Skip to content

Commit adcadb8

Browse files
committed
core: stabilize HTTP request path and bench helpers
1 parent c6dfd24 commit adcadb8

4 files changed

Lines changed: 115 additions & 37 deletions

File tree

include/vix/http/Request.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,13 @@ namespace vix::http
214214
headers_ = std::move(headers);
215215
}
216216

217+
[[nodiscard]] Request with_params(ParamMap params) const
218+
{
219+
Request copy = *this;
220+
copy.params_ = std::make_shared<const ParamMap>(std::move(params));
221+
return copy;
222+
}
223+
217224
/**
218225
* @brief Return a header value or an empty string if missing.
219226
*

include/vix/http/RequestHandler.hpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -237,17 +237,7 @@ namespace vix::http
237237
ResponseWrapper wrapped{res, template_view_};
238238

239239
auto params = extract_params_from_path(route_pattern_, incoming_req.path());
240-
auto state = incoming_req.state_ptr()
241-
? std::const_pointer_cast<RequestState>(incoming_req.state_ptr())
242-
: std::make_shared<RequestState>();
243-
244-
Request req(
245-
incoming_req.method(),
246-
incoming_req.target(),
247-
incoming_req.headers(),
248-
incoming_req.body(),
249-
std::move(params),
250-
std::move(state));
240+
Request req = incoming_req.with_params(std::move(params));
251241

252242
try
253243
{

src/server/HTTPServer.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ namespace vix::server
5151
{
5252
return Logger::getInstance();
5353
}
54-
55-
void set_affinity(std::size_t thread_index)
56-
{
57-
(void)thread_index;
58-
}
5954
} // namespace
6055

6156
HTTPServer::HTTPServer(

src/session/Session.cpp

Lines changed: 107 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,32 @@ namespace vix::session
9191
return true;
9292
}
9393

94+
task<bool> write_all(
95+
tcp_stream &stream,
96+
std::string_view data,
97+
vix::async::core::cancel_token token)
98+
{
99+
std::size_t written = 0;
100+
101+
while (written < data.size())
102+
{
103+
const std::byte *ptr =
104+
reinterpret_cast<const std::byte *>(data.data() + written);
105+
106+
const std::size_t n = co_await stream.async_write(
107+
std::span<const std::byte>(ptr, data.size() - written),
108+
token);
109+
110+
if (n == 0)
111+
{
112+
co_return false;
113+
}
114+
115+
written += n;
116+
}
117+
118+
co_return true;
119+
}
94120
inline bool is_close_connection(std::string_view value)
95121
{
96122
return equals_icase(value, "close");
@@ -107,6 +133,7 @@ namespace vix::session
107133
return pos + 4;
108134
}
109135

136+
#ifdef VIX_BENCH_MODE
110137
inline bool raw_header_requests_close(std::string_view raw_header)
111138
{
112139
std::size_t line_start = 0;
@@ -153,6 +180,17 @@ namespace vix::session
153180
return false;
154181
}
155182

183+
inline std::string_view strip_query_view(std::string_view target)
184+
{
185+
const auto q = target.find('?');
186+
if (q == std::string_view::npos)
187+
{
188+
return target;
189+
}
190+
191+
return target.substr(0, q);
192+
}
193+
#endif
156194
inline bool contains_token_icase(std::string_view text, std::string_view token)
157195
{
158196
if (token.empty())
@@ -220,16 +258,6 @@ namespace vix::session
220258
return out;
221259
}
222260

223-
inline std::string_view strip_query_view(std::string_view target)
224-
{
225-
const auto q = target.find('?');
226-
if (q == std::string_view::npos)
227-
{
228-
return target;
229-
}
230-
231-
return target.substr(0, q);
232-
}
233261
} // namespace
234262

235263
const std::regex Session::XSS_PATTERN(
@@ -724,24 +752,82 @@ namespace vix::session
724752

725753
try
726754
{
727-
std::string wire = res.to_http_string();
755+
if (!res.has_header("Server"))
756+
{
757+
res.set_header("Server", "Vix.cpp");
758+
}
728759

729-
std::size_t written = 0;
730-
while (written < wire.size())
760+
if (!res.has_header("Date"))
731761
{
732-
const std::byte *ptr =
733-
reinterpret_cast<const std::byte *>(wire.data() + written);
762+
res.set_header("Date", vix::http::Response::http_date_now());
763+
}
734764

735-
const std::size_t n = co_await stream_->async_write(
736-
std::span<const std::byte>(ptr, wire.size() - written),
737-
timer_cancel_.token());
765+
if (!res.has_header("Content-Length"))
766+
{
767+
res.set_header("Content-Length", std::to_string(res.body().size()));
768+
}
738769

739-
if (n == 0)
770+
if (!res.has_header("Connection"))
771+
{
772+
res.set_header("Connection", res.should_close() ? "close" : "keep-alive");
773+
}
774+
775+
std::string header_block;
776+
header_block.reserve(256 + res.headers().size() * 32);
777+
778+
header_block += res.version();
779+
header_block += ' ';
780+
header_block += std::to_string(res.status());
781+
header_block += ' ';
782+
783+
if (!res.reason().empty())
784+
{
785+
header_block += res.reason();
786+
}
787+
else
788+
{
789+
header_block += vix::http::reason_phrase(res.status());
790+
}
791+
792+
header_block += "\r\n";
793+
794+
for (const auto &[name, value] : res.headers())
795+
{
796+
header_block += name;
797+
header_block += ": ";
798+
header_block += value;
799+
header_block += "\r\n";
800+
}
801+
802+
header_block += "\r\n";
803+
804+
const std::string &body = res.body();
805+
const auto token = timer_cancel_.token();
806+
807+
constexpr std::size_t SMALL_RESPONSE_THRESHOLD = 1024;
808+
809+
if (body.size() <= SMALL_RESPONSE_THRESHOLD)
810+
{
811+
std::string wire;
812+
wire.reserve(header_block.size() + body.size());
813+
wire += header_block;
814+
wire += body;
815+
816+
const bool ok = co_await write_all(*stream_, wire, token);
817+
if (!ok)
740818
{
741-
break;
819+
must_close = true;
742820
}
821+
}
822+
else
823+
{
824+
const bool header_ok = co_await write_all(*stream_, header_block, token);
825+
const bool body_ok = header_ok ? co_await write_all(*stream_, body, token) : false;
743826

744-
written += n;
827+
if (!header_ok || !body_ok)
828+
{
829+
must_close = true;
830+
}
745831
}
746832

747833
#ifndef VIX_BENCH_MODE

0 commit comments

Comments
 (0)