1 #include "boost/beast/core/buffers_to_string.hpp" 2 #include "boost/beast/core/flat_buffer.hpp" 3 #include "boost/beast/http/serializer.hpp" 4 #include "file_test_utilities.hpp" 5 #include "http/http_body.hpp" 6 #include "http/http_response.hpp" 7 8 #include <filesystem> 9 #include <fstream> 10 #include <thread> 11 12 #include "gtest/gtest.h" 13 namespace 14 { 15 void addHeaders(crow::Response& res) 16 { 17 res.addHeader("myheader", "myvalue"); 18 res.keepAlive(true); 19 res.result(boost::beast::http::status::ok); 20 } 21 void verifyHeaders(crow::Response& res) 22 { 23 EXPECT_EQ(res.getHeaderValue("myheader"), "myvalue"); 24 EXPECT_EQ(res.keepAlive(), true); 25 EXPECT_EQ(res.result(), boost::beast::http::status::ok); 26 } 27 28 std::string getData(boost::beast::http::response<bmcweb::HttpBody>& m) 29 { 30 std::string ret; 31 32 boost::beast::http::response_serializer<bmcweb::HttpBody> sr{m}; 33 sr.split(true); 34 35 auto reader = [&sr, &ret](const boost::system::error_code& ec2, 36 const auto& buffer) { 37 EXPECT_FALSE(ec2); 38 std::string ret2 = boost::beast::buffers_to_string(buffer); 39 sr.consume(ret2.size()); 40 ret += ret2; 41 }; 42 boost::system::error_code ec; 43 44 // Read headers 45 while (!sr.is_header_done()) 46 { 47 sr.next(ec, reader); 48 EXPECT_FALSE(ec); 49 } 50 ret.clear(); 51 52 // Read body 53 while (!sr.is_done()) 54 { 55 sr.next(ec, reader); 56 EXPECT_FALSE(ec); 57 } 58 59 return ret; 60 } 61 62 TEST(HttpResponse, Headers) 63 { 64 crow::Response res; 65 addHeaders(res); 66 verifyHeaders(res); 67 } 68 TEST(HttpResponse, StringBody) 69 { 70 crow::Response res; 71 addHeaders(res); 72 std::string_view bodyvalue = "this is my new body"; 73 res.write({bodyvalue.data(), bodyvalue.length()}); 74 EXPECT_EQ(*res.body(), bodyvalue); 75 verifyHeaders(res); 76 } 77 TEST(HttpResponse, HttpBody) 78 { 79 crow::Response res; 80 addHeaders(res); 81 std::string path = makeFile("sample text"); 82 res.openFile(path); 83 84 verifyHeaders(res); 85 std::filesystem::remove(path); 86 } 87 TEST(HttpResponse, HttpBodyWithFd) 88 { 89 crow::Response res; 90 addHeaders(res); 91 std::string path = makeFile("sample text"); 92 FILE* fd = fopen(path.c_str(), "r+"); 93 res.openFd(fileno(fd)); 94 verifyHeaders(res); 95 fclose(fd); 96 std::filesystem::remove(path); 97 } 98 99 TEST(HttpResponse, Base64HttpBodyWithFd) 100 { 101 crow::Response res; 102 addHeaders(res); 103 std::string path = makeFile("sample text"); 104 FILE* fd = fopen(path.c_str(), "r+"); 105 res.openFd(fileno(fd), bmcweb::EncodingType::Base64); 106 verifyHeaders(res); 107 fclose(fd); 108 std::filesystem::remove(path); 109 } 110 111 TEST(HttpResponse, BodyTransitions) 112 { 113 crow::Response res; 114 addHeaders(res); 115 std::string path = makeFile("sample text"); 116 res.openFile(path); 117 118 verifyHeaders(res); 119 res.write("body text"); 120 121 verifyHeaders(res); 122 std::filesystem::remove(path); 123 } 124 125 void testFileData(crow::Response& res, const std::string& data) 126 { 127 auto& fb = res.response; 128 EXPECT_EQ(getData(fb), data); 129 } 130 131 std::string generateBigdata() 132 { 133 std::string result; 134 while (result.size() < 10000) 135 { 136 result += "sample text"; 137 } 138 return result; 139 } 140 141 TEST(HttpResponse, StringBodyWriterLarge) 142 { 143 crow::Response res; 144 std::string data = generateBigdata(); 145 res.write(std::string(data)); 146 testFileData(res, data); 147 } 148 149 TEST(HttpResponse, Base64HttpBodyWriter) 150 { 151 crow::Response res; 152 std::string data = "sample text"; 153 std::string path = makeFile(data); 154 FILE* f = fopen(path.c_str(), "r+"); 155 res.openFd(fileno(f), bmcweb::EncodingType::Base64); 156 testFileData(res, crow::utility::base64encode(data)); 157 fclose(f); 158 std::filesystem::remove(path); 159 } 160 161 TEST(HttpResponse, Base64HttpBodyWriterLarge) 162 { 163 crow::Response res; 164 std::string data = generateBigdata(); 165 std::string path = makeFile(data); 166 { 167 boost::beast::file_posix file; 168 boost::system::error_code ec; 169 file.open(path.c_str(), boost::beast::file_mode::read, ec); 170 EXPECT_EQ(ec.value(), 0); 171 res.openFd(file.native_handle(), bmcweb::EncodingType::Base64); 172 testFileData(res, crow::utility::base64encode(data)); 173 } 174 175 std::filesystem::remove(path); 176 } 177 178 TEST(HttpResponse, HttpBodyWriterLarge) 179 { 180 crow::Response res; 181 std::string data = generateBigdata(); 182 std::string path = makeFile(data); 183 { 184 boost::beast::file_posix file; 185 boost::system::error_code ec; 186 file.open(path.c_str(), boost::beast::file_mode::read, ec); 187 EXPECT_EQ(ec.value(), 0); 188 res.openFd(file.native_handle()); 189 testFileData(res, data); 190 } 191 std::filesystem::remove(path); 192 } 193 194 } // namespace 195