nghttpx: Implement cookie crumbling
This commit is contained in:
parent
0c669898a4
commit
e14baf134c
|
@ -179,6 +179,7 @@ size_t IGN_HDLEN = sizeof(IGN_HD)/sizeof(IGN_HD[0]);
|
|||
namespace {
|
||||
const char *HTTP1_IGN_HD[] = {
|
||||
"connection",
|
||||
"cookie",
|
||||
"expect",
|
||||
"http2-settings",
|
||||
"keep-alive",
|
||||
|
|
|
@ -106,7 +106,7 @@ void copy_norm_headers_to_nv
|
|||
|
||||
// Appends HTTP/1.1 style header lines to |hdrs| from headers in
|
||||
// |headers|. Certain headers, which requires special handling
|
||||
// (i.e. via), are not appended.
|
||||
// (i.e. via and cookie), are not appended.
|
||||
void build_http1_headers_from_norm_headers
|
||||
(std::string& hdrs,
|
||||
const std::vector<std::pair<std::string, std::string>>& headers);
|
||||
|
|
|
@ -92,6 +92,10 @@ int main(int argc, char* argv[])
|
|||
shrpx::test_downstream_get_norm_request_header) ||
|
||||
!CU_add_test(pSuite, "downstream_get_norm_response_header",
|
||||
shrpx::test_downstream_get_norm_response_header) ||
|
||||
!CU_add_test(pSuite, "downstream_crumble_request_cookie",
|
||||
shrpx::test_downstream_crumble_request_cookie) ||
|
||||
!CU_add_test(pSuite, "downstream_assemble_request_cookie",
|
||||
shrpx::test_downstream_assemble_request_cookie) ||
|
||||
!CU_add_test(pSuite, "util_streq", shrpx::test_util_streq) ||
|
||||
!CU_add_test(pSuite, "util_inp_strlower",
|
||||
shrpx::test_util_inp_strlower) ||
|
||||
|
|
|
@ -178,6 +178,69 @@ const Headers& Downstream::get_request_headers() const
|
|||
return request_headers_;
|
||||
}
|
||||
|
||||
void Downstream::assemble_request_cookie()
|
||||
{
|
||||
std::string& cookie = assembled_request_cookie_;
|
||||
cookie = "";
|
||||
for(auto& kv : request_headers_) {
|
||||
if(util::strieq("cookie", kv.first.c_str())) {
|
||||
auto end = kv.second.find_last_not_of(" ;");
|
||||
if(end == std::string::npos) {
|
||||
cookie += kv.second;
|
||||
} else {
|
||||
cookie.append(std::begin(kv.second), std::begin(kv.second) + end + 1);
|
||||
}
|
||||
cookie += "; ";
|
||||
}
|
||||
}
|
||||
if(cookie.size() >= 2) {
|
||||
cookie.erase(cookie.size() - 2);
|
||||
}
|
||||
}
|
||||
|
||||
void Downstream::crumble_request_cookie()
|
||||
{
|
||||
Headers cookie_hdrs;
|
||||
for(auto& kv : request_headers_) {
|
||||
if(util::strieq("cookie", kv.first.c_str())) {
|
||||
size_t last = kv.second.size();
|
||||
size_t num = 0;
|
||||
std::string rep_cookie;
|
||||
|
||||
for(size_t j = 0; j < last;) {
|
||||
j = kv.second.find_first_not_of("\t ;", j);
|
||||
if(j == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
auto first = j;
|
||||
|
||||
j = kv.second.find(';', j);
|
||||
if(j == std::string::npos) {
|
||||
j = last;
|
||||
}
|
||||
|
||||
if(num == 0) {
|
||||
rep_cookie = kv.second.substr(first, j - first);
|
||||
} else {
|
||||
cookie_hdrs.push_back
|
||||
(std::make_pair("cookie", kv.second.substr(first, j - first)));
|
||||
}
|
||||
++num;
|
||||
}
|
||||
if(num > 0) {
|
||||
kv.second = std::move(rep_cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
request_headers_.insert(std::end(request_headers_),
|
||||
std::begin(cookie_hdrs), std::end(cookie_hdrs));
|
||||
}
|
||||
|
||||
const std::string& Downstream::get_assembled_request_cookie() const
|
||||
{
|
||||
return assembled_request_cookie_;
|
||||
}
|
||||
|
||||
void Downstream::normalize_request_headers()
|
||||
{
|
||||
normalize_headers(request_headers_);
|
||||
|
|
|
@ -82,6 +82,9 @@ public:
|
|||
bool http2_upgrade_request() const;
|
||||
// downstream request API
|
||||
const Headers& get_request_headers() const;
|
||||
void crumble_request_cookie();
|
||||
void assemble_request_cookie();
|
||||
const std::string& get_assembled_request_cookie() const;
|
||||
// Makes key lowercase and sort headers by name using <
|
||||
void normalize_request_headers();
|
||||
// Returns iterator pointing to the request header with the name
|
||||
|
@ -197,6 +200,7 @@ private:
|
|||
bool chunked_request_;
|
||||
bool request_connection_close_;
|
||||
bool request_expect_100_continue_;
|
||||
std::string assembled_request_cookie_;
|
||||
Headers request_headers_;
|
||||
bool request_header_key_prev_;
|
||||
// the length of request body
|
||||
|
|
|
@ -110,4 +110,40 @@ void test_downstream_get_norm_response_header(void)
|
|||
CU_ASSERT(i == std::end(d.get_response_headers()));
|
||||
}
|
||||
|
||||
void test_downstream_crumble_request_cookie(void)
|
||||
{
|
||||
Downstream d(nullptr, 0, 0);
|
||||
d.add_request_header(":method", "get");
|
||||
d.add_request_header(":path", "/");
|
||||
d.add_request_header("cookie", "alpha; bravo; ; ;; charlie;;");
|
||||
d.add_request_header("cookie", ";delta");
|
||||
d.add_request_header("cookie", "echo");
|
||||
d.crumble_request_cookie();
|
||||
Headers ans = {
|
||||
std::make_pair(":method", "get"),
|
||||
std::make_pair(":path", "/"),
|
||||
std::make_pair("cookie", "alpha"),
|
||||
std::make_pair("cookie", "delta"),
|
||||
std::make_pair("cookie", "echo"),
|
||||
std::make_pair("cookie", "bravo"),
|
||||
std::make_pair("cookie", "charlie")
|
||||
};
|
||||
CU_ASSERT(ans == d.get_request_headers());
|
||||
}
|
||||
|
||||
void test_downstream_assemble_request_cookie(void)
|
||||
{
|
||||
Downstream d(nullptr, 0, 0);
|
||||
d.add_request_header(":method", "get");
|
||||
d.add_request_header(":path", "/");
|
||||
d.add_request_header("cookie", "alpha");
|
||||
d.add_request_header("cookie", "bravo;");
|
||||
d.add_request_header("cookie", "charlie; ");
|
||||
d.add_request_header("cookie", "delta;;");
|
||||
d.assemble_request_cookie();
|
||||
CU_ASSERT("alpha; bravo; charlie; delta" ==
|
||||
d.get_assembled_request_cookie());
|
||||
|
||||
}
|
||||
|
||||
} // namespace shrpx
|
||||
|
|
|
@ -31,6 +31,8 @@ void test_downstream_normalize_request_headers(void);
|
|||
void test_downstream_normalize_response_headers(void);
|
||||
void test_downstream_get_norm_request_header(void);
|
||||
void test_downstream_get_norm_response_header(void);
|
||||
void test_downstream_crumble_request_cookie(void);
|
||||
void test_downstream_assemble_request_cookie(void);
|
||||
|
||||
} // namespace shrpx
|
||||
|
||||
|
|
|
@ -228,6 +228,7 @@ int Http2DownstreamConnection::push_request_headers()
|
|||
return 0;
|
||||
}
|
||||
size_t nheader = downstream_->get_request_headers().size();
|
||||
downstream_->crumble_request_cookie();
|
||||
downstream_->normalize_request_headers();
|
||||
auto end_headers = std::end(downstream_->get_request_headers());
|
||||
// 12 means:
|
||||
|
|
|
@ -116,6 +116,7 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream)
|
|||
|
||||
int HttpDownstreamConnection::push_request_headers()
|
||||
{
|
||||
downstream_->assemble_request_cookie();
|
||||
downstream_->normalize_request_headers();
|
||||
auto end_headers = std::end(downstream_->get_request_headers());
|
||||
// Assume that method and request path do not contain \r\n.
|
||||
|
@ -152,6 +153,12 @@ int HttpDownstreamConnection::push_request_headers()
|
|||
http2::build_http1_headers_from_norm_headers
|
||||
(hdrs, downstream_->get_request_headers());
|
||||
|
||||
if(!downstream_->get_assembled_request_cookie().empty()) {
|
||||
hdrs += "Cookie: ";
|
||||
hdrs += downstream_->get_assembled_request_cookie();
|
||||
hdrs += "\r\n";
|
||||
}
|
||||
|
||||
if(downstream_->get_request_connection_close()) {
|
||||
hdrs += "Connection: close\r\n";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue