Handle Expect: 100-continue
This commit is contained in:
parent
e871768d84
commit
1fa784c709
|
@ -49,6 +49,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
|
||||||
request_minor_(1),
|
request_minor_(1),
|
||||||
chunked_request_(false),
|
chunked_request_(false),
|
||||||
request_connection_close_(false),
|
request_connection_close_(false),
|
||||||
|
request_expect_100_continue_(false),
|
||||||
response_state_(INITIAL),
|
response_state_(INITIAL),
|
||||||
response_http_status_(0),
|
response_http_status_(0),
|
||||||
response_major_(1),
|
response_major_(1),
|
||||||
|
@ -111,15 +112,31 @@ void Downstream::force_resume_read()
|
||||||
ioctrl_.force_resume_read();
|
ioctrl_.force_resume_read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void check_header_field(bool *result, const Headers::value_type &item,
|
||||||
|
const char *name, const char *value)
|
||||||
|
{
|
||||||
|
if(util::strieq(item.first.c_str(), name)) {
|
||||||
|
if(util::strifind(item.second.c_str(), value)) {
|
||||||
|
*result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void check_transfer_encoding_chunked(bool *chunked,
|
void check_transfer_encoding_chunked(bool *chunked,
|
||||||
const Headers::value_type &item)
|
const Headers::value_type &item)
|
||||||
{
|
{
|
||||||
if(util::strieq(item.first.c_str(), "transfer-encoding")) {
|
return check_header_field(chunked, item, "transfer-encoding", "chunked");
|
||||||
if(util::strifind(item.second.c_str(), "chunked")) {
|
|
||||||
*chunked = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void check_expect_100_continue(bool *res,
|
||||||
|
const Headers::value_type& item)
|
||||||
|
{
|
||||||
|
return check_header_field(res, item, "expect", "100-continue");
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -148,6 +165,7 @@ void Downstream::set_last_request_header_value(const std::string& value)
|
||||||
Headers::value_type &item = request_headers_.back();
|
Headers::value_type &item = request_headers_.back();
|
||||||
item.second = value;
|
item.second = value;
|
||||||
check_transfer_encoding_chunked(&chunked_request_, item);
|
check_transfer_encoding_chunked(&chunked_request_, item);
|
||||||
|
check_expect_100_continue(&request_expect_100_continue_, item);
|
||||||
check_connection_close(&request_connection_close_, item);
|
check_connection_close(&request_connection_close_, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +234,11 @@ void Downstream::set_request_connection_close(bool f)
|
||||||
request_connection_close_ = f;
|
request_connection_close_ = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Downstream::get_expect_100_continue() const
|
||||||
|
{
|
||||||
|
return request_expect_100_continue_;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const size_t DOWNSTREAM_OUTPUT_UPPER_THRES = 64*1024;
|
const size_t DOWNSTREAM_OUTPUT_UPPER_THRES = 64*1024;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -255,6 +278,10 @@ int Downstream::push_request_headers()
|
||||||
if(util::strieq((*i).first.c_str(), "host")) {
|
if(util::strieq((*i).first.c_str(), "host")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(util::strieq((*i).first.c_str(), "expect") &&
|
||||||
|
util::strifind((*i).second.c_str(), "100-continue")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
hdrs += (*i).first;
|
hdrs += (*i).first;
|
||||||
hdrs += ": ";
|
hdrs += ": ";
|
||||||
hdrs += (*i).second;
|
hdrs += (*i).second;
|
||||||
|
|
|
@ -80,6 +80,7 @@ public:
|
||||||
bool get_chunked_request() const;
|
bool get_chunked_request() const;
|
||||||
bool get_request_connection_close() const;
|
bool get_request_connection_close() const;
|
||||||
void set_request_connection_close(bool f);
|
void set_request_connection_close(bool f);
|
||||||
|
bool get_expect_100_continue() const;
|
||||||
int push_upload_data_chunk(const uint8_t *data, size_t datalen);
|
int push_upload_data_chunk(const uint8_t *data, size_t datalen);
|
||||||
int end_upload_data();
|
int end_upload_data();
|
||||||
enum {
|
enum {
|
||||||
|
@ -122,6 +123,7 @@ private:
|
||||||
int request_minor_;
|
int request_minor_;
|
||||||
bool chunked_request_;
|
bool chunked_request_;
|
||||||
bool request_connection_close_;
|
bool request_connection_close_;
|
||||||
|
bool request_expect_100_continue_;
|
||||||
Headers request_headers_;
|
Headers request_headers_;
|
||||||
|
|
||||||
int response_state_;
|
int response_state_;
|
||||||
|
|
|
@ -161,6 +161,12 @@ int htp_hdrs_completecb(htparser *htp)
|
||||||
DownstreamConnection *dconn;
|
DownstreamConnection *dconn;
|
||||||
dconn = upstream->get_client_handler()->get_downstream_connection();
|
dconn = upstream->get_client_handler()->get_downstream_connection();
|
||||||
|
|
||||||
|
if(downstream->get_expect_100_continue()) {
|
||||||
|
static const char reply_100[] = "HTTP/1.1 100 Continue\r\n\r\n";
|
||||||
|
bufferevent_write(upstream->get_client_handler()->get_bev(),
|
||||||
|
reply_100, sizeof(reply_100)-1);
|
||||||
|
}
|
||||||
|
|
||||||
int rv = dconn->attach_downstream(downstream);
|
int rv = dconn->attach_downstream(downstream);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
downstream->set_request_state(Downstream::CONNECT_FAIL);
|
downstream->set_request_state(Downstream::CONNECT_FAIL);
|
||||||
|
|
Loading…
Reference in New Issue