Skip to content

Commit 8a803b3

Browse files
committed
Fix #990
1 parent 80be649 commit 8a803b3

File tree

1 file changed

+47
-14
lines changed

1 file changed

+47
-14
lines changed

httplib.h

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,25 +4520,58 @@ inline void Server::stop() {
45204520
}
45214521

45224522
inline bool Server::parse_request_line(const char *s, Request &req) {
4523-
const static std::regex re(
4524-
"(GET|HEAD|POST|PUT|DELETE|CONNECT|OPTIONS|TRACE|PATCH|PRI) "
4525-
"(([^? ]+)(?:\\?([^ ]*?))?) (HTTP/1\\.[01])\r\n");
4523+
auto len = strlen(s);
4524+
if (len < 2 || s[len - 2] != '\r' || s[len - 1] != '\n') { return false; }
4525+
len -= 2;
45264526

4527-
std::cmatch m;
4528-
if (std::regex_match(s, m, re)) {
4529-
req.version = std::string(m[5]);
4530-
req.method = std::string(m[1]);
4531-
req.target = std::string(m[2]);
4532-
req.path = detail::decode_url(m[3], false);
4527+
{
4528+
size_t count = 0;
4529+
4530+
detail::split(s, s + len, ' ', [&](const char *b, const char *e) {
4531+
switch (count) {
4532+
case 0: req.method = std::string(b, e); break;
4533+
case 1: req.target = std::string(b, e); break;
4534+
case 2: req.version = std::string(b, e); break;
4535+
default: break;
4536+
}
4537+
count++;
4538+
});
45334539

4534-
// Parse query text
4535-
auto len = std::distance(m[4].first, m[4].second);
4536-
if (len > 0) { detail::parse_query_text(m[4], req.params); }
4540+
if (count != 3) { return false; }
4541+
}
45374542

4538-
return true;
4543+
const std::set<std::string> methods{"GET", "HEAD", "POST", "PUT",
4544+
"DELETE", "CONNECT", "OPTIONS", "TRACE",
4545+
"PATCH", "PRI"};
4546+
4547+
if (methods.find(req.method) == methods.end()) { return false; }
4548+
4549+
if (req.version != "HTTP/1.1" && req.version != "HTTP/1.0") { return false; }
4550+
4551+
{
4552+
size_t count = 0;
4553+
4554+
detail::split(req.target.data(), req.target.data() + req.target.size(), '?',
4555+
[&](const char *b, const char *e) {
4556+
switch (count) {
4557+
case 0:
4558+
req.path = detail::decode_url(std::string(b, e), false);
4559+
break;
4560+
case 1: {
4561+
if (e - b > 0) {
4562+
detail::parse_query_text(std::string(b, e), req.params);
4563+
}
4564+
break;
4565+
}
4566+
default: break;
4567+
}
4568+
count++;
4569+
});
4570+
4571+
if (count > 2) { return false; }
45394572
}
45404573

4541-
return false;
4574+
return true;
45424575
}
45434576

45444577
inline bool Server::write_response(Stream &strm, bool close_connection,

0 commit comments

Comments
 (0)