-
Notifications
You must be signed in to change notification settings - Fork 30
allow empty header values #139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,7 +51,8 @@ const http_request_t::request_exception_t | |
| "The HTTP request version is not supported", | ||
| {CORS})); | ||
|
|
||
| template <class T> size_t name_max(const std::unordered_map<std::string, T>& methods) { | ||
| template <class T> | ||
| size_t name_max(const std::unordered_map<std::string, T>& methods) { | ||
| size_t i = 0; | ||
| for (const auto& kv : methods) | ||
| i = std::max(i, kv.first.size()); | ||
|
|
@@ -460,10 +461,11 @@ http_request_t::from_stream(const char* start, size_t length, size_t max_size) { | |
| // while the char is in the set, basically implement TRIM.. lets instead hope to ditch our | ||
| // custom parser | ||
| size_t field_end, value_begin; | ||
| if ((field_end = partial_buffer.find(':')) == std::string::npos || | ||
| (value_begin = partial_buffer.find_first_not_of(' ', field_end + 1)) == | ||
| std::string::npos) | ||
| if ((field_end = partial_buffer.find(':')) == std::string::npos) | ||
| throw RESPONSE_400; | ||
|
Comment on lines
+464
to
465
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok so we still bail if you send headers with no |
||
| if ((value_begin = partial_buffer.find_first_not_of(' ', field_end + 1)) == | ||
| std::string::npos) | ||
| value_begin = partial_buffer.size(); | ||
|
Comment on lines
+466
to
+468
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but now if you dont send a value or if your value is all whitespace we detect that and set the value to empty string |
||
| headers.insert({partial_buffer.substr(0, field_end), partial_buffer.substr(value_begin)}); | ||
| } // the end or body | ||
| else { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,12 +39,12 @@ class testable_http_server_t : public http_server_t { | |
| // remember the last response that was sent | ||
| std::vector<http_response_t> last_responses; | ||
| virtual bool dequeue(const http_request_info_t& info, const zmq::message_t& response) { | ||
| last_responses.emplace_back(http_response_t::from_string(static_cast<const char*>(response.data()), response.size())); | ||
| last_responses.emplace_back( | ||
| http_response_t::from_string(static_cast<const char*>(response.data()), response.size())); | ||
| try { | ||
| return http_server_t::dequeue(info, response); | ||
| } | ||
| catch(const std::runtime_error& e){ | ||
| if(std::string(e.what()).find("unreachable") == std::string::npos) { | ||
| } catch (const std::runtime_error& e) { | ||
| if (std::string(e.what()).find("unreachable") == std::string::npos) { | ||
| throw e; | ||
| } | ||
| } | ||
|
|
@@ -189,6 +189,27 @@ void test_request_parsing() { | |
| auto content_length = request.headers.find("content-length"); | ||
| if (content_length == request.headers.cend() || content_length->second != "11") | ||
| throw std::runtime_error("Request parsing failed"); | ||
|
|
||
| request_str = "GET /empty HTTP/1.1\r\nx-often-empty-header: \r\n\r\n"; | ||
| request = http_request_t::from_string(request_str.c_str(), request_str.size()); | ||
| auto empty = request.headers.find("x-often-empty-header"); | ||
| if (empty == request.headers.cend() || !empty->second.empty()) | ||
| throw std::runtime_error("Request parsing failed"); | ||
|
|
||
| request_str = "GET /empty HTTP/1.1\r\nx-often-empty-header:\r\n\r\n"; | ||
| request = http_request_t::from_string(request_str.c_str(), request_str.size()); | ||
| auto still_empty = request.headers.find("x-often-empty-header"); | ||
| if (still_empty == request.headers.cend() || !still_empty->second.empty()) | ||
| throw std::runtime_error("Request parsing failed"); | ||
|
Comment on lines
+193
to
+203
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we try with no value but a ton of whitespace and then again with literally nothing, then below we make sure that no colon still fails |
||
|
|
||
| request_str = "GET /bad_header HTTP/1.1\r\nx-bad-header-no-colon \r\n\r\n"; | ||
| try { | ||
| request = http_request_t::from_string(request_str.c_str(), request_str.size()); | ||
| throw std::runtime_error("Request parsing should have failed"); | ||
| } catch (const http_request_t::request_exception_t& e) { | ||
| if (e.code != 400) | ||
| throw std::runtime_error("Request parsing failed"); | ||
| } | ||
| } | ||
|
|
||
| void test_query_parsing() { | ||
|
|
@@ -265,10 +286,9 @@ void test_response_parsing() { | |
| void test_shortcircuit() { | ||
| // a server who lets us snoop on what its doing | ||
| zmq::context_t context; | ||
| testable_http_server_t server(context, "ipc:///tmp/test_http_server", | ||
| "ipc:///tmp/test_http_proxy_upstream", "ipc:///tmp/test_http_results", | ||
| "ipc:///tmp/test_http_interrupt", false, | ||
| MAX_REQUEST_SIZE, -1, | ||
| testable_http_server_t server( | ||
| context, "ipc:///tmp/test_http_server", "ipc:///tmp/test_http_proxy_upstream", | ||
| "ipc:///tmp/test_http_results", "ipc:///tmp/test_http_interrupt", false, MAX_REQUEST_SIZE, -1, | ||
|
Comment on lines
-268
to
+291
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. more linter blowback |
||
| [](const http_request_t& r) -> bool { return r.path == "/health_check"; }, | ||
| http_response_t{200, "OK", "foo_bar_baz"}.to_string()); | ||
| server.passify(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stupid linters