mirror of
https://github.com/nginx/nginx.git
synced 2024-12-22 15:13:28 -06:00
nginx-0.0.1-2003-04-25-18:43:13 import
This commit is contained in:
parent
0e18ebd0d9
commit
a09f08dbab
@ -2,3 +2,6 @@
|
||||
#ifndef OFF_EQUAL_PTR
|
||||
#define OFF_EQUAL_PTR 0
|
||||
#endif
|
||||
|
||||
|
||||
#define NGX_PAGE_SIZE 4096
|
||||
|
@ -24,6 +24,7 @@ typedef struct {
|
||||
|
||||
static int ngx_http_proxy_handler(ngx_http_request_t *r);
|
||||
|
||||
static int ngx_http_proxy_read_client_body(ngx_http_proxy_ctx_t *p);
|
||||
static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p);
|
||||
static int ngx_http_proxy_process_upstream(ngx_http_proxy_ctx_t *p,
|
||||
ngx_event_t *ev);
|
||||
@ -182,7 +183,11 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||
p->method = r->method;
|
||||
p->headers_in.headers = ngx_create_table(r->pool, 10);
|
||||
|
||||
/* TODO: read a client's body */
|
||||
if (r->headers_in.content_length_n > 0) {
|
||||
if (ngx_http_proxy_read_client_body(p) == NGX_ERROR) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
chain = ngx_http_proxy_create_request(p);
|
||||
if (chain == NULL) {
|
||||
@ -204,6 +209,53 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
|
||||
static int ngx_http_proxy_read_client_body(ngx_http_proxy_ctx_t *p)
|
||||
{
|
||||
int size, first_part;
|
||||
ngx_hunk_t *h;
|
||||
ngx_http_request_t *r;
|
||||
|
||||
r = p->request;
|
||||
|
||||
first_part = r->header_in->last - r->header_in->pos;
|
||||
|
||||
if (first_part > r->headers_in.content_length_n) {
|
||||
first_part = r->headers_in.content_length_n;
|
||||
size = 0;
|
||||
|
||||
} else {
|
||||
size = r->headers_in.content_length_n - first_part;
|
||||
if (size > p->lcf->client_request_buffer_size) {
|
||||
size = p->lcf->client_request_buffer_size;
|
||||
|
||||
} else if (size > NGX_PAGE_SIZE) {
|
||||
size = ((size + NGX_PAGE_SIZE) / NGX_PAGE_SIZE) * NGX_PAGE_SIZE;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
ngx_test_null(p->client_request_hunk, ngx_palloc(r->pool, size),
|
||||
NGX_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (first_part) {
|
||||
ngx_test_null(h, ngx_alloc_hunk(r->pool), NGX_ERROR);
|
||||
|
||||
h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
|
||||
h->pos = h->start = h->pre_start = r->header_in->pos;
|
||||
h->last = h->end = h->post_end = r->header_in->pos + first_part;
|
||||
h->file_pos = h->file_last = 0;
|
||||
h->file = NULL;
|
||||
h->shadow = NULL;
|
||||
h->tag = 0;
|
||||
|
||||
p->client_first_part_hunk = h;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
|
||||
{
|
||||
int i;
|
||||
|
@ -61,6 +61,7 @@ typedef struct {
|
||||
ngx_http_proxy_upstreams_t *upstreams;
|
||||
ngx_http_proxy_upstream_url_t *upstream_url;
|
||||
|
||||
int client_request_buffer_size;
|
||||
int rcvbuf;
|
||||
int conn_pool_size;
|
||||
int connect_timeout;
|
||||
@ -99,6 +100,7 @@ typedef struct ngx_http_proxy_ctx_s ngx_http_proxy_ctx_t;
|
||||
struct ngx_http_proxy_ctx_s {
|
||||
ngx_event_proxy_t *event_proxy;
|
||||
|
||||
|
||||
ngx_chain_t *in_hunks;
|
||||
ngx_chain_t *last_in_hunk;
|
||||
|
||||
@ -109,8 +111,12 @@ struct ngx_http_proxy_ctx_s {
|
||||
|
||||
ngx_chain_t *free_hunks;
|
||||
|
||||
|
||||
ngx_chain_t *request_hunks;
|
||||
|
||||
ngx_hunk_t *client_request_hunk;
|
||||
ngx_hunk_t *client_first_part_hunk;
|
||||
|
||||
ngx_connection_t *connection;
|
||||
ngx_http_request_t *request;
|
||||
ngx_http_proxy_headers_in_t headers_in;
|
||||
|
@ -27,14 +27,15 @@
|
||||
#define NGX_HTTP_CONN_KEEP_ALIVE 1
|
||||
|
||||
|
||||
#define NGX_HTTP_PARSE_HEADER_DONE 1
|
||||
#define NGX_HTTP_PARSE_INVALID_METHOD 10
|
||||
#define NGX_HTTP_PARSE_INVALID_REQUEST 11
|
||||
#define NGX_HTTP_PARSE_TOO_LONG_URI 12
|
||||
#define NGX_HTTP_PARSE_INVALID_HEAD 13
|
||||
#define NGX_HTTP_PARSE_INVALID_HEADER 14
|
||||
#define NGX_HTTP_PARSE_TOO_LONG_HEADER 15
|
||||
#define NGX_HTTP_PARSE_NO_HOST_HEADER 16
|
||||
#define NGX_HTTP_PARSE_HEADER_DONE 1
|
||||
#define NGX_HTTP_PARSE_INVALID_METHOD 10
|
||||
#define NGX_HTTP_PARSE_INVALID_REQUEST 11
|
||||
#define NGX_HTTP_PARSE_TOO_LONG_URI 12
|
||||
#define NGX_HTTP_PARSE_INVALID_HEAD 13
|
||||
#define NGX_HTTP_PARSE_INVALID_HEADER 14
|
||||
#define NGX_HTTP_PARSE_TOO_LONG_HEADER 15
|
||||
#define NGX_HTTP_PARSE_NO_HOST_HEADER 16
|
||||
#define NGX_HTTP_PARSE_INVALID_CL_HEADER 17
|
||||
|
||||
|
||||
#define NGX_HTTP_OK 200
|
||||
@ -70,10 +71,12 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
size_t host_name_len;
|
||||
ssize_t content_length_n;
|
||||
|
||||
ngx_table_elt_t *host;
|
||||
ngx_table_elt_t *connection;
|
||||
ngx_table_elt_t *if_modified_since;
|
||||
ngx_table_elt_t *content_length;
|
||||
ngx_table_elt_t *accept_encoding;
|
||||
|
||||
ngx_table_elt_t *user_agent;
|
||||
@ -141,7 +144,6 @@ struct ngx_http_request_s {
|
||||
|
||||
int filter;
|
||||
|
||||
ssize_t client_content_length;
|
||||
char *discarded_buffer;
|
||||
|
||||
ngx_str_t path;
|
||||
|
@ -47,7 +47,8 @@ static char *header_errors[] = {
|
||||
|
||||
"client %s sent invalid header, URL: %s",
|
||||
"client %s sent too long header line, URL: %s",
|
||||
"client %s sent HTTP/1.1 request without \"Host\" header, URL: %s"
|
||||
"client %s sent HTTP/1.1 request without \"Host\" header, URL: %s",
|
||||
"client %s sent invalid \"Content-Length\" header, URL: %s"
|
||||
};
|
||||
|
||||
|
||||
@ -57,6 +58,8 @@ static ngx_http_header_t headers_in[] = {
|
||||
{ ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection) },
|
||||
{ ngx_string("If-Modified-Since"),
|
||||
offsetof(ngx_http_headers_in_t, if_modified_since) },
|
||||
{ ngx_string("Content-Length"),
|
||||
offsetof(ngx_http_headers_in_t, content_length) },
|
||||
|
||||
{ ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent) },
|
||||
|
||||
@ -169,6 +172,7 @@ static int ngx_http_init_request(ngx_event_t *rev)
|
||||
r->srv_conf = ctx->srv_conf;
|
||||
r->loc_conf = ctx->loc_conf;
|
||||
|
||||
r->headers_in.content_length_n = -1;
|
||||
r->headers_out.headers = ngx_create_table(r->pool, 10);
|
||||
r->headers_out.content_length = -1;
|
||||
r->headers_out.last_modified_time = -1;
|
||||
@ -531,6 +535,17 @@ static int ngx_http_process_request_headers(ngx_http_request_t *r)
|
||||
r->headers_in.host_name_len = 0;
|
||||
}
|
||||
|
||||
if (r->headers_in.content_length) {
|
||||
r->headers_in.content_length_n =
|
||||
ngx_atoi(r->headers_in.content_length->value.data,
|
||||
r->headers_in.content_length->value.len);
|
||||
if (r->headers_in.content_length_n == NGX_ERROR) {
|
||||
ngx_http_header_parse_error(r,
|
||||
NGX_HTTP_PARSE_INVALID_CL_HEADER);
|
||||
return NGX_HTTP_BAD_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
r->state_handler = NULL;
|
||||
return NGX_OK;
|
||||
|
||||
@ -815,7 +830,7 @@ int ngx_http_discard_body(ngx_http_request_t *r)
|
||||
ev->timer_set = 0;
|
||||
}
|
||||
|
||||
if (r->client_content_length) {
|
||||
if (r->headers_in.content_length_n) {
|
||||
ev->event_handler = ngx_http_read_discarded_body;
|
||||
/* if blocked - read */
|
||||
/* else add timer */
|
||||
@ -852,7 +867,7 @@ static int ngx_http_read_discarded_body(ngx_event_t *ev)
|
||||
NGX_ERROR);
|
||||
}
|
||||
|
||||
size = r->client_content_length;
|
||||
size = r->headers_in.content_length_n;
|
||||
if (size > lcf->discarded_buffer_size) {
|
||||
size = lcf->discarded_buffer_size;
|
||||
}
|
||||
@ -866,7 +881,7 @@ static int ngx_http_read_discarded_body(ngx_event_t *ev)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
r->client_content_length -= n;
|
||||
r->headers_in.content_length_n -= n;
|
||||
/* XXX: what if r->client_content_length == 0 ? */
|
||||
return NGX_OK;
|
||||
}
|
||||
|
196
src/http/ngx_http_request_body.c
Normal file
196
src/http/ngx_http_request_body.c
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
|
||||
|
||||
|
||||
int ngx_http_start_read_client_body(ngx_http_proxy_ctx_t *p)
|
||||
{
|
||||
int first_part, size;
|
||||
ngx_hunk_t *h;
|
||||
ngx_http_request_t *r;
|
||||
|
||||
r = p->request;
|
||||
|
||||
first_part = r->header_in->last - r->header_in->pos;
|
||||
|
||||
if (first_part > r->headers_in.content_length_n) {
|
||||
first_part = r->headers_in.content_length_n;
|
||||
size = 0;
|
||||
|
||||
} else {
|
||||
size = r->headers_in.content_length_n - first_part;
|
||||
if (size > p->lcf->client_request_buffer_size) {
|
||||
size = p->lcf->client_request_buffer_size;
|
||||
|
||||
} else if (size > NGX_PAGE_SIZE) {
|
||||
size = ((size + NGX_PAGE_SIZE) / NGX_PAGE_SIZE) * NGX_PAGE_SIZE;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
ngx_test_null(p->client_request_hunk, ngx_palloc(r->pool, size),
|
||||
NGX_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (first_part) {
|
||||
ngx_test_null(h, ngx_alloc_hunk(r->pool), NGX_ERROR);
|
||||
|
||||
h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
|
||||
h->pos = h->start = h->pre_start = r->header_in->pos;
|
||||
h->last = h->end = h->post_end = r->header_in->pos + first_part;
|
||||
h->file_pos = h->file_last = 0;
|
||||
h->file = NULL;
|
||||
h->shadow = NULL;
|
||||
h->tag = 0;
|
||||
|
||||
p->client_first_part_hunk = h;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
int ngx_http_read_client_body(ngx_event_t *rev)
|
||||
{
|
||||
|
||||
do {
|
||||
if (r->header_in->last < r->header_in->end) {
|
||||
rb->chain[0].hunk = r->header_in;
|
||||
|
||||
if (rb->hunk) {
|
||||
rb->chain[0].next = &rb->chain[1];
|
||||
rb->chain[1].hunk = rb->hunk;
|
||||
rb->chain[1].next = NULL;
|
||||
|
||||
} else {
|
||||
rb->chain[0].next = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
rb->chain[0].hunk = rb->hunk;
|
||||
rb->chain[0].next = NULL;
|
||||
}
|
||||
|
||||
n = ngx_recv_chain(c, &rb->chain);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
for (entry = &rb->chain; entry; entry = entry->next) {
|
||||
size = entry->hunk->end - entry->hunk->last;
|
||||
|
||||
if (n >= size) {
|
||||
n -= size;
|
||||
entry->hunk->last = entry->hunk->end;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
entry->hunk->last += n;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (rb->hunk && rb->hunk->last == rb->hunk->end) {
|
||||
if (rb->temp_file->fd == NGX_INVALID_FILE) {
|
||||
rc = ngx_create_temp_file(rb->temp_file, rb->temp_path, r->pool,
|
||||
rb->number, rb->random, 0);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
n = ngx_write_file(rb->temp_file, rb->hunk,
|
||||
rb->hunk->last - rb->hunk->pos, rb->offset);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rb->offset += n;
|
||||
rb->hunk->last = rb->hunk->pos;
|
||||
}
|
||||
|
||||
} while (rev->ready);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
int ngx_init_client_request_body_chain(ngx_http_reuqest_t *r)
|
||||
{
|
||||
int i;
|
||||
ngx_hunk_t *h;
|
||||
ngx_http_request_body_t *rb;
|
||||
|
||||
rb = r->request_body;
|
||||
|
||||
rb->chain[0].hunk = rb->header_out;
|
||||
i = 0;
|
||||
|
||||
if (r->header_in->pos < r->header_in->last) {
|
||||
rb->chain[i].next = &rb->chain[i + 1];
|
||||
i++;
|
||||
rb->chain[i].hunk = r->header_in;
|
||||
}
|
||||
|
||||
if (rb->temp_file->fd != NGX_INVALID_FILE) {
|
||||
if (rb->file_hunk == NULL) {
|
||||
ngx_test_null(h, ngx_alloc_hunk(r->pool), NGX_ERROR);
|
||||
|
||||
h->type = NGX_HUNK_FILE;
|
||||
h->pos = h->start = h->pre_start = 0;
|
||||
h->last = h->end = h->post_end = 0;
|
||||
h->file_pos = 0;
|
||||
h->file_last = rb->offset;
|
||||
h->file = rb->temp_file;
|
||||
h->shadow = NULL;
|
||||
h->tag = 0;
|
||||
|
||||
rb->file_hunk = h;
|
||||
}
|
||||
|
||||
rb->chain[i].next = &rb->chain[i + 1];
|
||||
i++;
|
||||
rb->chain[i].hunk = rb->file_hunk;
|
||||
}
|
||||
|
||||
if (rb->hunk && rb->hunk->pos < rb->hunk->last) {
|
||||
rb->chain[i].next = &rb->chain[i + 1];
|
||||
i++;
|
||||
rb->chain[i].hunk = h;
|
||||
}
|
||||
|
||||
rb->chain[i].next = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
int ngx_reinit_client_request_body_hunks(ngx_http_reuqest_t *r)
|
||||
{
|
||||
ngx_http_request_body_t *rb;
|
||||
|
||||
rb = r->request_body;
|
||||
|
||||
if (rb->header_in_pos) {
|
||||
r->header_in->pos = rb->header_in_pos;
|
||||
}
|
||||
|
||||
if (rb->file_hunk) {
|
||||
rb->file_hunk->file_pos = rb->file_hunk->file_start;
|
||||
}
|
||||
|
||||
if (rb->hunk) {
|
||||
rb->hunk->pos = rb->hunk->start;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user