blob: 8277a3f7feaf7244a106c7dac5ceeed62ef15777 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Ed Tanous7a6f0032024-01-28 09:49:03 -08003#include "file_test_utilities.hpp"
Ed Tanousb2896142024-01-31 15:25:47 -08004#include "http/http_body.hpp"
Abhilash Raju8e3f7032023-07-17 08:53:11 -05005#include "http/http_response.hpp"
Ed Tanousf0b59af2024-03-20 13:38:04 -07006#include "utility.hpp"
Abhilash Raju8e3f7032023-07-17 08:53:11 -05007
Ed Tanous8d45b9c2024-04-08 17:50:10 -07008#include <boost/beast/core/buffers_to_string.hpp>
Ed Tanousf0b59af2024-03-20 13:38:04 -07009#include <boost/beast/core/file_base.hpp>
10#include <boost/beast/core/file_posix.hpp>
11#include <boost/beast/http/message.hpp>
Ed Tanous8d45b9c2024-04-08 17:50:10 -070012#include <boost/beast/http/serializer.hpp>
Ed Tanousf0b59af2024-03-20 13:38:04 -070013#include <boost/beast/http/status.hpp>
14
15#include <cstdio>
Abhilash Raju8e3f7032023-07-17 08:53:11 -050016#include <filesystem>
Ed Tanousf0b59af2024-03-20 13:38:04 -070017#include <string>
Abhilash Raju8e3f7032023-07-17 08:53:11 -050018
19#include "gtest/gtest.h"
20namespace
21{
22void addHeaders(crow::Response& res)
23{
24 res.addHeader("myheader", "myvalue");
25 res.keepAlive(true);
26 res.result(boost::beast::http::status::ok);
27}
28void verifyHeaders(crow::Response& res)
29{
30 EXPECT_EQ(res.getHeaderValue("myheader"), "myvalue");
31 EXPECT_EQ(res.keepAlive(), true);
32 EXPECT_EQ(res.result(), boost::beast::http::status::ok);
33}
34
Ed Tanousb2896142024-01-31 15:25:47 -080035std::string getData(boost::beast::http::response<bmcweb::HttpBody>& m)
Abhilash Rajub5f288d2023-11-08 22:32:44 -060036{
Ed Tanous52e31622024-01-23 16:31:11 -080037 std::string ret;
38
Ed Tanousb2896142024-01-31 15:25:47 -080039 boost::beast::http::response_serializer<bmcweb::HttpBody> sr{m};
Ed Tanous52e31622024-01-23 16:31:11 -080040 sr.split(true);
Ed Tanous5575efb2024-01-30 09:25:03 -080041 // Reads buffers into ret
Patrick Williamsbd79bce2024-08-16 15:22:20 -040042 auto reader =
43 [&sr, &ret](const boost::system::error_code& ec2, const auto& buffer) {
44 EXPECT_FALSE(ec2);
45 std::string ret2 = boost::beast::buffers_to_string(buffer);
46 sr.consume(ret2.size());
47 ret += ret2;
48 };
Ed Tanous52e31622024-01-23 16:31:11 -080049 boost::system::error_code ec;
50
51 // Read headers
Abhilash Rajub5f288d2023-11-08 22:32:44 -060052 while (!sr.is_header_done())
53 {
Ed Tanous52e31622024-01-23 16:31:11 -080054 sr.next(ec, reader);
55 EXPECT_FALSE(ec);
Abhilash Rajub5f288d2023-11-08 22:32:44 -060056 }
Ed Tanous52e31622024-01-23 16:31:11 -080057 ret.clear();
Abhilash Rajub5f288d2023-11-08 22:32:44 -060058
Ed Tanous52e31622024-01-23 16:31:11 -080059 // Read body
Abhilash Rajub5f288d2023-11-08 22:32:44 -060060 while (!sr.is_done())
61 {
Ed Tanous52e31622024-01-23 16:31:11 -080062 sr.next(ec, reader);
Abhilash Rajub5f288d2023-11-08 22:32:44 -060063 EXPECT_FALSE(ec);
64 }
65
66 return ret;
67}
Ed Tanous52e31622024-01-23 16:31:11 -080068
Abhilash Raju8e3f7032023-07-17 08:53:11 -050069TEST(HttpResponse, Headers)
70{
71 crow::Response res;
72 addHeaders(res);
73 verifyHeaders(res);
74}
75TEST(HttpResponse, StringBody)
76{
77 crow::Response res;
78 addHeaders(res);
Ed Tanous5575efb2024-01-30 09:25:03 -080079 std::string_view bodyValue = "this is my new body";
80 res.write({bodyValue.data(), bodyValue.length()});
81 EXPECT_EQ(*res.body(), bodyValue);
Abhilash Raju8e3f7032023-07-17 08:53:11 -050082 verifyHeaders(res);
83}
Ed Tanousb2896142024-01-31 15:25:47 -080084TEST(HttpResponse, HttpBody)
Abhilash Raju8e3f7032023-07-17 08:53:11 -050085{
86 crow::Response res;
87 addHeaders(res);
Ed Tanous5575efb2024-01-30 09:25:03 -080088 TemporaryFileHandle temporaryFile("sample text");
89 res.openFile(temporaryFile.stringPath);
Abhilash Raju8e3f7032023-07-17 08:53:11 -050090
91 verifyHeaders(res);
Abhilash Raju8e3f7032023-07-17 08:53:11 -050092}
Ed Tanousb2896142024-01-31 15:25:47 -080093TEST(HttpResponse, HttpBodyWithFd)
Abhilash Rajub5f288d2023-11-08 22:32:44 -060094{
95 crow::Response res;
96 addHeaders(res);
Ed Tanous5575efb2024-01-30 09:25:03 -080097 TemporaryFileHandle temporaryFile("sample text");
98 FILE* fd = fopen(temporaryFile.stringPath.c_str(), "r+");
Abhilash Rajub5f288d2023-11-08 22:32:44 -060099 res.openFd(fileno(fd));
100 verifyHeaders(res);
101 fclose(fd);
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600102}
103
Ed Tanousb2896142024-01-31 15:25:47 -0800104TEST(HttpResponse, Base64HttpBodyWithFd)
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600105{
106 crow::Response res;
107 addHeaders(res);
Ed Tanous5575efb2024-01-30 09:25:03 -0800108 TemporaryFileHandle temporaryFile("sample text");
109 FILE* fd = fopen(temporaryFile.stringPath.c_str(), "r");
110 ASSERT_NE(fd, nullptr);
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600111 res.openFd(fileno(fd), bmcweb::EncodingType::Base64);
112 verifyHeaders(res);
113 fclose(fd);
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600114}
115
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500116TEST(HttpResponse, BodyTransitions)
117{
118 crow::Response res;
119 addHeaders(res);
Ed Tanous5575efb2024-01-30 09:25:03 -0800120 TemporaryFileHandle temporaryFile("sample text");
121 res.openFile(temporaryFile.stringPath);
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500122
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500123 verifyHeaders(res);
124 res.write("body text");
125
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500126 verifyHeaders(res);
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600127}
128
Ed Tanous7a6f0032024-01-28 09:49:03 -0800129std::string generateBigdata()
130{
131 std::string result;
132 while (result.size() < 10000)
133 {
134 result += "sample text";
135 }
136 return result;
137}
138
139TEST(HttpResponse, StringBodyWriterLarge)
140{
141 crow::Response res;
142 std::string data = generateBigdata();
143 res.write(std::string(data));
Ed Tanous5575efb2024-01-30 09:25:03 -0800144 EXPECT_EQ(getData(res.response), data);
Ed Tanous7a6f0032024-01-28 09:49:03 -0800145}
146
Ed Tanousb2896142024-01-31 15:25:47 -0800147TEST(HttpResponse, Base64HttpBodyWriter)
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600148{
149 crow::Response res;
150 std::string data = "sample text";
Ed Tanous5575efb2024-01-30 09:25:03 -0800151 TemporaryFileHandle temporaryFile(data);
152 FILE* f = fopen(temporaryFile.stringPath.c_str(), "r+");
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600153 res.openFd(fileno(f), bmcweb::EncodingType::Base64);
Ed Tanous5575efb2024-01-30 09:25:03 -0800154 EXPECT_EQ(getData(res.response), "c2FtcGxlIHRleHQ=");
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600155}
156
Ed Tanousb2896142024-01-31 15:25:47 -0800157TEST(HttpResponse, Base64HttpBodyWriterLarge)
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600158{
159 crow::Response res;
160 std::string data = generateBigdata();
Ed Tanous5575efb2024-01-30 09:25:03 -0800161 TemporaryFileHandle temporaryFile(data);
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600162
Ed Tanous5575efb2024-01-30 09:25:03 -0800163 boost::beast::file_posix file;
164 boost::system::error_code ec;
165 file.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
166 ec);
167 EXPECT_EQ(ec.value(), 0);
168 res.openFd(file.native_handle(), bmcweb::EncodingType::Base64);
169 EXPECT_EQ(getData(res.response), crow::utility::base64encode(data));
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600170}
171
Ed Tanousb2896142024-01-31 15:25:47 -0800172TEST(HttpResponse, HttpBodyWriterLarge)
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600173{
174 crow::Response res;
175 std::string data = generateBigdata();
Ed Tanous5575efb2024-01-30 09:25:03 -0800176 TemporaryFileHandle temporaryFile(data);
177
178 boost::beast::file_posix file;
179 boost::system::error_code ec;
180 file.open(temporaryFile.stringPath.c_str(), boost::beast::file_mode::read,
181 ec);
182 EXPECT_EQ(ec.value(), 0);
183 res.openFd(file.native_handle());
184 EXPECT_EQ(getData(res.response), data);
Abhilash Rajub5f288d2023-11-08 22:32:44 -0600185}
186
Abhilash Raju8e3f7032023-07-17 08:53:11 -0500187} // namespace