1 #include "file_test_utilities.hpp"
2 #include "http/http_body.hpp"
3 #include "http/http_response.hpp"
4 #include "utility.hpp"
5
6 #include <boost/beast/core/buffers_to_string.hpp>
7 #include <boost/beast/core/file_base.hpp>
8 #include <boost/beast/core/file_posix.hpp>
9 #include <boost/beast/http/message.hpp>
10 #include <boost/beast/http/serializer.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 {
addHeaders(crow::Response & res)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 }
verifyHeaders(crow::Response & res)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
getData(boost::beast::http::response<bmcweb::HttpBody> & m)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 =
41 [&sr, &ret](const boost::system::error_code& ec2, 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
TEST(HttpResponse,Headers)67 TEST(HttpResponse, Headers)
68 {
69 crow::Response res;
70 addHeaders(res);
71 verifyHeaders(res);
72 }
TEST(HttpResponse,StringBody)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 }
TEST(HttpResponse,HttpBody)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 }
TEST(HttpResponse,HttpBodyWithFd)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
TEST(HttpResponse,Base64HttpBodyWithFd)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
TEST(HttpResponse,BodyTransitions)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
generateBigdata()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
TEST(HttpResponse,StringBodyWriterLarge)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
TEST(HttpResponse,Base64HttpBodyWriter)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
TEST(HttpResponse,Base64HttpBodyWriterLarge)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
TEST(HttpResponse,HttpBodyWriterLarge)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