the "Expect" header support

This commit is contained in:
Igor Sysoev 2008-06-26 13:00:39 +00:00
parent 24329bf299
commit 1e1f4c8a04
4 changed files with 57 additions and 1 deletions

View File

@ -402,6 +402,7 @@ static ngx_keyval_t ngx_http_proxy_headers[] = {
{ ngx_string("Host"), ngx_string("$proxy_host") }, { ngx_string("Host"), ngx_string("$proxy_host") },
{ ngx_string("Connection"), ngx_string("close") }, { ngx_string("Connection"), ngx_string("close") },
{ ngx_string("Keep-Alive"), ngx_string("") }, { ngx_string("Keep-Alive"), ngx_string("") },
{ ngx_string("Expect"), ngx_string("") },
{ ngx_null_string, ngx_null_string } { ngx_null_string, ngx_null_string }
}; };

View File

@ -25,6 +25,7 @@ typedef struct {
static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r); static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r, static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
ngx_http_location_tree_node_t *node); ngx_http_location_tree_node_t *node);
static ngx_int_t ngx_http_core_send_continue(ngx_http_request_t *r);
static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf); static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
static void *ngx_http_core_create_main_conf(ngx_conf_t *cf); static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
@ -771,7 +772,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
{ {
u_char *p; u_char *p;
size_t len; size_t len;
ngx_int_t rc; ngx_int_t rc, expect;
ngx_http_core_loc_conf_t *clcf; ngx_http_core_loc_conf_t *clcf;
r->content_handler = NULL; r->content_handler = NULL;
@ -815,6 +816,15 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
return NGX_OK; return NGX_OK;
} }
if (r->headers_in.expect) {
expect = ngx_http_core_send_continue(r);
if (expect != NGX_OK) {
ngx_http_finalize_request(r, expect);
return NGX_OK;
}
}
if (rc == NGX_DONE) { if (rc == NGX_DONE) {
r->headers_out.location = ngx_list_push(&r->headers_out.headers); r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) { if (r->headers_out.location == NULL) {
@ -1244,6 +1254,45 @@ ngx_http_core_find_static_location(ngx_http_request_t *r,
} }
static ngx_int_t
ngx_http_core_send_continue(ngx_http_request_t *r)
{
ngx_int_t n;
ngx_str_t *expect;
if (r->expect_tested) {
return NGX_OK;
}
r->expect_tested = 1;
expect = &r->headers_in.expect->value;
if (expect->len != sizeof("100-continue") - 1
|| ngx_strncasecmp(expect->data, (u_char *) "100-continue",
sizeof("100-continue") - 1)
!= 0)
{
return NGX_OK;
}
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"send 100 Continue");
n = r->connection->send(r->connection,
(u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
return NGX_OK;
}
/* we assume that such small packet should be send successfully */
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_int_t ngx_int_t
ngx_http_set_content_type(ngx_http_request_t *r) ngx_http_set_content_type(ngx_http_request_t *r)
{ {

View File

@ -106,6 +106,10 @@ ngx_http_header_t ngx_http_headers_in[] = {
offsetof(ngx_http_headers_in_t, transfer_encoding), offsetof(ngx_http_headers_in_t, transfer_encoding),
ngx_http_process_header_line }, ngx_http_process_header_line },
{ ngx_string("Expect"),
offsetof(ngx_http_headers_in_t, expect),
ngx_http_process_unique_header_line },
#if (NGX_HTTP_GZIP) #if (NGX_HTTP_GZIP)
{ ngx_string("Accept-Encoding"), { ngx_string("Accept-Encoding"),
offsetof(ngx_http_headers_in_t, accept_encoding), offsetof(ngx_http_headers_in_t, accept_encoding),

View File

@ -171,6 +171,7 @@ typedef struct {
ngx_table_elt_t *if_range; ngx_table_elt_t *if_range;
ngx_table_elt_t *transfer_encoding; ngx_table_elt_t *transfer_encoding;
ngx_table_elt_t *expect;
#if (NGX_HTTP_GZIP) #if (NGX_HTTP_GZIP)
ngx_table_elt_t *accept_encoding; ngx_table_elt_t *accept_encoding;
@ -467,6 +468,7 @@ struct ngx_http_request_s {
unsigned request_complete:1; unsigned request_complete:1;
unsigned request_output:1; unsigned request_output:1;
unsigned header_sent:1; unsigned header_sent:1;
unsigned expect_tested:1;
unsigned done:1; unsigned done:1;
unsigned utf8:1; unsigned utf8:1;