blob: f61d6dea9d10b5dd7ea316efd04327a738bee9ed [file] [log] [blame]
Ed Tanous52e31622024-01-23 16:31:11 -08001#include "boost/beast/core/buffers_to_string.hpp"
Abhilash Raju8e3f7032023-07-17 08:53:11 -05002#include "boost/beast/core/flat_buffer.hpp"
3#include "boost/beast/http/serializer.hpp"
4#include "http/http_response.hpp"
5
6#include <filesystem>
7#include <fstream>
8#include <thread>
9
10#include "gtest/gtest.h"
11namespace
12{
13void addHeaders(crow::Response& res)
14{
15 res.addHeader("myheader", "myvalue");
16 res.keepAlive(true);
17 res.result(boost::beast::http::status::ok);
18}
19void verifyHeaders(crow::Response& res)
20{
21 EXPECT_EQ(res.getHeaderValue("myheader"), "myvalue");
22 EXPECT_EQ(res.keepAlive(), true);
23 EXPECT_EQ(res.result(), boost::beast::http::status::ok);
24}
25
Abhilash Rajub5f288d2023-11-08 22:32:44 -060026std::string makeFile(std::string_view sampleData)
Abhilash Raju8e3f7032023-07-17 08:53:11 -050027{
28 std::filesystem::path path = std::filesystem::temp_directory_path();
29 path /= "bmcweb_http_response_test_XXXXXXXXXXX";
30 std::string stringPath = path.string();
31 int fd = mkstemp(stringPath.data());
32 EXPECT_GT(fd, 0);
Abhilash Rajub5f288d2023-11-08 22:32:44 -060033 EXPECT_EQ(write(fd, sampleData.data(), sampleData.size()),
34 sampleData.size());
35 close(fd);
Abhilash Raju8e3f7032023-07-17 08:53:11 -050036 return stringPath;
37}
Abhilash Rajub5f288d2023-11-08 22:32:44 -060038
Ed Tanous52e31622024-01-23 16:31:11 -080039std::string getData(boost::beast::http::response<bmcweb::FileBody>& m)
Abhilash Rajub5f288d2023-11-08 22:32:44 -060040{
Ed Tanous52e31622024-01-23 16:31:11 -080041 std::string ret;
42
43 boost::beast::http::response_serializer<bmcweb::FileBody> sr{m};
44 sr.split(true);
45
46 auto reader = [&sr, &ret](const boost::system::error_code& ec2,
47 const auto& buffer) {
48 EXPECT_FALSE(ec2);
49 std::string ret2 = boost::beast::buffers_to_string(buffer);
50 sr.consume(ret2.size());
51 ret += ret2;
52 };
53 boost::system::error_code ec;
54
55 // Read headers
Abhilash Rajub5f288d2023-11-08 22:32:44 -060056 while (!sr.is_header_done())
57 {
Ed Tanous52e31622024-01-23 16:31:11 -080058 sr.next(ec, reader);
59 EXPECT_FALSE(ec);
Abhilash Rajub5f288d2023-11-08 22:32:44 -060060 }
Ed Tanous52e31622024-01-23 16:31:11 -080061 ret.clear();
Abhilash Rajub5f288d2023-11-08 22:32:44 -060062
Ed Tanous52e31622024-01-23 16:31:11 -080063 // Read body
Abhilash Rajub5f288d2023-11-08 22:32:44 -060064 while (!sr.is_done())
65 {
Ed Tanous52e31622024-01-23 16:31:11 -080066 sr.next(ec, reader);
Abhilash Rajub5f288d2023-11-08 22:32:44 -060067 EXPECT_FALSE(ec);
68 }
69
70 return ret;
71}
Ed Tanous52e31622024-01-23 16:31:11 -080072
Abhilash Raju8e3f7032023-07-17 08:53:11 -050073TEST(HttpResponse, Headers)
74{
75 crow::Response res;
76 addHeaders(res);
77 verifyHeaders(res);
78}
79TEST(HttpResponse, StringBody)
80{
81 crow::Response res;
82 addHeaders(res);
83 std::string_view bodyvalue = "this is my new body";
84 res.write({bodyvalue.data(), bodyvalue.length()});
85 EXPECT_EQ(*res.body(), bodyvalue);
86 verifyHeaders(res);
87}
88TEST(HttpResponse, FileBody)
89{
90 crow::Response res;
91 addHeaders(res);
Abhilash Rajub5f288d2023-11-08 22:32:44 -060092 std::string path = makeFile("sample text");
Abhilash Raju8e3f7032023-07-17 08:53:11 -050093 res.openFile(path);
94
95 verifyHeaders(res);
96 std::filesystem::remove(path);
97}
Abhilash Rajub5f288d2023-11-08 22:32:44 -060098TEST(HttpResponse, FileBodyWithFd)
99{
100 crow::Response res;
101 addHeaders(res);
102 std::string path = makeFile("sample text");
103 FILE* fd = fopen(path.c_str(), "r+");
104 res.openFd(fileno(fd));
105 verifyHeaders(res);
106 fclose(fd);
107 std::filesystem::remove(path);
108}
109
110TEST(HttpResponse, Base64FileBodyWithFd)
111{
112 crow::Response res;
113 addHeaders(res);
114 std::string path = makeFile("sample text");
115 FILE* fd = fopen(path.c_str(), "r+");
116 res.openFd(fileno(fd), bmcweb::EncodingType::Base64);
117 verifyHeaders(res);
118 fclose(fd);
119 std::filesystem::remove(path);
120}
121
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500122TEST(HttpResponse, BodyTransitions)
123{
124 crow::Response res;
125 addHeaders(res);
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600126 std::string path = makeFile("sample text");
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500127 res.openFile(path);
128
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500129 verifyHeaders(res);
130 res.write("body text");
131
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500132 verifyHeaders(res);
133 std::filesystem::remove(path);
134}
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600135
136void testFileData(crow::Response& res, const std::string& data)
137{
Ed Tanous52e31622024-01-23 16:31:11 -0800138 auto& fb = res.response;
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600139 EXPECT_EQ(getData(fb), data);
140}
141
142TEST(HttpResponse, Base64FileBodyWriter)
143{
144 crow::Response res;
145 std::string data = "sample text";
146 std::string path = makeFile(data);
147 FILE* f = fopen(path.c_str(), "r+");
148 res.openFd(fileno(f), bmcweb::EncodingType::Base64);
149 testFileData(res, crow::utility::base64encode(data));
150 fclose(f);
151 std::filesystem::remove(path);
152}
153
154std::string generateBigdata()
155{
156 std::string result;
157 while (result.size() < 10000)
158 {
159 result += "sample text";
160 }
161 return result;
162}
163
164TEST(HttpResponse, Base64FileBodyWriterLarge)
165{
166 crow::Response res;
167 std::string data = generateBigdata();
168 std::string path = makeFile(data);
169 {
170 boost::beast::file_posix file;
171 boost::system::error_code ec;
172 file.open(path.c_str(), boost::beast::file_mode::read, ec);
173 EXPECT_EQ(ec.value(), 0);
174 res.openFd(file.native_handle(), bmcweb::EncodingType::Base64);
175 testFileData(res, crow::utility::base64encode(data));
176 }
177
178 std::filesystem::remove(path);
179}
180
181TEST(HttpResponse, FileBodyWriterLarge)
182{
183 crow::Response res;
184 std::string data = generateBigdata();
185 std::string path = makeFile(data);
186 {
187 boost::beast::file_posix file;
188 boost::system::error_code ec;
189 file.open(path.c_str(), boost::beast::file_mode::read, ec);
190 EXPECT_EQ(ec.value(), 0);
191 res.openFd(file.native_handle());
192 testFileData(res, data);
193 }
194 std::filesystem::remove(path);
195}
196
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500197} // namespace