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