mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 17:52:38 +08:00
nginx-0.0.1-2002-08-29-20:59:54 import
This commit is contained in:
parent
0ad17c0903
commit
016b852702
@ -14,6 +14,9 @@ void *ngx_alloc(size_t size, ngx_log_t *log)
|
|||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
|
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
|
||||||
"malloc() %d bytes failed", size);
|
"malloc() %d bytes failed", size);
|
||||||
|
|
||||||
|
ngx_log_debug(log, "malloc: %x" _ p);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ struct ngx_connection_s {
|
|||||||
char *addr_text;
|
char *addr_text;
|
||||||
size_t addr_textlen;
|
size_t addr_textlen;
|
||||||
|
|
||||||
time_t post_accept_timeout;
|
unsigned int post_accept_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +57,9 @@ struct ngx_chain_s {
|
|||||||
ngx_chain_t *next;
|
ngx_chain_t *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ngx_create_temp_hunk(pool, size, before, after) \
|
||||||
|
ngx_get_hunk(pool, size, before, after)
|
||||||
|
|
||||||
#define ngx_add_hunk_to_chain(chain, h, pool, error) \
|
#define ngx_add_hunk_to_chain(chain, h, pool, error) \
|
||||||
do { \
|
do { \
|
||||||
ngx_test_null(chain, ngx_create_chain_entry(pool), error); \
|
ngx_test_null(chain, ngx_create_chain_entry(pool), error); \
|
||||||
@ -66,6 +69,7 @@ struct ngx_chain_s {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after);
|
ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after);
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
|
#include <ngx_core.h>
|
||||||
#include <ngx_types.h>
|
#include <ngx_types.h>
|
||||||
#include <ngx_log.h>
|
#include <ngx_log.h>
|
||||||
#include <ngx_connection.h>
|
#include <ngx_connection.h>
|
||||||
@ -19,7 +20,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
|
static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
|
||||||
static void ngx_inline ngx_del_timer(ngx_event_t *ev);
|
|
||||||
|
|
||||||
|
|
||||||
static int kq;
|
static int kq;
|
||||||
@ -145,7 +145,7 @@ int ngx_kqueue_process_events(ngx_log_t *log)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug(log, "ngx_kqueue_process_events: "
|
ngx_log_debug(log, "ngx_kqueue_process_events: "
|
||||||
"timer: %d, delta: %d" _ timer _ delta);
|
"timer: %d, delta: %d" _ timer _ delta);
|
||||||
|
|
||||||
if (timer) {
|
if (timer) {
|
||||||
if (delta >= timer) {
|
if (delta >= timer) {
|
||||||
@ -158,7 +158,7 @@ int ngx_kqueue_process_events(ngx_log_t *log)
|
|||||||
ngx_del_timer(ev);
|
ngx_del_timer(ev);
|
||||||
#if 1
|
#if 1
|
||||||
ev->timedout = 1;
|
ev->timedout = 1;
|
||||||
if (ev->event_handler(ev) == -1)
|
if (ev->event_handler(ev) == NGX_ERROR)
|
||||||
ev->close_handler(ev);
|
ev->close_handler(ev);
|
||||||
#else
|
#else
|
||||||
if (ev->timer_handler(ev) == -1)
|
if (ev->timer_handler(ev) == -1)
|
||||||
@ -200,7 +200,7 @@ int ngx_kqueue_process_events(ngx_log_t *log)
|
|||||||
ev->error = event_list[i].fflags;
|
ev->error = event_list[i].fflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev->event_handler(ev) == -1)
|
if (ev->event_handler(ev) == NGX_ERROR)
|
||||||
ev->close_handler(ev);
|
ev->close_handler(ev);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -233,6 +233,7 @@ static void ngx_add_timer_core(ngx_event_t *ev, u_int timer)
|
|||||||
e->timer_prev = ev;
|
e->timer_prev = ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
|
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
|
||||||
{
|
{
|
||||||
if (ev->timer_prev)
|
if (ev->timer_prev)
|
||||||
@ -240,9 +241,10 @@ static void ngx_inline ngx_del_timer(ngx_event_t *ev)
|
|||||||
|
|
||||||
if (ev->timer_next) {
|
if (ev->timer_next) {
|
||||||
ev->timer_next->timer_prev = ev->timer_prev;
|
ev->timer_next->timer_prev = ev->timer_prev;
|
||||||
ev->timer_prev = NULL;
|
ev->timer_next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev->timer_prev)
|
if (ev->timer_prev)
|
||||||
ev->timer_next = NULL;
|
ev->timer_prev = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -24,7 +24,6 @@ static ngx_event_t timer_queue;
|
|||||||
|
|
||||||
|
|
||||||
static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
|
static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
|
||||||
static void ngx_inline ngx_del_timer(ngx_event_t *ev);
|
|
||||||
|
|
||||||
static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
|
static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
|
||||||
ngx_log_t *log);
|
ngx_log_t *log);
|
||||||
@ -338,6 +337,7 @@ static void ngx_add_timer_core(ngx_event_t *ev, u_int timer)
|
|||||||
e->timer_prev = ev;
|
e->timer_prev = ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
|
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
|
||||||
{
|
{
|
||||||
if (ev->timer_prev)
|
if (ev->timer_prev)
|
||||||
@ -345,9 +345,10 @@ static void ngx_inline ngx_del_timer(ngx_event_t *ev)
|
|||||||
|
|
||||||
if (ev->timer_next) {
|
if (ev->timer_next) {
|
||||||
ev->timer_next->timer_prev = ev->timer_prev;
|
ev->timer_next->timer_prev = ev->timer_prev;
|
||||||
ev->timer_prev = NULL;
|
ev->timer_next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev->timer_prev)
|
if (ev->timer_prev)
|
||||||
ev->timer_next = NULL;
|
ev->timer_prev = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -19,7 +19,7 @@ ngx_event_t *ngx_read_events, *ngx_write_events;
|
|||||||
|
|
||||||
#if !(USE_KQUEUE)
|
#if !(USE_KQUEUE)
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT;
|
ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT;
|
||||||
#else
|
#else
|
||||||
ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT;
|
ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT;
|
||||||
|
@ -133,6 +133,23 @@ NGX_AIO_EVENT overlapped, aio_read, aioread
|
|||||||
|
|
||||||
#define ngx_add_timer(ev, time) ngx_add_event(ev, NGX_TIMER_EVENT, time)
|
#define ngx_add_timer(ev, time) ngx_add_event(ev, NGX_TIMER_EVENT, time)
|
||||||
|
|
||||||
|
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
|
||||||
|
{
|
||||||
|
if (ev->timer_prev)
|
||||||
|
ev->timer_prev->timer_next = ev->timer_next;
|
||||||
|
|
||||||
|
if (ev->timer_next) {
|
||||||
|
ev->timer_next->timer_prev = ev->timer_prev;
|
||||||
|
ev->timer_next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev->timer_prev)
|
||||||
|
ev->timer_prev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern ngx_event_t *ngx_read_events;
|
extern ngx_event_t *ngx_read_events;
|
||||||
extern ngx_event_t *ngx_write_events;
|
extern ngx_event_t *ngx_write_events;
|
||||||
extern ngx_connection_t *ngx_connections;
|
extern ngx_connection_t *ngx_connections;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
|
#include <ngx_core.h>
|
||||||
#include <ngx_types.h>
|
#include <ngx_types.h>
|
||||||
#include <ngx_connection.h>
|
#include <ngx_connection.h>
|
||||||
#include <ngx_event_close.h>
|
#include <ngx_event_close.h>
|
||||||
@ -8,22 +9,24 @@
|
|||||||
int ngx_event_close_connection(ngx_event_t *ev)
|
int ngx_event_close_connection(ngx_event_t *ev)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
ngx_connection_t *cn = (ngx_connection_t *) ev->data;
|
ngx_connection_t *c = (ngx_connection_t *) ev->data;
|
||||||
|
|
||||||
ngx_assert((cn->fd != -1), return -1, ev->log,
|
ngx_assert((c->fd != -1), return NGX_ERROR, c->log,
|
||||||
"ngx_event_close: already closed");
|
"ngx_event_close: already closed");
|
||||||
|
|
||||||
if ((rc = ngx_close_socket(cn->fd)) == -1)
|
ngx_destroy_pool(c->pool);
|
||||||
ngx_log_error(NGX_LOG_ERR, ev->log, ngx_socket_errno,
|
|
||||||
|
if ((rc = ngx_close_socket(c->fd)) == -1)
|
||||||
|
ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
|
||||||
"ngx_event_close: close failed");
|
"ngx_event_close: close failed");
|
||||||
|
|
||||||
if (cn->read->next)
|
if (c->read->next)
|
||||||
ngx_del_event(cn->read, NGX_READ_EVENT);
|
ngx_del_event(c->read, NGX_READ_EVENT);
|
||||||
|
|
||||||
if (cn->write->next)
|
if (c->write->next)
|
||||||
ngx_del_event(cn->write, NGX_WRITE_EVENT);
|
ngx_del_event(c->write, NGX_WRITE_EVENT);
|
||||||
|
|
||||||
cn->fd = -1;
|
c->fd = -1;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -6,29 +6,27 @@
|
|||||||
#include <ngx_recv.h>
|
#include <ngx_recv.h>
|
||||||
#include <ngx_connection.h>
|
#include <ngx_connection.h>
|
||||||
|
|
||||||
int ngx_event_recv_core(ngx_event_t *ev, char *buf, size_t size)
|
int ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
ngx_connection_t *c;
|
|
||||||
|
|
||||||
c = (ngx_connection_t *) ev->data;
|
if (c->read->timedout) {
|
||||||
|
|
||||||
if (ev->timedout) {
|
|
||||||
ngx_set_socket_errno(NGX_ETIMEDOUT);
|
ngx_set_socket_errno(NGX_ETIMEDOUT);
|
||||||
ngx_log_error(NGX_LOG_ERR, ev->log, NGX_ETIMEDOUT, "recv() failed");
|
ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "recv() failed");
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (HAVE_KQUEUE)
|
#if (HAVE_KQUEUE)
|
||||||
ngx_log_debug(ev->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _
|
ngx_log_debug(c->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _
|
||||||
ev->eof _ ev->available _ ev->error);
|
c->read->eof _ c->read->available _ c->read->error);
|
||||||
#if !(USE_KQUEUE)
|
#if !(USE_KQUEUE)
|
||||||
if (ngx_event_type == NGX_KQUEUE_EVENT)
|
if (ngx_event_type == NGX_KQUEUE_EVENT)
|
||||||
#endif
|
#endif
|
||||||
if (ev->eof && ev->available == 0) {
|
if (c->read->eof && c->read->available == 0) {
|
||||||
if (ev->error) {
|
if (c->read->error) {
|
||||||
ngx_log_error(NGX_LOG_ERR, ev->log, ev->error, "recv() failed");
|
ngx_log_error(NGX_LOG_ERR, c->log, c->read->error,
|
||||||
|
"recv() failed");
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,11 +40,11 @@ int ngx_event_recv_core(ngx_event_t *ev, char *buf, size_t size)
|
|||||||
err = ngx_socket_errno;
|
err = ngx_socket_errno;
|
||||||
|
|
||||||
if (err == NGX_EAGAIN) {
|
if (err == NGX_EAGAIN) {
|
||||||
ngx_log_error(NGX_LOG_INFO, ev->log, err, "recv() returns EAGAIN");
|
ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returns EAGAIN");
|
||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_ERR, ev->log, err, "recv() failed");
|
ngx_log_error(NGX_LOG_ERR, c->log, err, "recv() failed");
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +52,7 @@ int ngx_event_recv_core(ngx_event_t *ev, char *buf, size_t size)
|
|||||||
#if !(USE_KQUEUE)
|
#if !(USE_KQUEUE)
|
||||||
if (ngx_event_type == NGX_KQUEUE_EVENT)
|
if (ngx_event_type == NGX_KQUEUE_EVENT)
|
||||||
#endif
|
#endif
|
||||||
ev->available -= n;
|
c->read->available -= n;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -17,6 +17,7 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
|
|||||||
{
|
{
|
||||||
ngx_listen_t *ls;
|
ngx_listen_t *ls;
|
||||||
|
|
||||||
|
ngx_http_server.header_timeout = 20000;
|
||||||
ngx_http_server.buff_size = 1024;
|
ngx_http_server.buff_size = 1024;
|
||||||
#if (WIN32)
|
#if (WIN32)
|
||||||
ngx_http_server.doc_root = "html";
|
ngx_http_server.doc_root = "html";
|
||||||
|
@ -4,15 +4,11 @@
|
|||||||
|
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
#include <ngx_types.h>
|
#include <ngx_types.h>
|
||||||
|
#include <ngx_hunk.h>
|
||||||
#include <ngx_file.h>
|
#include <ngx_file.h>
|
||||||
#include <ngx_connection.h>
|
#include <ngx_connection.h>
|
||||||
|
|
||||||
|
|
||||||
#define NGX_SYS_ERROR -1
|
|
||||||
#define NGX_HTTP_INVALID_METHOD -2
|
|
||||||
#define NGX_HTTP_INVALID_REQUEST -3
|
|
||||||
#define NGX_HTTP_INVALID_HEADER -4
|
|
||||||
|
|
||||||
#define NGX_HTTP_GET 1
|
#define NGX_HTTP_GET 1
|
||||||
#define NGX_HTTP_HEAD 2
|
#define NGX_HTTP_HEAD 2
|
||||||
#define NGX_HTTP_POST 3
|
#define NGX_HTTP_POST 3
|
||||||
@ -20,10 +16,17 @@
|
|||||||
#define NGX_HTTP_CONN_CLOSE 0
|
#define NGX_HTTP_CONN_CLOSE 0
|
||||||
#define NGX_HTTP_CONN_KEEP_ALIVE 1
|
#define NGX_HTTP_CONN_KEEP_ALIVE 1
|
||||||
|
|
||||||
#define NGX_OK 0
|
|
||||||
|
#define NGX_HTTP_HEADER_DONE 1
|
||||||
|
#define NGX_HTTP_INVALID_METHOD 10
|
||||||
|
#define NGX_HTTP_INVALID_REQUEST 11
|
||||||
|
#define NGX_HTTP_INVALID_HEAD 12
|
||||||
|
#define NGX_HTTP_INVALID_HEADER 13
|
||||||
|
|
||||||
|
|
||||||
#define NGX_HTTP_OK 200
|
#define NGX_HTTP_OK 200
|
||||||
#define NGX_HTTP_MOVED_PERMANENTLY 302
|
#define NGX_HTTP_MOVED_PERMANENTLY 302
|
||||||
|
#define NGX_HTTP_BAD_REQUEST 400
|
||||||
#define NGX_HTTP_NOT_FOUND 404
|
#define NGX_HTTP_NOT_FOUND 404
|
||||||
#define NGX_HTTP_INTERNAL_SERVER_ERROR 503
|
#define NGX_HTTP_INTERNAL_SERVER_ERROR 503
|
||||||
|
|
||||||
@ -40,9 +43,11 @@ typedef struct {
|
|||||||
#define ngx_get_module_ctx(r, module) (module)->ctx
|
#define ngx_get_module_ctx(r, module) (module)->ctx
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *doc_root;
|
char *doc_root;
|
||||||
size_t doc_root_len;
|
size_t doc_root_len;
|
||||||
size_t buff_size;
|
size_t buff_size;
|
||||||
|
|
||||||
|
unsigned int header_timeout;
|
||||||
} ngx_http_server_t;
|
} ngx_http_server_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -72,6 +77,12 @@ struct ngx_http_request_s {
|
|||||||
char *location;
|
char *location;
|
||||||
ngx_fd_t fd;
|
ngx_fd_t fd;
|
||||||
|
|
||||||
|
ngx_pool_t *pool;
|
||||||
|
ngx_hunk_t *header_in;
|
||||||
|
|
||||||
|
/*
|
||||||
|
ngx_http_headers_in_t *headers_in;
|
||||||
|
*/
|
||||||
ngx_http_headers_out_t *headers_out;
|
ngx_http_headers_out_t *headers_out;
|
||||||
|
|
||||||
int filename_len;
|
int filename_len;
|
||||||
@ -90,11 +101,11 @@ struct ngx_http_request_s {
|
|||||||
|
|
||||||
ngx_connection_t *connection;
|
ngx_connection_t *connection;
|
||||||
ngx_http_server_t *server;
|
ngx_http_server_t *server;
|
||||||
ngx_buff_t *buff;
|
|
||||||
ngx_pool_t *pool;
|
|
||||||
|
|
||||||
int filter;
|
int filter;
|
||||||
|
|
||||||
|
unsigned header_timeout:1;
|
||||||
|
|
||||||
unsigned header_only:1;
|
unsigned header_only:1;
|
||||||
unsigned unusual_uri:1;
|
unsigned unusual_uri:1;
|
||||||
unsigned complex_uri:1;
|
unsigned complex_uri:1;
|
||||||
|
@ -15,12 +15,12 @@ int ngx_http_init_connection(ngx_connection_t *c);
|
|||||||
static int ngx_http_init_request(ngx_event_t *ev);
|
static int ngx_http_init_request(ngx_event_t *ev);
|
||||||
static int ngx_http_process_request(ngx_event_t *ev);
|
static int ngx_http_process_request(ngx_event_t *ev);
|
||||||
|
|
||||||
static int ngx_process_http_request_line(ngx_http_request_t *r);
|
static int ngx_http_process_request_line(ngx_http_request_t *r);
|
||||||
static int ngx_process_http_request_header(ngx_http_request_t *r);
|
static int ngx_http_process_request_header(ngx_http_request_t *r);
|
||||||
|
|
||||||
static int ngx_process_http_request(ngx_http_request_t *r);
|
static int ngx_http_process_http_request(ngx_http_request_t *r);
|
||||||
|
|
||||||
static int ngx_http_close_request(ngx_event_t *ev);
|
static int ngx_http_close_request(ngx_http_request_t *r);
|
||||||
static size_t ngx_http_log_error(void *data, char *buf, size_t len);
|
static size_t ngx_http_log_error(void *data, char *buf, size_t len);
|
||||||
|
|
||||||
|
|
||||||
@ -28,6 +28,13 @@ static size_t ngx_http_log_error(void *data, char *buf, size_t len);
|
|||||||
static int ngx_http_writer(ngx_event_t *ev);
|
static int ngx_http_writer(ngx_event_t *ev);
|
||||||
|
|
||||||
|
|
||||||
|
static char *header_errors[] = {
|
||||||
|
"client %s sent invalid method",
|
||||||
|
"client %s sent invalid request",
|
||||||
|
"client %s sent HEAD method in HTTP/0.9 request"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ngx_http_init_connection(ngx_connection_t *c)
|
int ngx_http_init_connection(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
@ -57,13 +64,12 @@ int ngx_http_init_connection(ngx_connection_t *c)
|
|||||||
c->log->data = ctx;
|
c->log->data = ctx;
|
||||||
c->log->handler = ngx_http_log_error;
|
c->log->handler = ngx_http_log_error;
|
||||||
|
|
||||||
ngx_add_timer(ev, c->post_accept_timeout);
|
|
||||||
|
|
||||||
#if (HAVE_DEFERRED_ACCEPT)
|
#if (HAVE_DEFERRED_ACCEPT)
|
||||||
if (ev->ready)
|
if (ev->ready) {
|
||||||
return ngx_http_init_request(ev);
|
return ngx_http_init_request(ev);
|
||||||
else
|
} else {
|
||||||
#endif
|
#endif
|
||||||
|
ngx_add_timer(ev, c->post_accept_timeout);
|
||||||
#if (USE_KQUEUE)
|
#if (USE_KQUEUE)
|
||||||
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
|
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
|
||||||
#else
|
#else
|
||||||
@ -76,9 +82,11 @@ int ngx_http_init_connection(ngx_connection_t *c)
|
|||||||
if (ngx_event_type == NGX_KQUEUE_EVENT)
|
if (ngx_event_type == NGX_KQUEUE_EVENT)
|
||||||
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
|
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
|
||||||
else
|
else
|
||||||
#else
|
|
||||||
return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT);
|
|
||||||
#endif
|
#endif
|
||||||
|
return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT);
|
||||||
|
#endif /* USE_KQUEUE */
|
||||||
|
#if (HAVE_DEFERRED_ACCEPT)
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,21 +107,16 @@ int ngx_http_init_request(ngx_event_t *ev)
|
|||||||
r->connection = c;
|
r->connection = c;
|
||||||
r->server = srv;
|
r->server = srv;
|
||||||
|
|
||||||
ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), NGX_ERROR);
|
/* TODO: request's pool size */
|
||||||
|
ngx_test_null(r->pool, ngx_create_pool(16384, ev->log),
|
||||||
|
ngx_http_close_request(r));
|
||||||
|
|
||||||
/* TODO: buff -> hunk */
|
ngx_test_null(r->header_in,
|
||||||
ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), NGX_ERROR);
|
ngx_create_temp_hunk(r->pool, srv->buff_size, 0, 0),
|
||||||
ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size),
|
ngx_http_close_request(r));
|
||||||
NGX_ERROR);
|
|
||||||
|
|
||||||
r->buff->pos = r->buff->last = r->buff->buff;
|
|
||||||
r->buff->end = r->buff->buff + srv->buff_size;
|
|
||||||
|
|
||||||
r->state_handler = ngx_process_http_request_line;
|
|
||||||
|
|
||||||
ev->event_handler = ngx_http_process_request;
|
ev->event_handler = ngx_http_process_request;
|
||||||
ev->close_handler = ngx_http_close_request;
|
r->state_handler = ngx_http_process_request_line;
|
||||||
c->write->close_handler = ngx_http_close_request;
|
|
||||||
|
|
||||||
return ngx_http_process_request(ev);
|
return ngx_http_process_request(ev);
|
||||||
}
|
}
|
||||||
@ -121,7 +124,7 @@ int ngx_http_init_request(ngx_event_t *ev)
|
|||||||
|
|
||||||
int ngx_http_process_request(ngx_event_t *ev)
|
int ngx_http_process_request(ngx_event_t *ev)
|
||||||
{
|
{
|
||||||
int n;
|
int n, rc;
|
||||||
ngx_connection_t *c ;
|
ngx_connection_t *c ;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
|
|
||||||
@ -130,79 +133,128 @@ int ngx_http_process_request(ngx_event_t *ev)
|
|||||||
|
|
||||||
ngx_log_debug(ev->log, "http process request");
|
ngx_log_debug(ev->log, "http process request");
|
||||||
|
|
||||||
n = ngx_event_recv(ev, r->buff->last, r->buff->end - r->buff->last);
|
n = ngx_event_recv(c, r->header_in->last.mem,
|
||||||
|
r->header_in->end - r->header_in->last.mem);
|
||||||
|
|
||||||
if (n == NGX_AGAIN)
|
if (n == NGX_AGAIN) {
|
||||||
|
if (!r->header_timeout) {
|
||||||
|
r->header_timeout = 1;
|
||||||
|
ngx_del_timer(ev);
|
||||||
|
ngx_add_timer(ev, r->server->header_timeout);
|
||||||
|
}
|
||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
|
|
||||||
if (n == NGX_ERROR) {
|
|
||||||
/* close request */
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n == NGX_ERROR)
|
||||||
|
return ngx_http_close_request(r);
|
||||||
|
|
||||||
ngx_log_debug(ev->log, "http read %d" _ n);
|
ngx_log_debug(ev->log, "http read %d" _ n);
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
if (ev->unexpected_eof) {
|
/* STUB: c-> */
|
||||||
ngx_log_error(NGX_LOG_INFO, ev->log, 0, "connection is closed");
|
if (ev->unexpected_eof)
|
||||||
/* close request */
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
return NGX_ERROR;
|
"client prematurely closed connection");
|
||||||
|
|
||||||
|
return ngx_http_close_request(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->header_in->last.mem += n;
|
||||||
|
|
||||||
|
/* state_handlers are called in following order:
|
||||||
|
ngx_http_process_request_line(r)
|
||||||
|
ngx_http_process_request_header(r) */
|
||||||
|
|
||||||
|
do {
|
||||||
|
rc = (r->state_handler)(r);
|
||||||
|
|
||||||
|
if (rc == NGX_ERROR)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* rc == NGX_OK || rc == NGX_AGAIN */
|
||||||
|
|
||||||
|
} while (r->header_in->pos.mem < r->header_in->last.mem);
|
||||||
|
|
||||||
|
if (!r->header_timeout) {
|
||||||
|
r->header_timeout = 1;
|
||||||
|
ngx_del_timer(ev);
|
||||||
|
ngx_add_timer(ev, r->server->header_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ngx_http_process_request_line(ngx_http_request_t *r)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
ngx_http_log_ctx_t *ctx;
|
||||||
|
|
||||||
|
rc = ngx_read_http_request_line(r);
|
||||||
|
|
||||||
|
if (rc == NGX_OK) {
|
||||||
|
ngx_test_null(r->uri,
|
||||||
|
ngx_palloc(r->pool, r->uri_end - r->uri_start + 1),
|
||||||
|
ngx_http_close_request(r));
|
||||||
|
ngx_cpystrn(r->uri, r->uri_start, r->uri_end - r->uri_start + 1);
|
||||||
|
|
||||||
|
ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _
|
||||||
|
r->method _ r->http_version _ r->uri);
|
||||||
|
|
||||||
|
if (r->http_version == 9) {
|
||||||
|
/* set lock event */
|
||||||
|
return ngx_http_process_http_request(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ngx_http_close_request(ev);
|
r->state_handler = ngx_http_process_request_header;
|
||||||
}
|
|
||||||
|
|
||||||
if (!ev->read_discarded) {
|
|
||||||
r->buff->last += n;
|
|
||||||
|
|
||||||
/* state_handlers are called in following order:
|
|
||||||
ngx_process_http_request_line()
|
|
||||||
ngx_process_http_request_header() */
|
|
||||||
|
|
||||||
do {
|
|
||||||
if ((r->state_handler)(r) < 0)
|
|
||||||
return -1;
|
|
||||||
} while (r->buff->pos < r->buff->last);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_del_event(ev, NGX_TIMER_EVENT) == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ngx_add_event(ev, NGX_TIMER_EVENT, ev->timer) == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ngx_process_http_request_line(ngx_http_request_t *r)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if ((n = ngx_read_http_request_line(r)) == 1) {
|
|
||||||
*r->uri_end = '\0';
|
|
||||||
ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _
|
|
||||||
r->method _ r->http_version _ r->uri_start);
|
|
||||||
r->state_handler = ngx_process_http_request_header;
|
|
||||||
r->connection->read->action = "reading client request headers";
|
r->connection->read->action = "reading client request headers";
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
r->connection->log->handler = NULL;
|
||||||
|
ctx = r->connection->log->data;
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
header_errors[rc - NGX_HTTP_INVALID_METHOD], ctx->client);
|
||||||
|
|
||||||
|
r->connection->log->handler = ngx_http_log_error;
|
||||||
|
|
||||||
|
/* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST) */
|
||||||
|
return ngx_http_close_request(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ngx_process_http_request_header(ngx_http_request_t *r)
|
static int ngx_http_process_request_header(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
int n;
|
int rc;
|
||||||
|
ngx_http_log_ctx_t *ctx;
|
||||||
|
|
||||||
while ((n = ngx_read_http_header_line(r)) == 1) {
|
for ( ;; ) {
|
||||||
*r->header_name_end = '\0';
|
rc = ngx_read_http_header_line(r);
|
||||||
*r->header_end = '\0';
|
|
||||||
ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
|
if (rc == NGX_OK) {
|
||||||
r->header_name_start _ r->header_start);
|
*r->header_name_end = '\0';
|
||||||
|
*r->header_end = '\0';
|
||||||
|
ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
|
||||||
|
r->header_name_start _ r->header_start);
|
||||||
|
|
||||||
|
} else if (rc == NGX_AGAIN) {
|
||||||
|
return NGX_AGAIN;
|
||||||
|
|
||||||
|
} else if (rc == NGX_HTTP_HEADER_DONE) {
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else if (rc == NGX_HTTP_INVALID_HEADER) {
|
||||||
|
r->connection->log->handler = NULL;
|
||||||
|
ctx = r->connection->log->data;
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client %s sent invalid header", ctx->client);
|
||||||
|
r->connection->log->handler = ngx_http_log_error;
|
||||||
|
|
||||||
|
/* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST) */
|
||||||
|
return ngx_http_close_request(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n != 2)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
r->state_handler = NULL;
|
r->state_handler = NULL;
|
||||||
r->connection->read->action = "reading client request body";
|
r->connection->read->action = "reading client request body";
|
||||||
|
|
||||||
@ -210,7 +262,9 @@ static int ngx_process_http_request_header(ngx_http_request_t *r)
|
|||||||
r->connection->read->unexpected_eof = 0;
|
r->connection->read->unexpected_eof = 0;
|
||||||
ngx_log_debug(r->connection->log, "HTTP header done");
|
ngx_log_debug(r->connection->log, "HTTP header done");
|
||||||
|
|
||||||
return ngx_process_http_request(r);
|
ngx_del_timer(r->connection->read);
|
||||||
|
|
||||||
|
return ngx_http_process_http_request(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -221,7 +275,7 @@ static int ngx_http_lock_read(ngx_event_t *ev)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int ngx_process_http_request(ngx_http_request_t *r)
|
static int ngx_http_process_http_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
int err, rc;
|
int err, rc;
|
||||||
char *name, *loc, *file;
|
char *name, *loc, *file;
|
||||||
@ -489,16 +543,16 @@ static int ngx_process_http_request(ngx_http_request_t *r)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int ngx_http_close_request(ngx_event_t *ev)
|
static int ngx_http_close_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ngx_connection_t *c = (ngx_connection_t *) ev->data;
|
ngx_destroy_pool(r->pool);
|
||||||
|
|
||||||
ngx_log_debug(ev->log, "http close");
|
ngx_log_debug(r->connection->log, "http close");
|
||||||
|
|
||||||
ngx_del_event(c->read, NGX_TIMER_EVENT);
|
ngx_del_event(r->connection->read, NGX_TIMER_EVENT);
|
||||||
ngx_del_event(c->write, NGX_TIMER_EVENT);
|
ngx_del_event(r->connection->write, NGX_TIMER_EVENT);
|
||||||
|
|
||||||
return ngx_event_close_connection(ev);
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ int ngx_http_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
|||||||
|
|
||||||
ngx_test_null(ctx->hunk,
|
ngx_test_null(ctx->hunk,
|
||||||
ngx_create_temp_hunk(r->pool, size,
|
ngx_create_temp_hunk(r->pool, size,
|
||||||
50, 50),
|
50, 50),
|
||||||
NGX_ERROR);
|
NGX_ERROR);
|
||||||
|
|
||||||
rc = ngx_http_filter_copy_hunk(ctx->hunk,
|
rc = ngx_http_filter_copy_hunk(ctx->hunk,
|
||||||
|
@ -1,47 +1,47 @@
|
|||||||
|
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
|
#include <ngx_core.h>
|
||||||
#include <ngx_http.h>
|
#include <ngx_http.h>
|
||||||
|
|
||||||
int ngx_read_http_request_line(ngx_http_request_t *r)
|
int ngx_read_http_request_line(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
char *buff = r->buff->buff;
|
char *p = r->header_in->pos.mem;
|
||||||
char *p = r->buff->pos;
|
|
||||||
enum {
|
enum {
|
||||||
rl_start = 0,
|
sw_start = 0,
|
||||||
rl_space_after_method,
|
sw_space_after_method,
|
||||||
rl_spaces_before_uri,
|
sw_spaces_before_uri,
|
||||||
rl_after_slash_in_uri,
|
sw_after_slash_in_uri,
|
||||||
rl_check_uri,
|
sw_check_uri,
|
||||||
rl_uri,
|
sw_uri,
|
||||||
rl_http_09,
|
sw_http_09,
|
||||||
rl_http_version,
|
sw_http_version,
|
||||||
rl_first_major_digit,
|
sw_first_major_digit,
|
||||||
rl_major_digit,
|
sw_major_digit,
|
||||||
rl_first_minor_digit,
|
sw_first_minor_digit,
|
||||||
rl_minor_digit,
|
sw_minor_digit,
|
||||||
rl_almost_done,
|
sw_almost_done,
|
||||||
rl_done
|
sw_done
|
||||||
} state = r->state;
|
} state = r->state;
|
||||||
|
|
||||||
while (p < r->buff->last && state < rl_done) {
|
while (p < r->header_in->last.mem && state < sw_done) {
|
||||||
ch = *p++;
|
ch = *p++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
||||||
state, p, r->buff->last, ch, p);
|
state, p, r->header_in->last, ch, p);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* GCC complie it as jump table */
|
/* GCC compiles switch as jump table */
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
||||||
/* HTTP methods: GET, HEAD, POST */
|
/* HTTP methods: GET, HEAD, POST */
|
||||||
case rl_start:
|
case sw_start:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'G':
|
case 'G':
|
||||||
if (p + 1 >= r->buff->last)
|
if (p + 1 >= r->header_in->last.mem)
|
||||||
return 0;
|
return NGX_AGAIN;
|
||||||
|
|
||||||
if (*p != 'E' || *(p + 1) != 'T')
|
if (*p != 'E' || *(p + 1) != 'T')
|
||||||
return NGX_HTTP_INVALID_METHOD;
|
return NGX_HTTP_INVALID_METHOD;
|
||||||
@ -51,8 +51,8 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'H':
|
case 'H':
|
||||||
if (p + 2 >= r->buff->last)
|
if (p + 2 >= r->header_in->last.mem)
|
||||||
return 0;
|
return NGX_AGAIN;
|
||||||
|
|
||||||
if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D')
|
if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D')
|
||||||
return NGX_HTTP_INVALID_METHOD;
|
return NGX_HTTP_INVALID_METHOD;
|
||||||
@ -62,8 +62,8 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
if (p + 2 >= r->buff->last)
|
if (p + 2 >= r->header_in->last.mem)
|
||||||
return 0;
|
return NGX_AGAIN;
|
||||||
|
|
||||||
if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T')
|
if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T')
|
||||||
return NGX_HTTP_INVALID_METHOD;
|
return NGX_HTTP_INVALID_METHOD;
|
||||||
@ -76,14 +76,14 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
return NGX_HTTP_INVALID_METHOD;
|
return NGX_HTTP_INVALID_METHOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = rl_space_after_method;
|
state = sw_space_after_method;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* single space after method */
|
/* single space after method */
|
||||||
case rl_space_after_method:
|
case sw_space_after_method:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
state = rl_spaces_before_uri;
|
state = sw_spaces_before_uri;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NGX_HTTP_INVALID_METHOD;
|
return NGX_HTTP_INVALID_METHOD;
|
||||||
@ -91,123 +91,123 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* space* before URI */
|
/* space* before URI */
|
||||||
case rl_spaces_before_uri:
|
case sw_spaces_before_uri:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '/':
|
case '/':
|
||||||
r->uri_start = p - 1;
|
r->uri_start = p - 1;
|
||||||
state = rl_after_slash_in_uri;
|
state = sw_after_slash_in_uri;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r->unusual_uri = 1;
|
r->unusual_uri = 1;
|
||||||
r->uri_start = p - 1;
|
r->uri_start = p - 1;
|
||||||
state = rl_uri;
|
state = sw_uri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* check dot after slash */
|
/* check dot after slash */
|
||||||
case rl_after_slash_in_uri:
|
case sw_after_slash_in_uri:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case CR:
|
case CR:
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
state = rl_http_09;
|
state = sw_http_09;
|
||||||
break;
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
r->complex_uri = 1;
|
r->complex_uri = 1;
|
||||||
state = rl_uri;
|
state = sw_uri;
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
r->complex_uri = 1;
|
r->complex_uri = 1;
|
||||||
state = rl_uri;
|
state = sw_uri;
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
r->args_start = p;
|
r->args_start = p;
|
||||||
state = rl_uri;
|
state = sw_uri;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state = rl_check_uri;
|
state = sw_check_uri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* check slash in URI */
|
/* check slash in URI */
|
||||||
case rl_check_uri:
|
case sw_check_uri:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case CR:
|
case CR:
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
state = rl_http_09;
|
state = sw_http_09;
|
||||||
break;
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
r->uri_ext = p;
|
r->uri_ext = p;
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
r->uri_ext = NULL;
|
r->uri_ext = NULL;
|
||||||
state = rl_after_slash_in_uri;
|
state = sw_after_slash_in_uri;
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
r->args_start = p;
|
r->args_start = p;
|
||||||
state = rl_uri;
|
state = sw_uri;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* URI */
|
/* URI */
|
||||||
case rl_uri:
|
case sw_uri:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case CR:
|
case CR:
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
r->uri_end = p - 1;
|
r->uri_end = p - 1;
|
||||||
state = rl_http_09;
|
state = sw_http_09;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* space+ after URI */
|
/* space+ after URI */
|
||||||
case rl_http_09:
|
case sw_http_09:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
break;
|
break;
|
||||||
case CR:
|
case CR:
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
r->http_minor = 9;
|
r->http_minor = 9;
|
||||||
state = rl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
state = rl_http_version;
|
state = sw_http_version;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NGX_HTTP_INVALID_REQUEST;
|
return NGX_HTTP_INVALID_REQUEST;
|
||||||
@ -215,33 +215,33 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* TTP/ */
|
/* TTP/ */
|
||||||
case rl_http_version:
|
case sw_http_version:
|
||||||
if (p + 2 >= r->buff->last) {
|
if (p + 2 >= r->header_in->last.mem) {
|
||||||
r->state = rl_http_version;
|
r->state = sw_http_version;
|
||||||
r->buff->pos = p - 1;
|
r->header_in->pos.mem = p - 1;
|
||||||
return 0;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/')
|
if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/')
|
||||||
return NGX_HTTP_INVALID_REQUEST;
|
return NGX_HTTP_INVALID_REQUEST;
|
||||||
|
|
||||||
p += 3;
|
p += 3;
|
||||||
state = rl_first_major_digit;
|
state = sw_first_major_digit;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* first digit of major HTTP version */
|
/* first digit of major HTTP version */
|
||||||
case rl_first_major_digit:
|
case sw_first_major_digit:
|
||||||
if (ch < '1' || ch > '9')
|
if (ch < '1' || ch > '9')
|
||||||
return NGX_HTTP_INVALID_REQUEST;
|
return NGX_HTTP_INVALID_REQUEST;
|
||||||
|
|
||||||
r->http_major = ch - '0';
|
r->http_major = ch - '0';
|
||||||
state = rl_major_digit;
|
state = sw_major_digit;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* major HTTP version or dot */
|
/* major HTTP version or dot */
|
||||||
case rl_major_digit:
|
case sw_major_digit:
|
||||||
if (ch == '.') {
|
if (ch == '.') {
|
||||||
state = rl_first_minor_digit;
|
state = sw_first_minor_digit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,24 +252,24 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* first digit of minor HTTP version */
|
/* first digit of minor HTTP version */
|
||||||
case rl_first_minor_digit:
|
case sw_first_minor_digit:
|
||||||
if (ch < '0' || ch > '9')
|
if (ch < '0' || ch > '9')
|
||||||
return NGX_HTTP_INVALID_REQUEST;
|
return NGX_HTTP_INVALID_REQUEST;
|
||||||
|
|
||||||
r->http_minor = ch - '0';
|
r->http_minor = ch - '0';
|
||||||
|
|
||||||
state = rl_minor_digit;
|
state = sw_minor_digit;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* minor HTTP version or end of request line */
|
/* minor HTTP version or end of request line */
|
||||||
case rl_minor_digit:
|
case sw_minor_digit:
|
||||||
if (ch == CR) {
|
if (ch == CR) {
|
||||||
state = rl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == LF) {
|
if (ch == LF) {
|
||||||
state = rl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,70 +280,72 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* end of request line */
|
/* end of request line */
|
||||||
case rl_almost_done:
|
case sw_almost_done:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case LF:
|
case LF:
|
||||||
state = rl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NGX_HTTP_INVALID_METHOD;
|
return NGX_HTTP_INVALID_REQUEST;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r->buff->pos = p;
|
r->header_in->pos.mem = p;
|
||||||
|
|
||||||
if (state == rl_done) {
|
if (state == sw_done) {
|
||||||
r->http_version = r->http_major * 1000 + r->http_minor;
|
r->http_version = r->http_major * 1000 + r->http_minor;
|
||||||
r->state = rl_start;
|
r->state = sw_start;
|
||||||
return 1;
|
if (r->http_version == 9 && r->method == NGX_HTTP_HEAD)
|
||||||
|
return NGX_HTTP_INVALID_HEAD;
|
||||||
|
else
|
||||||
|
return NGX_OK;
|
||||||
} else {
|
} else {
|
||||||
r->state = state;
|
r->state = state;
|
||||||
return 0;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ngx_read_http_header_line(ngx_http_request_t *r)
|
int ngx_read_http_header_line(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
char c, ch;
|
char c, ch;
|
||||||
char *buff = r->buff->buff;
|
char *p = r->header_in->pos.mem;
|
||||||
char *p = r->buff->pos;
|
|
||||||
enum {
|
enum {
|
||||||
hl_start = 0,
|
sw_start = 0,
|
||||||
hl_name,
|
sw_name,
|
||||||
hl_space_before_value,
|
sw_space_before_value,
|
||||||
hl_value,
|
sw_value,
|
||||||
hl_space_after_value,
|
sw_space_after_value,
|
||||||
hl_almost_done,
|
sw_almost_done,
|
||||||
header_almost_done,
|
sw_header_almost_done,
|
||||||
hl_done,
|
sw_done,
|
||||||
header_done
|
sw_header_done
|
||||||
} state = r->state;
|
} state = r->state;
|
||||||
|
|
||||||
while (p < r->buff->last && state < hl_done) {
|
while (p < r->header_in->last.mem && state < sw_done) {
|
||||||
ch = *p++;
|
ch = *p++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
||||||
state, p, r->buff->last, ch, p);
|
state, p, r->header_in->last.mem, ch, p);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
||||||
/* first char */
|
/* first char */
|
||||||
case hl_start:
|
case sw_start:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case CR:
|
case CR:
|
||||||
r->header_end = p - 1;
|
r->header_end = p - 1;
|
||||||
state = header_almost_done;
|
state = sw_header_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
r->header_end = p - 1;
|
r->header_end = p - 1;
|
||||||
state = header_done;
|
state = sw_header_done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state = hl_name;
|
state = sw_name;
|
||||||
r->header_name_start = p - 1;
|
r->header_name_start = p - 1;
|
||||||
|
|
||||||
c = ch | 0x20;
|
c = ch | 0x20;
|
||||||
@ -362,14 +364,14 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* header name */
|
/* header name */
|
||||||
case hl_name:
|
case sw_name:
|
||||||
c = ch | 0x20;
|
c = ch | 0x20;
|
||||||
if (c >= 'a' && c <= 'z')
|
if (c >= 'a' && c <= 'z')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (ch == ':') {
|
if (ch == ':') {
|
||||||
r->header_name_end = p - 1;
|
r->header_name_end = p - 1;
|
||||||
state = hl_space_before_value;
|
state = sw_space_before_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,65 +384,65 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
return NGX_HTTP_INVALID_HEADER;
|
return NGX_HTTP_INVALID_HEADER;
|
||||||
|
|
||||||
/* space* before header value */
|
/* space* before header value */
|
||||||
case hl_space_before_value:
|
case sw_space_before_value:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
break;
|
break;
|
||||||
case CR:
|
case CR:
|
||||||
r->header_start = r->header_end = p - 1;
|
r->header_start = r->header_end = p - 1;
|
||||||
state = hl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
r->header_start = r->header_end = p - 1;
|
r->header_start = r->header_end = p - 1;
|
||||||
state = hl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
r->header_start = p - 1;
|
r->header_start = p - 1;
|
||||||
state = hl_value;
|
state = sw_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* header value */
|
/* header value */
|
||||||
case hl_value:
|
case sw_value:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
r->header_end = p - 1;
|
r->header_end = p - 1;
|
||||||
state = hl_space_after_value;
|
state = sw_space_after_value;
|
||||||
break;
|
break;
|
||||||
case CR:
|
case CR:
|
||||||
r->header_end = p - 1;
|
r->header_end = p - 1;
|
||||||
state = hl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
r->header_end = p - 1;
|
r->header_end = p - 1;
|
||||||
state = hl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* space* before end of header line */
|
/* space* before end of header line */
|
||||||
case hl_space_after_value:
|
case sw_space_after_value:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
break;
|
break;
|
||||||
case CR:
|
case CR:
|
||||||
state = hl_almost_done;
|
state = sw_almost_done;
|
||||||
break;
|
break;
|
||||||
case LF:
|
case LF:
|
||||||
state = hl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state = hl_value;
|
state = sw_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* end of header line */
|
/* end of header line */
|
||||||
case hl_almost_done:
|
case sw_almost_done:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case LF:
|
case LF:
|
||||||
state = hl_done;
|
state = sw_done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NGX_HTTP_INVALID_HEADER;
|
return NGX_HTTP_INVALID_HEADER;
|
||||||
@ -448,10 +450,10 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* end of header */
|
/* end of header */
|
||||||
case header_almost_done:
|
case sw_header_almost_done:
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case LF:
|
case LF:
|
||||||
state = header_done;
|
state = sw_header_done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NGX_HTTP_INVALID_HEADER;
|
return NGX_HTTP_INVALID_HEADER;
|
||||||
@ -460,16 +462,16 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r->buff->pos = p;
|
r->header_in->pos.mem = p;
|
||||||
|
|
||||||
if (state == hl_done) {
|
if (state == sw_done) {
|
||||||
r->state = hl_start;
|
r->state = sw_start;
|
||||||
return 1;
|
return NGX_OK;
|
||||||
} else if (state == header_done) {
|
} else if (state == sw_header_done) {
|
||||||
r->state = hl_start;
|
r->state = sw_start;
|
||||||
return 2;
|
return NGX_HTTP_HEADER_DONE;
|
||||||
} else {
|
} else {
|
||||||
r->state = state;
|
r->state = state;
|
||||||
return 0;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user