]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/seastar/tests/unit/httpd_test.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / seastar / tests / unit / httpd_test.cc
index 17a26c802fa37a73bc2b90cde4b4800b17750e5d..1d66e4e5590c668acbb1b271756b506971e02f8b 100644 (file)
@@ -252,10 +252,10 @@ future<> test_transformer_stream(std::stringstream& ss, content_replace& cr, std
     ss.str("");
     req->_headers["Host"] = "localhost";
     return do_with(output_stream<char>(cr.transform(std::move(req), "json", output_stream<char>(memory_data_sink(ss), 32000, true))),
-            std::vector<sstring>(std::move(buffer_parts)), [&ss, &cr] (output_stream<char>& os, std::vector<sstring>& parts) {
+            std::vector<sstring>(std::move(buffer_parts)), [] (output_stream<char>& os, std::vector<sstring>& parts) {
         return do_for_each(parts, [&os](auto& p) {
             return os.write(p);
-        }).then([&os, &ss] {
+        }).then([&os] {
             return os.close();
         });
     });
@@ -264,7 +264,7 @@ future<> test_transformer_stream(std::stringstream& ss, content_replace& cr, std
 SEASTAR_TEST_CASE(test_transformer) {
     return do_with(std::stringstream(), content_replace("json"), [] (std::stringstream& ss, content_replace& cr) {
         return do_with(output_stream<char>(cr.transform(std::make_unique<seastar::httpd::request>(), "html", output_stream<char>(memory_data_sink(ss), 32000, true))),
-                [&ss] (output_stream<char>& os) {
+                [] (output_stream<char>& os) {
             return os.write(sstring("hello-{{Protocol}}-xyz-{{Host}}")).then([&os] {
                 return os.close();
             });
@@ -274,7 +274,7 @@ SEASTAR_TEST_CASE(test_transformer) {
                 BOOST_REQUIRE_EQUAL(ss.str(), "hello-http-xyz-localhost{{Pr");
                 return test_transformer_stream(ss, cr, {"hell", "o-{{", "Pro", "tocol}}{{Protocol}}-{{Protoxyz-{{Ho", "st}}{{Pr"}).then([&ss, &cr] {
                     BOOST_REQUIRE_EQUAL(ss.str(), "hello-httphttp-{{Protoxyz-localhost{{Pr");
-                    return test_transformer_stream(ss, cr, {"hell", "o-{{Pro", "t{{Protocol}}ocol}}", "{{Host}}"}).then([&ss, &cr] {
+                    return test_transformer_stream(ss, cr, {"hell", "o-{{Pro", "t{{Protocol}}ocol}}", "{{Host}}"}).then([&ss] {
                         BOOST_REQUIRE_EQUAL(ss.str(), "hello-{{Prothttpocol}}localhost");
                     });
                 });
@@ -394,8 +394,8 @@ public:
 
                 auto client = seastar::async([&lsi, reader] {
                     connected_socket c_socket = std::get<connected_socket>(lsi.connect(socket_address(ipv4_addr()), socket_address(ipv4_addr())).get());
-                    input_stream<char> input(std::move(c_socket.input()));
-                    output_stream<char> output(std::move(c_socket.output()));
+                    input_stream<char> input(c_socket.input());
+                    output_stream<char> output(c_socket.output());
                     bool more = true;
                     size_t count = 0;
                     while (more) {
@@ -403,8 +403,8 @@ public:
                         htp._concat = false;
 
                         write_request(output).get();
-                        repeat([&c_socket, &input, &htp] {
-                            return input.read().then([&c_socket, &input, &htp](const temporary_buffer<char>& b) mutable {
+                        repeat([&input, &htp] {
+                            return input.read().then([&htp](const temporary_buffer<char>& b) mutable {
                                 return (b.size() == 0 || htp.read(b)) ? make_ready_future<stop_iteration>(stop_iteration::yes) :
                                         make_ready_future<stop_iteration>(stop_iteration::no);
                             });
@@ -457,15 +457,15 @@ public:
 
                 auto client = seastar::async([&lsi, tests] {
                     connected_socket c_socket = std::get<connected_socket>(lsi.connect(socket_address(ipv4_addr()), socket_address(ipv4_addr())).get());
-                    input_stream<char> input(std::move(c_socket.input()));
-                    output_stream<char> output(std::move(c_socket.output()));
+                    input_stream<char> input(c_socket.input());
+                    output_stream<char> output(c_socket.output());
                     bool more = true;
                     size_t count = 0;
                     while (more) {
                         http_consumer htp;
                         write_request(output).get();
-                        repeat([&c_socket, &input, &htp] {
-                            return input.read().then([&c_socket, &input, &htp](const temporary_buffer<char>& b) mutable {
+                        repeat([&input, &htp] {
+                            return input.read().then([&htp](const temporary_buffer<char>& b) mutable {
                                 return (b.size() == 0 || htp.read(b)) ? make_ready_future<stop_iteration>(stop_iteration::yes) :
                                         make_ready_future<stop_iteration>(stop_iteration::no);
                             });
@@ -530,7 +530,7 @@ public:
                         throw std::runtime_error("Throwing exception before writing");
                     }
                 }
-                return repeat([&str, &remain, success] () mutable {
+                return repeat([&str, &remain] () mutable {
                     return str.write("1234567890").then([&remain]() mutable {
                         remain--;
                         return (remain == 0)? make_ready_future<stop_iteration>(stop_iteration::yes) : make_ready_future<stop_iteration>(stop_iteration::no);
@@ -623,8 +623,6 @@ struct extra_big_object : public json::json_base {
             _elements.emplace_back(value);
         }
     }
-
-    extra_big_object(extra_big_object&&) = default;
 };
 
 SEASTAR_TEST_CASE(json_stream) {
@@ -632,10 +630,68 @@ SEASTAR_TEST_CASE(json_stream) {
     size_t num_objects = 1000;
     size_t total_size = num_objects * 1000001 + 1;
     for (size_t i = 0; i < num_objects; i++) {
-        vec.emplace_back(extra_big_object(1000000));
+        vec.emplace_back(1000000);
     }
     return test_client_server::run_test(json::stream_object(vec), [total_size](size_t s, http_consumer& h) {
         BOOST_REQUIRE_EQUAL(h._size, total_size);
         return false;
     });
 }
+
+SEASTAR_TEST_CASE(content_length_limit) {
+    return seastar::async([] {
+        loopback_connection_factory lcf;
+        http_server server("test");
+        server.set_content_length_limit(11);
+        loopback_socket_impl lsi(lcf);
+        httpd::http_server_tester::listeners(server).emplace_back(lcf.get_server_socket());
+
+        future<> client = seastar::async([&lsi] {
+            connected_socket c_socket = std::get<connected_socket>(lsi.connect(socket_address(ipv4_addr()), socket_address(ipv4_addr())).get());
+            input_stream<char> input(c_socket.input());
+            output_stream<char> output(c_socket.output());
+
+            output.write(sstring("GET /test HTTP/1.1\r\nHost: test\r\n\r\n")).get();
+            output.flush().get();
+            auto resp = input.read().get0();
+            BOOST_REQUIRE_NE(std::string(resp.get(), resp.size()).find("200 OK"), std::string::npos);
+
+            output.write(sstring("GET /test HTTP/1.1\r\nHost: test\r\nContent-Length: 11\r\n\r\nxxxxxxxxxxx")).get();
+            output.flush().get();
+            resp = input.read().get0();
+            BOOST_REQUIRE_NE(std::string(resp.get(), resp.size()).find("200 OK"), std::string::npos);
+
+            output.write(sstring("GET /test HTTP/1.1\r\nHost: test\r\nContent-Length: 17\r\n\r\nxxxxxxxxxxxxxxxx")).get();
+            output.flush().get();
+            resp = input.read().get0();
+            BOOST_REQUIRE_EQUAL(std::string(resp.get(), resp.size()).find("200 OK"), std::string::npos);
+            BOOST_REQUIRE_NE(std::string(resp.get(), resp.size()).find("413 Payload Too Large"), std::string::npos);
+
+            input.close().get();
+            output.close().get();
+        });
+
+        future<> writer = seastar::async([&server] {
+            class test_handler : public handler_base {
+                size_t count = 0;
+                http_server& _server;
+                std::function<future<>(output_stream<char> &&)> _write_func;
+            public:
+                test_handler(http_server& server, std::function<future<>(output_stream<char> &&)>&& write_func) : _server(server), _write_func(write_func) {
+                }
+                future<std::unique_ptr<reply>> handle(const sstring& path,
+                        std::unique_ptr<request> req, std::unique_ptr<reply> rep) override {
+                    rep->write_body("json", _write_func);
+                    return make_ready_future<std::unique_ptr<reply>>(std::move(rep));
+                }
+            };
+            auto handler = new test_handler(server, json::stream_object("hello"));
+            server._routes.put(GET, "/test", handler);
+            server.do_accepts(0).get();
+        });
+
+        client.get();
+        writer.get();
+        server.stop().get();
+    });
+}