1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #include "async_resp.hpp" 4 #include "http/http_connection.hpp" 5 #include "http/http_request.hpp" 6 #include "http/http_response.hpp" 7 #include "http_connect_types.hpp" 8 #include "test_stream.hpp" 9 10 #include <boost/asio/buffer.hpp> 11 #include <boost/asio/io_context.hpp> 12 #include <boost/asio/ssl/context.hpp> 13 #include <boost/asio/steady_timer.hpp> 14 #include <boost/beast/_experimental/test/stream.hpp> 15 #include <boost/beast/http/field.hpp> 16 #include <boost/beast/http/verb.hpp> 17 18 #include <chrono> 19 #include <functional> 20 #include <memory> 21 #include <string> 22 #include <utility> 23 24 #include "gtest/gtest.h" 25 namespace crow 26 { 27 28 struct FakeHandler 29 { 30 template <typename Adaptor> 31 static void handleUpgrade( 32 const std::shared_ptr<Request>& /*req*/, 33 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/, 34 Adaptor&& /*adaptor*/) 35 { 36 // Handle Upgrade should never be called 37 EXPECT_FALSE(true); 38 } 39 40 void handle(const std::shared_ptr<Request>& req, 41 const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/) 42 { 43 EXPECT_EQ(req->method(), boost::beast::http::verb::get); 44 EXPECT_EQ(req->target(), "/"); 45 EXPECT_EQ(req->getHeaderValue(boost::beast::http::field::host), 46 "openbmc_project.xyz"); 47 EXPECT_FALSE(req->keepAlive()); 48 EXPECT_EQ(req->version(), 11); 49 EXPECT_EQ(req->body(), ""); 50 51 called = true; 52 } 53 bool called = false; 54 }; 55 56 struct ClockFake 57 { 58 bool wascalled = false; 59 std::string getDateStr() 60 { 61 wascalled = true; 62 return "TestTime"; 63 } 64 }; 65 66 TEST(http_connection, RequestPropogates) 67 { 68 boost::asio::io_context io; 69 ClockFake clock; 70 TestStream stream(io); 71 TestStream out(io); 72 stream.connect(out); 73 74 out.write_some(boost::asio::buffer( 75 "GET / HTTP/1.1\r\nHost: openbmc_project.xyz\r\nConnection: close\r\n\r\n")); 76 FakeHandler handler; 77 boost::asio::steady_timer timer(io); 78 std::function<std::string()> date( 79 std::bind_front(&ClockFake::getDateStr, &clock)); 80 81 boost::asio::ssl::context context{boost::asio::ssl::context::tls}; 82 std::shared_ptr<crow::Connection<TestStream, FakeHandler>> conn = 83 std::make_shared<crow::Connection<TestStream, FakeHandler>>( 84 &handler, HttpType::HTTP, std::move(timer), date, 85 boost::asio::ssl::stream<TestStream>(std::move(stream), context)); 86 conn->disableAuth(); 87 conn->start(); 88 io.run_for(std::chrono::seconds(1000)); 89 EXPECT_TRUE(handler.called); 90 std::string outStr = out.str(); 91 92 std::string expected = 93 "HTTP/1.1 200 OK\r\n" 94 "Connection: close\r\n" 95 "Strict-Transport-Security: max-age=31536000; includeSubdomains\r\n" 96 "Pragma: no-cache\r\n" 97 "Cache-Control: no-store, max-age=0\r\n" 98 "X-Content-Type-Options: nosniff\r\n" 99 "Date: TestTime\r\n" 100 "Content-Length: 0\r\n\r\n"; 101 EXPECT_EQ(outStr, expected); 102 EXPECT_TRUE(clock.wascalled); 103 } 104 105 } // namespace crow 106