Skip to content

Commit 1a62e26

Browse files
committed
feat: post and http_stream refactor
1 parent 433e610 commit 1a62e26

File tree

15 files changed

+623
-189
lines changed

15 files changed

+623
-189
lines changed

example/post-test.html

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>POST Test</title>
5+
</head>
6+
<body>
7+
<input type="text" id="url" value="http://localhost:80" size="40">
8+
<button onclick="sendPost()">Send POST</button>
9+
<button onclick="sendOptions()">Send OPTIONS *</button>
10+
<pre id="status"></pre>
11+
12+
<script>
13+
function generateData(size) {
14+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
15+
let result = '';
16+
for (let i = 0; i < size; i++) {
17+
result += chars[i % chars.length];
18+
}
19+
return result;
20+
}
21+
22+
async function sendPost() {
23+
const url = document.getElementById('url').value;
24+
const status = document.getElementById('status');
25+
const data = generateData(256 * 1024);
26+
27+
status.textContent = 'Sending ' + data.length + ' bytes to ' + url + '...';
28+
29+
try {
30+
const response = await fetch(url, {
31+
method: 'POST',
32+
body: data,
33+
headers: { 'Content-Type': 'application/octet-stream' }
34+
});
35+
status.textContent = 'Response: ' + response.status + ' ' + response.statusText;
36+
} catch (e) {
37+
status.textContent = 'Error: ' + e.message;
38+
}
39+
}
40+
41+
async function sendOptions() {
42+
const url = document.getElementById('url').value;
43+
const status = document.getElementById('status');
44+
45+
status.textContent = 'Sending OPTIONS * to ' + url + '...';
46+
47+
try {
48+
const response = await fetch(url, {
49+
method: 'OPTIONS',
50+
headers: { 'Request-URI': '*' }
51+
});
52+
status.textContent = 'Response: ' + response.status + ' ' + response.statusText;
53+
} catch (e) {
54+
status.textContent = 'Error: ' + e.message;
55+
}
56+
}
57+
</script>
58+
</body>
59+
</html>

example/server/main.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//
99

1010
#include "certificate.hpp"
11+
#include "post_work.hpp"
1112
#include "serve_detached.hpp"
1213
#include "serve_log_admin.hpp"
1314
#include <boost/beast2/asio_io_context.hpp>
@@ -69,7 +70,15 @@ int server_main( int argc, char* argv[] )
6970

7071
//srv.wwwroot.use("/log", serve_log_admin(app));
7172
//srv.wwwroot.use("/alt", serve_static( argv[3] ));
72-
srv.wwwroot.use("/detach", serve_detached());
73+
//srv.wwwroot.use("/detach", serve_detached());
74+
srv.wwwroot.use(post_work());
75+
srv.wwwroot.use(
76+
[]( Request& req,
77+
Response& res) ->
78+
route_result
79+
{
80+
return route::next;
81+
});
7382
srv.wwwroot.use("/", serve_static( argv[3] ));
7483

7584
app.start();

example/server/post_work.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//
2+
// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/beast2
8+
//
9+
10+
#include "post_work.hpp"
11+
12+
namespace boost {
13+
namespace beast2 {
14+
15+
/*
16+
struct etag
17+
{
18+
Request& req;
19+
Response& res;
20+
sha1_state digest;
21+
22+
void operator()( resumer resume )
23+
{
24+
char buf[8192];
25+
system::error_code ec;
26+
auto nread = res.body.read(
27+
buffers::make_buffer(buf), ec);
28+
digest.update( buf, nread );
29+
if(ec == error::eof)
30+
{
31+
res.body.rewind();
32+
res.set_header(
33+
http::field::etag,
34+
to_hex(digest.finalize()) );
35+
return resume( route::next );
36+
}
37+
if( ec.failed() )
38+
return resume( ec );
39+
// we will get called again
40+
}
41+
};
42+
*/
43+
44+
namespace {
45+
46+
struct task
47+
{
48+
std::size_t i = 10;
49+
50+
void
51+
operator()(resumer resume)
52+
{
53+
if(i--)
54+
return;
55+
resume(route::next);
56+
}
57+
};
58+
59+
} // (anon)
60+
61+
//------------------------------------------------
62+
63+
route_result
64+
post_work::
65+
operator()(
66+
Request&,
67+
Response& res) const
68+
{
69+
return res.post(task());
70+
}
71+
72+
} // beast2
73+
} // boost

example/server/post_work.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/beast2
8+
//
9+
10+
#ifndef BOOST_BEAST2_SERVER_POST_WORK_HPP
11+
#define BOOST_BEAST2_SERVER_POST_WORK_HPP
12+
13+
#include <boost/beast2/detail/config.hpp>
14+
#include <boost/beast2/server/route_handler.hpp>
15+
16+
namespace boost {
17+
namespace beast2 {
18+
19+
struct post_work
20+
{
21+
system::error_code
22+
operator()(
23+
Request&,
24+
Response& res) const;
25+
};
26+
27+
} // beast2
28+
} // boost
29+
30+
#endif

include/boost/beast2/server/basic_router.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class any_router
178178
BOOST_BEAST2_DECL void add_impl(layer&,
179179
core::string_view, handler_list const&);
180180
BOOST_BEAST2_DECL route_result resume_impl(
181-
basic_request&, basic_response&, route_result const& ec) const;
181+
basic_request&, basic_response&, route_result ec) const;
182182
BOOST_BEAST2_DECL route_result dispatch_impl(http_proto::method,
183183
core::string_view, urls::url_view const&,
184184
basic_request&, basic_response&) const;
@@ -733,7 +733,7 @@ class basic_router : public /*detail::*/any_router
733733
route_result const& rv) const ->
734734
route_result
735735
{
736-
return resume_impl(req, res, rv);
736+
return resume_impl(req, res, rv);
737737
}
738738

739739
private:
@@ -833,7 +833,8 @@ class basic_router : public /*detail::*/any_router
833833
{
834834
auto const& ec = static_cast<
835835
basic_response const&>(res).ec_;
836-
if(! ec.failed())
836+
if( res.resume_ > 0 ||
837+
! ec.failed())
837838
return h.dispatch_impl(req, res);
838839
return beast2::route::next;
839840
}

0 commit comments

Comments
 (0)