nginx-0.0.1-2002-08-29-20:59:54 import
diff --git a/src/core/ngx_alloc.c b/src/core/ngx_alloc.c
index 1fd058b..3c6b4de 100644
--- a/src/core/ngx_alloc.c
+++ b/src/core/ngx_alloc.c
@@ -14,6 +14,9 @@
if (p == NULL)
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"malloc() %d bytes failed", size);
+
+ ngx_log_debug(log, "malloc: %x" _ p);
+
return p;
}
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 2f6d128..cdd72bb 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -34,7 +34,7 @@
char *addr_text;
size_t addr_textlen;
- time_t post_accept_timeout;
+ unsigned int post_accept_timeout;
};
diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h
index 5e2a1d4..3703db4 100644
--- a/src/core/ngx_hunk.h
+++ b/src/core/ngx_hunk.h
@@ -57,6 +57,9 @@
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) \
do { \
ngx_test_null(chain, ngx_create_chain_entry(pool), error); \
@@ -66,6 +69,7 @@
+
ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after);
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index f7dee18..1ea3d22 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -8,6 +8,7 @@
*/
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_log.h>
#include <ngx_connection.h>
@@ -19,7 +20,6 @@
#endif
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;
@@ -145,7 +145,7 @@
}
ngx_log_debug(log, "ngx_kqueue_process_events: "
- "timer: %d, delta: %d" _ timer _ delta);
+ "timer: %d, delta: %d" _ timer _ delta);
if (timer) {
if (delta >= timer) {
@@ -158,7 +158,7 @@
ngx_del_timer(ev);
#if 1
ev->timedout = 1;
- if (ev->event_handler(ev) == -1)
+ if (ev->event_handler(ev) == NGX_ERROR)
ev->close_handler(ev);
#else
if (ev->timer_handler(ev) == -1)
@@ -200,7 +200,7 @@
ev->error = event_list[i].fflags;
}
- if (ev->event_handler(ev) == -1)
+ if (ev->event_handler(ev) == NGX_ERROR)
ev->close_handler(ev);
break;
@@ -233,6 +233,7 @@
e->timer_prev = ev;
}
+#if 0
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
{
if (ev->timer_prev)
@@ -240,9 +241,10 @@
if (ev->timer_next) {
ev->timer_next->timer_prev = ev->timer_prev;
- ev->timer_prev = NULL;
+ ev->timer_next = NULL;
}
if (ev->timer_prev)
- ev->timer_next = NULL;
+ ev->timer_prev = NULL;
}
+#endif
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index bde14a1..9639a1b 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -24,7 +24,6 @@
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,
ngx_log_t *log);
@@ -338,6 +337,7 @@
e->timer_prev = ev;
}
+#if 0
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
{
if (ev->timer_prev)
@@ -345,9 +345,10 @@
if (ev->timer_next) {
ev->timer_next->timer_prev = ev->timer_prev;
- ev->timer_prev = NULL;
+ ev->timer_next = NULL;
}
if (ev->timer_prev)
- ev->timer_next = NULL;
+ ev->timer_prev = NULL;
}
+#endif
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index a5cdb11..0d02dfe 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -19,7 +19,7 @@
#if !(USE_KQUEUE)
-#if 1
+#if 0
ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT;
#else
ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index d2e6c1f..9e4bc02 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -133,6 +133,23 @@
#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_write_events;
extern ngx_connection_t *ngx_connections;
diff --git a/src/event/ngx_event_close.c b/src/event/ngx_event_close.c
index c956891..0e3fe20 100644
--- a/src/event/ngx_event_close.c
+++ b/src/event/ngx_event_close.c
@@ -1,5 +1,6 @@
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_connection.h>
#include <ngx_event_close.h>
@@ -8,22 +9,24 @@
int ngx_event_close_connection(ngx_event_t *ev)
{
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");
- if ((rc = ngx_close_socket(cn->fd)) == -1)
- ngx_log_error(NGX_LOG_ERR, ev->log, ngx_socket_errno,
+ ngx_destroy_pool(c->pool);
+
+ if ((rc = ngx_close_socket(c->fd)) == -1)
+ ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
"ngx_event_close: close failed");
- if (cn->read->next)
- ngx_del_event(cn->read, NGX_READ_EVENT);
+ if (c->read->next)
+ ngx_del_event(c->read, NGX_READ_EVENT);
- if (cn->write->next)
- ngx_del_event(cn->write, NGX_WRITE_EVENT);
+ if (c->write->next)
+ ngx_del_event(c->write, NGX_WRITE_EVENT);
- cn->fd = -1;
+ c->fd = -1;
return rc;
}
diff --git a/src/event/ngx_event_recv.c b/src/event/ngx_event_recv.c
index e286aca..4b01a4c 100644
--- a/src/event/ngx_event_recv.c
+++ b/src/event/ngx_event_recv.c
@@ -6,29 +6,27 @@
#include <ngx_recv.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;
ngx_err_t err;
- ngx_connection_t *c;
- c = (ngx_connection_t *) ev->data;
-
- if (ev->timedout) {
+ if (c->read->timedout) {
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;
}
#if (HAVE_KQUEUE)
- ngx_log_debug(ev->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _
- ev->eof _ ev->available _ ev->error);
+ ngx_log_debug(c->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _
+ c->read->eof _ c->read->available _ c->read->error);
#if !(USE_KQUEUE)
if (ngx_event_type == NGX_KQUEUE_EVENT)
#endif
- if (ev->eof && ev->available == 0) {
- if (ev->error) {
- ngx_log_error(NGX_LOG_ERR, ev->log, ev->error, "recv() failed");
+ if (c->read->eof && c->read->available == 0) {
+ if (c->read->error) {
+ ngx_log_error(NGX_LOG_ERR, c->log, c->read->error,
+ "recv() failed");
return NGX_ERROR;
}
@@ -42,11 +40,11 @@
err = ngx_socket_errno;
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;
}
- 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;
}
@@ -54,7 +52,7 @@
#if !(USE_KQUEUE)
if (ngx_event_type == NGX_KQUEUE_EVENT)
#endif
- ev->available -= n;
+ c->read->available -= n;
#endif
return n;
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 41d8d23..5410d31 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -17,6 +17,7 @@
{
ngx_listen_t *ls;
+ ngx_http_server.header_timeout = 20000;
ngx_http_server.buff_size = 1024;
#if (WIN32)
ngx_http_server.doc_root = "html";
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 33de2fd..fe89874 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -4,15 +4,11 @@
#include <ngx_config.h>
#include <ngx_types.h>
+#include <ngx_hunk.h>
#include <ngx_file.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_HEAD 2
#define NGX_HTTP_POST 3
@@ -20,10 +16,17 @@
#define NGX_HTTP_CONN_CLOSE 0
#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_MOVED_PERMANENTLY 302
+#define NGX_HTTP_BAD_REQUEST 400
#define NGX_HTTP_NOT_FOUND 404
#define NGX_HTTP_INTERNAL_SERVER_ERROR 503
@@ -40,9 +43,11 @@
#define ngx_get_module_ctx(r, module) (module)->ctx
typedef struct {
- char *doc_root;
- size_t doc_root_len;
- size_t buff_size;
+ char *doc_root;
+ size_t doc_root_len;
+ size_t buff_size;
+
+ unsigned int header_timeout;
} ngx_http_server_t;
typedef struct {
@@ -72,6 +77,12 @@
char *location;
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;
int filename_len;
@@ -90,11 +101,11 @@
ngx_connection_t *connection;
ngx_http_server_t *server;
- ngx_buff_t *buff;
- ngx_pool_t *pool;
int filter;
+ unsigned header_timeout:1;
+
unsigned header_only:1;
unsigned unusual_uri:1;
unsigned complex_uri:1;
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c
index 3500b08..63fc29a 100644
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -15,12 +15,12 @@
static int ngx_http_init_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_process_http_request_header(ngx_http_request_t *r);
+static int ngx_http_process_request_line(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);
@@ -28,6 +28,13 @@
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)
{
@@ -57,13 +64,12 @@
c->log->data = ctx;
c->log->handler = ngx_http_log_error;
- ngx_add_timer(ev, c->post_accept_timeout);
-
#if (HAVE_DEFERRED_ACCEPT)
- if (ev->ready)
+ if (ev->ready) {
return ngx_http_init_request(ev);
- else
+ } else {
#endif
+ ngx_add_timer(ev, c->post_accept_timeout);
#if (USE_KQUEUE)
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
#else
@@ -76,9 +82,11 @@
if (ngx_event_type == NGX_KQUEUE_EVENT)
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
else
-#else
- return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT);
#endif
+ return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT);
+#endif /* USE_KQUEUE */
+#if (HAVE_DEFERRED_ACCEPT)
+ }
#endif
}
@@ -99,21 +107,16 @@
r->connection = c;
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->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), NGX_ERROR);
- ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size),
- 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;
+ ngx_test_null(r->header_in,
+ ngx_create_temp_hunk(r->pool, srv->buff_size, 0, 0),
+ ngx_http_close_request(r));
ev->event_handler = ngx_http_process_request;
- ev->close_handler = ngx_http_close_request;
- c->write->close_handler = ngx_http_close_request;
+ r->state_handler = ngx_http_process_request_line;
return ngx_http_process_request(ev);
}
@@ -121,7 +124,7 @@
int ngx_http_process_request(ngx_event_t *ev)
{
- int n;
+ int n, rc;
ngx_connection_t *c ;
ngx_http_request_t *r;
@@ -130,79 +133,128 @@
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;
-
- 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);
if (n == 0) {
- if (ev->unexpected_eof) {
- ngx_log_error(NGX_LOG_INFO, ev->log, 0, "connection is closed");
- /* close request */
- return NGX_ERROR;
+ /* STUB: c-> */
+ if (ev->unexpected_eof)
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "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);
- }
-
- 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->state_handler = ngx_http_process_request_header;
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) {
- *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);
+ for ( ;; ) {
+ rc = ngx_read_http_header_line(r);
+
+ if (rc == NGX_OK) {
+ *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->connection->read->action = "reading client request body";
@@ -210,7 +262,9 @@
r->connection->read->unexpected_eof = 0;
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
@@ -221,7 +275,7 @@
}
#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;
char *name, *loc, *file;
@@ -489,16 +543,16 @@
#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(c->write, NGX_TIMER_EVENT);
+ ngx_del_event(r->connection->read, NGX_TIMER_EVENT);
+ ngx_del_event(r->connection->write, NGX_TIMER_EVENT);
- return ngx_event_close_connection(ev);
+ return NGX_ERROR;
}
diff --git a/src/http/ngx_http_filter.c b/src/http/ngx_http_filter.c
index abb91de..6f39d9b 100644
--- a/src/http/ngx_http_filter.c
+++ b/src/http/ngx_http_filter.c
@@ -141,7 +141,7 @@
ngx_test_null(ctx->hunk,
ngx_create_temp_hunk(r->pool, size,
- 50, 50),
+ 50, 50),
NGX_ERROR);
rc = ngx_http_filter_copy_hunk(ctx->hunk,
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 6bfab9b..5ab42ac 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -1,47 +1,47 @@
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_http.h>
int ngx_read_http_request_line(ngx_http_request_t *r)
{
char ch;
- char *buff = r->buff->buff;
- char *p = r->buff->pos;
+ char *p = r->header_in->pos.mem;
enum {
- rl_start = 0,
- rl_space_after_method,
- rl_spaces_before_uri,
- rl_after_slash_in_uri,
- rl_check_uri,
- rl_uri,
- rl_http_09,
- rl_http_version,
- rl_first_major_digit,
- rl_major_digit,
- rl_first_minor_digit,
- rl_minor_digit,
- rl_almost_done,
- rl_done
+ sw_start = 0,
+ sw_space_after_method,
+ sw_spaces_before_uri,
+ sw_after_slash_in_uri,
+ sw_check_uri,
+ sw_uri,
+ sw_http_09,
+ sw_http_version,
+ sw_first_major_digit,
+ sw_major_digit,
+ sw_first_minor_digit,
+ sw_minor_digit,
+ sw_almost_done,
+ sw_done
} state = r->state;
- while (p < r->buff->last && state < rl_done) {
+ while (p < r->header_in->last.mem && state < sw_done) {
ch = *p++;
/*
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) {
/* HTTP methods: GET, HEAD, POST */
- case rl_start:
+ case sw_start:
switch (ch) {
case 'G':
- if (p + 1 >= r->buff->last)
- return 0;
+ if (p + 1 >= r->header_in->last.mem)
+ return NGX_AGAIN;
if (*p != 'E' || *(p + 1) != 'T')
return NGX_HTTP_INVALID_METHOD;
@@ -51,8 +51,8 @@
break;
case 'H':
- if (p + 2 >= r->buff->last)
- return 0;
+ if (p + 2 >= r->header_in->last.mem)
+ return NGX_AGAIN;
if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D')
return NGX_HTTP_INVALID_METHOD;
@@ -62,8 +62,8 @@
break;
case 'P':
- if (p + 2 >= r->buff->last)
- return 0;
+ if (p + 2 >= r->header_in->last.mem)
+ return NGX_AGAIN;
if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T')
return NGX_HTTP_INVALID_METHOD;
@@ -76,14 +76,14 @@
return NGX_HTTP_INVALID_METHOD;
}
- state = rl_space_after_method;
+ state = sw_space_after_method;
break;
/* single space after method */
- case rl_space_after_method:
+ case sw_space_after_method:
switch (ch) {
case ' ':
- state = rl_spaces_before_uri;
+ state = sw_spaces_before_uri;
break;
default:
return NGX_HTTP_INVALID_METHOD;
@@ -91,123 +91,123 @@
break;
/* space* before URI */
- case rl_spaces_before_uri:
+ case sw_spaces_before_uri:
switch (ch) {
case '/':
r->uri_start = p - 1;
- state = rl_after_slash_in_uri;
+ state = sw_after_slash_in_uri;
break;
case ' ':
break;
default:
r->unusual_uri = 1;
r->uri_start = p - 1;
- state = rl_uri;
+ state = sw_uri;
break;
}
break;
/* check dot after slash */
- case rl_after_slash_in_uri:
+ case sw_after_slash_in_uri:
switch (ch) {
case CR:
r->uri_end = p - 1;
r->http_minor = 9;
- state = rl_almost_done;
+ state = sw_almost_done;
break;
case LF:
r->uri_end = p - 1;
r->http_minor = 9;
- state = rl_done;
+ state = sw_done;
break;
case ' ':
r->uri_end = p - 1;
- state = rl_http_09;
+ state = sw_http_09;
break;
case '.':
r->complex_uri = 1;
- state = rl_uri;
+ state = sw_uri;
break;
case '/':
r->complex_uri = 1;
- state = rl_uri;
+ state = sw_uri;
break;
case '?':
r->args_start = p;
- state = rl_uri;
+ state = sw_uri;
break;
default:
- state = rl_check_uri;
+ state = sw_check_uri;
break;
}
break;
/* check slash in URI */
- case rl_check_uri:
+ case sw_check_uri:
switch (ch) {
case CR:
r->uri_end = p - 1;
r->http_minor = 9;
- state = rl_almost_done;
+ state = sw_almost_done;
break;
case LF:
r->uri_end = p - 1;
r->http_minor = 9;
- state = rl_done;
+ state = sw_done;
break;
case ' ':
r->uri_end = p - 1;
- state = rl_http_09;
+ state = sw_http_09;
break;
case '.':
r->uri_ext = p;
break;
case '/':
r->uri_ext = NULL;
- state = rl_after_slash_in_uri;
+ state = sw_after_slash_in_uri;
break;
case '?':
r->args_start = p;
- state = rl_uri;
+ state = sw_uri;
break;
}
break;
/* URI */
- case rl_uri:
+ case sw_uri:
switch (ch) {
case CR:
r->uri_end = p - 1;
r->http_minor = 9;
- state = rl_almost_done;
+ state = sw_almost_done;
break;
case LF:
r->uri_end = p - 1;
r->http_minor = 9;
- state = rl_done;
+ state = sw_done;
break;
case ' ':
r->uri_end = p - 1;
- state = rl_http_09;
+ state = sw_http_09;
break;
}
break;
/* space+ after URI */
- case rl_http_09:
+ case sw_http_09:
switch (ch) {
case ' ':
break;
case CR:
r->http_minor = 9;
- state = rl_almost_done;
+ state = sw_almost_done;
break;
case LF:
r->http_minor = 9;
- state = rl_done;
+ state = sw_done;
break;
case 'H':
- state = rl_http_version;
+ state = sw_http_version;
break;
default:
return NGX_HTTP_INVALID_REQUEST;
@@ -215,33 +215,33 @@
break;
/* TTP/ */
- case rl_http_version:
- if (p + 2 >= r->buff->last) {
- r->state = rl_http_version;
- r->buff->pos = p - 1;
- return 0;
+ case sw_http_version:
+ if (p + 2 >= r->header_in->last.mem) {
+ r->state = sw_http_version;
+ r->header_in->pos.mem = p - 1;
+ return NGX_AGAIN;
}
if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/')
return NGX_HTTP_INVALID_REQUEST;
p += 3;
- state = rl_first_major_digit;
+ state = sw_first_major_digit;
break;
/* first digit of major HTTP version */
- case rl_first_major_digit:
+ case sw_first_major_digit:
if (ch < '1' || ch > '9')
return NGX_HTTP_INVALID_REQUEST;
r->http_major = ch - '0';
- state = rl_major_digit;
+ state = sw_major_digit;
break;
/* major HTTP version or dot */
- case rl_major_digit:
+ case sw_major_digit:
if (ch == '.') {
- state = rl_first_minor_digit;
+ state = sw_first_minor_digit;
break;
}
@@ -252,24 +252,24 @@
break;
/* first digit of minor HTTP version */
- case rl_first_minor_digit:
+ case sw_first_minor_digit:
if (ch < '0' || ch > '9')
return NGX_HTTP_INVALID_REQUEST;
r->http_minor = ch - '0';
- state = rl_minor_digit;
+ state = sw_minor_digit;
break;
/* minor HTTP version or end of request line */
- case rl_minor_digit:
+ case sw_minor_digit:
if (ch == CR) {
- state = rl_almost_done;
+ state = sw_almost_done;
break;
}
if (ch == LF) {
- state = rl_done;
+ state = sw_done;
break;
}
@@ -280,70 +280,72 @@
break;
/* end of request line */
- case rl_almost_done:
+ case sw_almost_done:
switch (ch) {
case LF:
- state = rl_done;
+ state = sw_done;
break;
default:
- return NGX_HTTP_INVALID_METHOD;
+ return NGX_HTTP_INVALID_REQUEST;
}
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->state = rl_start;
- return 1;
+ r->state = sw_start;
+ if (r->http_version == 9 && r->method == NGX_HTTP_HEAD)
+ return NGX_HTTP_INVALID_HEAD;
+ else
+ return NGX_OK;
} else {
r->state = state;
- return 0;
+ return NGX_AGAIN;
}
}
int ngx_read_http_header_line(ngx_http_request_t *r)
{
char c, ch;
- char *buff = r->buff->buff;
- char *p = r->buff->pos;
+ char *p = r->header_in->pos.mem;
enum {
- hl_start = 0,
- hl_name,
- hl_space_before_value,
- hl_value,
- hl_space_after_value,
- hl_almost_done,
- header_almost_done,
- hl_done,
- header_done
+ sw_start = 0,
+ sw_name,
+ sw_space_before_value,
+ sw_value,
+ sw_space_after_value,
+ sw_almost_done,
+ sw_header_almost_done,
+ sw_done,
+ sw_header_done
} state = r->state;
- while (p < r->buff->last && state < hl_done) {
+ while (p < r->header_in->last.mem && state < sw_done) {
ch = *p++;
/*
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) {
/* first char */
- case hl_start:
+ case sw_start:
switch (ch) {
case CR:
r->header_end = p - 1;
- state = header_almost_done;
+ state = sw_header_almost_done;
break;
case LF:
r->header_end = p - 1;
- state = header_done;
+ state = sw_header_done;
break;
default:
- state = hl_name;
+ state = sw_name;
r->header_name_start = p - 1;
c = ch | 0x20;
@@ -362,14 +364,14 @@
break;
/* header name */
- case hl_name:
+ case sw_name:
c = ch | 0x20;
if (c >= 'a' && c <= 'z')
break;
if (ch == ':') {
r->header_name_end = p - 1;
- state = hl_space_before_value;
+ state = sw_space_before_value;
break;
}
@@ -382,65 +384,65 @@
return NGX_HTTP_INVALID_HEADER;
/* space* before header value */
- case hl_space_before_value:
+ case sw_space_before_value:
switch (ch) {
case ' ':
break;
case CR:
r->header_start = r->header_end = p - 1;
- state = hl_almost_done;
+ state = sw_almost_done;
break;
case LF:
r->header_start = r->header_end = p - 1;
- state = hl_done;
+ state = sw_done;
break;
default:
r->header_start = p - 1;
- state = hl_value;
+ state = sw_value;
break;
}
break;
/* header value */
- case hl_value:
+ case sw_value:
switch (ch) {
case ' ':
r->header_end = p - 1;
- state = hl_space_after_value;
+ state = sw_space_after_value;
break;
case CR:
r->header_end = p - 1;
- state = hl_almost_done;
+ state = sw_almost_done;
break;
case LF:
r->header_end = p - 1;
- state = hl_done;
+ state = sw_done;
break;
}
break;
/* space* before end of header line */
- case hl_space_after_value:
+ case sw_space_after_value:
switch (ch) {
case ' ':
break;
case CR:
- state = hl_almost_done;
+ state = sw_almost_done;
break;
case LF:
- state = hl_done;
+ state = sw_done;
break;
default:
- state = hl_value;
+ state = sw_value;
break;
}
break;
/* end of header line */
- case hl_almost_done:
+ case sw_almost_done:
switch (ch) {
case LF:
- state = hl_done;
+ state = sw_done;
break;
default:
return NGX_HTTP_INVALID_HEADER;
@@ -448,10 +450,10 @@
break;
/* end of header */
- case header_almost_done:
+ case sw_header_almost_done:
switch (ch) {
case LF:
- state = header_done;
+ state = sw_header_done;
break;
default:
return NGX_HTTP_INVALID_HEADER;
@@ -460,16 +462,16 @@
}
}
- r->buff->pos = p;
+ r->header_in->pos.mem = p;
- if (state == hl_done) {
- r->state = hl_start;
- return 1;
- } else if (state == header_done) {
- r->state = hl_start;
- return 2;
+ if (state == sw_done) {
+ r->state = sw_start;
+ return NGX_OK;
+ } else if (state == sw_header_done) {
+ r->state = sw_start;
+ return NGX_HTTP_HEADER_DONE;
} else {
r->state = state;
- return 0;
+ return NGX_AGAIN;
}
}