changeset 21:df7fb216a149

nginx-0.0.1-2002-12-04-19:29:40 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 04 Dec 2002 16:29:40 +0000
parents a649c0a0adb3
children aa3b53e74728
files src/http/modules/ngx_http_event_proxy_handler.c src/http/modules/ngx_http_event_proxy_handler.h src/http/ngx_http_parse.c
diffstat 3 files changed, 169 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/ngx_http_event_proxy_handler.c
+++ b/src/http/modules/ngx_http_event_proxy_handler.c
@@ -16,6 +16,10 @@ static int ngx_http_proxy_connect(ngx_ht
                                   struct sockaddr_in *addr,
                                   char *addr_text);
 static int ngx_http_proxy_send_request(ngx_event_t *ev);
+static int ngx_http_proxy_read_response_header(ngx_event_t *ev);
+
+
+static char conn_close[] = "Connection: close" CRLF;
 
 
 int ngx_http_proxy_handler(ngx_http_request_t *r)
@@ -53,11 +57,11 @@ static ngx_chain_t *ngx_http_proxy_creat
     ngx_chain_t      *chain;
     ngx_table_elt_t  *header;
 
-    /* STUB */
-    int size = 1024;
+    /* "+ 4" is for "\r\n" after request line and at the header end */
+    len = r->request_line.len + 4;
 
-    /* "+ 2" is for "\r\n" */
-    len = r->request_line.len + 2;
+    /* "Connection: close\r\n" */
+    len += sizeof(conn_close) - 1;
 
     header = (ngx_table_elt_t *) r->headers_in.headers->elts;
     for (i = 0; i < r->headers_in.headers->nelts; i++) {
@@ -68,9 +72,6 @@ static ngx_chain_t *ngx_http_proxy_creat
         len += header[i].key.len + header[i].value.len + 4;
     }
 
-    /* add "\r\n" at the header end */
-    len += 2;
-
     /* STUB */ len++;
 
     ngx_test_null(hunk, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL);
@@ -80,10 +81,16 @@ static ngx_chain_t *ngx_http_proxy_creat
     hunk->last.mem += r->request_line.len;
     *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF;
 
+    ngx_memcpy(hunk->last.mem, conn_close, sizeof(conn_close) - 1);
+    hunk->last.mem += sizeof(conn_close) - 1;
+
     for (i = 0; i < r->headers_in.headers->nelts; i++) {
         if (&header[i] == r->headers_in.host)
             continue;
 
+        if (&header[i] == r->headers_in.connection)
+            continue;
+
         ngx_memcpy(hunk->last.mem, header[i].key.data, header[i].key.len);
         hunk->last.mem += header[i].key.len;
 
@@ -107,6 +114,7 @@ static ngx_chain_t *ngx_http_proxy_creat
     return chain;
 }
 
+
 static int ngx_http_proxy_connect(ngx_http_request_t *r,
                                   struct sockaddr_in *addr,
                                   char *addr_text)
@@ -114,6 +122,7 @@ static int ngx_http_proxy_connect(ngx_ht
     int                  rc;
     ngx_err_t            err;
     ngx_socket_t         s;
+    ngx_event_t         *rev, *wev;
     ngx_connection_t    *c, *pc;
     ngx_http_log_ctx_t  *ctx;
 
@@ -171,41 +180,49 @@ static int ngx_http_proxy_connect(ngx_ht
     }
 
     pc = &ngx_connections[s];
+    rev = &ngx_read_events[s];
+    wev = &ngx_write_events[s];
 
-    ngx_memzero(&ngx_read_events[s], sizeof(ngx_event_t));
-    ngx_memzero(&ngx_write_events[s], sizeof(ngx_event_t));
-    ngx_memzero(&ngx_connections[s], sizeof(ngx_connection_t));
-
-    ngx_read_events[s].data = ngx_write_events[s].data = &ngx_connections[s];
-    ngx_connections[s].read = &ngx_read_events[s];
-    ngx_connections[s].write = &ngx_write_events[s];
+    ngx_memzero(rev, sizeof(ngx_event_t));
+    ngx_memzero(wev, sizeof(ngx_event_t));
+    ngx_memzero(pc, sizeof(ngx_connection_t));
 
-    ngx_connections[s].data = r;
+    rev->data = wev->data = pc;
+    pc->read = rev;
+    pc->write = wev;
+
+    pc->data = r;
 
-    ngx_connections[s].fd = s;
-    ngx_connections[s].server = c->server;
-    ngx_connections[s].servers = c->servers;
+    pc->fd = s;
+    pc->server = c->server;
+    pc->servers = c->servers;
 
-    ngx_connections[s].log =
-        ngx_read_events[s].log = ngx_write_events[s].log = c->log;
+    pc->log = rev->log = wev->log = c->log;
 
     ngx_test_null(pc->pool,
                   ngx_create_pool(/* STUB */ 1024 /* */, pc->log),
                   NGX_ERROR);
 
-    if (rc == -1) {
-        ngx_write_events[s].event_handler = ngx_http_proxy_send_request;
+    wev->event_handler = ngx_http_proxy_send_request;
+    rev->event_handler = ngx_http_proxy_read_response_header;
+
+#if (HAVE_CLEAR_EVENT)
+    if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK)
+#else
+    if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK)
+#endif
+        return NGX_ERROR;
 
-        return ngx_add_event(&ngx_write_events[s],
-                             NGX_WRITE_EVENT, NGX_ONESHOT_EVENT);
-    }
+    if (rc == -1)
+        return ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT);
 
-    ngx_write_events[s].write = 1;
-    ngx_write_events[s].ready = 1;
+    wev->write = 1;
+    wev->ready = 1;
 
-    return ngx_http_proxy_send_request(&ngx_write_events[s]);
+    return ngx_http_proxy_send_request(wev);
 }
 
+
 static int ngx_http_proxy_send_request(ngx_event_t *ev)
 {
     ngx_chain_t           *chain;
@@ -223,43 +240,13 @@ static int ngx_http_proxy_send_request(n
 
     p->out = chain;
 
-    /* STUB */ return NGX_ERROR;
-    return NGX_OK;
+    return NGX_AGAIN;
 }
 
-#if 0
-
-static int ngx_http_proxy_send_request(ngx_event_t *ev)
-{
-    ngx_connection_t      *c;
-    ngx_http_request_t    *r;
-    ngx_http_proxy_ctx_t  *p;
-
-    c = (ngx_connection_t *) ev->data;
-    r = (ngx_http_request_t *) c->data;
-    p = (ngx_http_proxy_ctx_t *) ngx_get_module_ctx(r, ngx_http_proxy_module);
-
-    n = ngx_send(p->fd, p->header_out->pos.mem,
-                 p->header_out->end.mem - p->header_out->pos.mem);
-
-    if (n == NGX_ERROR) {
-        ngx_log_error(NGX_LOG_ERR, r->log, ngx_socket_errno,
-                      ngx_send_n " %s falied", p->addr_text);
-        return NGX_ERROR;
-    }
-
-    p->header_out->pos.mem += n;
-
-    if (p->header_out->end.mem - p->header_out->pos.mem > 0)
-        return NGX_AGAIN;
-
-    /* TODO: body */
-
-    return NGX_OK;
-}
 
 static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
 {
+    int  n;
     ngx_connection_t      *c;
     ngx_http_request_t    *r;
     ngx_http_proxy_ctx_t  *p;
@@ -271,11 +258,30 @@ static int ngx_http_proxy_read_response_
     r = (ngx_http_request_t *) c->data;
     p = (ngx_http_proxy_ctx_t *) ngx_get_module_ctx(r, ngx_http_proxy_module);
 
-    n = ngx_event_recv(c, p->header_in->last.mem,
-                       p->header_in->end - p->header_in->last.mem);
+    if (p->header_in == NULL) {
+        ngx_test_null(p->header_in,
+                      ngx_palloc(r->pool, sizeof(ngx_http_proxy_header_in_t)),
+                      NGX_ERROR);
+
+        ngx_test_null(p->hunk,
+                      ngx_create_temp_hunk(r->pool,
+                                           /* STUB */ 1024 /* */, 0, 0),
+                      NGX_ERROR);
+    }
 
+    n = ngx_event_recv(c, p->hunk->last.mem, p->hunk->end - p->hunk->last.mem);
+
+    ngx_log_debug(r->connection->log, "READ:%d" _ n);
+
+    p->hunk->last.mem += n;
+
+    *p->hunk->last.mem = '\0';
+    ngx_log_debug(r->connection->log, "PROXY:\n'%s'" _ p->hunk->pos.mem);
+
+    /* STUB */ return NGX_ERROR;
 }
 
+#if 0
 static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
 {
     ngx_connection_t      *c;
--- a/src/http/modules/ngx_http_event_proxy_handler.h
+++ b/src/http/modules/ngx_http_event_proxy_handler.h
@@ -8,7 +8,15 @@
 
 
 typedef struct {
+    int dummy;
+} ngx_http_proxy_header_in_t;
+
+typedef struct {
     ngx_chain_t  *out;
+
+    ngx_hunk_t   *hunk;
+
+    ngx_http_proxy_header_in_t  *header_in;
 } ngx_http_proxy_ctx_t;
 
 
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -5,8 +5,8 @@
 
 int ngx_read_http_request_line(ngx_http_request_t *r)
 {
-    char  ch;
-    char *p = r->header_in->pos.mem;
+    char   ch;
+    char  *p;
     enum {
         sw_start = 0,
         sw_space_after_method,
@@ -22,7 +22,10 @@ int ngx_read_http_request_line(ngx_http_
         sw_minor_digit,
         sw_almost_done,
         sw_done
-    } state = r->state;
+    } state;
+
+    state = r->state;
+    p = r->header_in->pos.mem;
 
     while (p < r->header_in->last.mem && state < sw_done) {
         ch = *p++;
@@ -214,7 +217,7 @@ printf("\nstate: %d, pos: %x, end: %x, c
             }
             break;
 
-        /* TTP/ */
+        /* "TTP/" */
         case sw_http_version:
             if (p + 2 >= r->header_in->last.mem) {
                 r->state = sw_http_version;
@@ -309,10 +312,90 @@ printf("\nstate: %d, pos: %x, end: %x, c
     }
 }
 
+#if 0
+int ngx_read_http_response_line(ngx_http_request_t *r)
+{
+    char   c, ch;
+    char  *p;
+    enum  {
+        sw_start = 0,
+        sw_done
+    } state;
+
+    state = r->state;
+    p = r->header_in->pos.mem;
+
+    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->header_in->last, ch, p);
+*/
+
+        switch (state) {
+
+        /* "HTTP/" */
+        case sw_start:
+            if (p + 3 >= r->header_in->last.mem)
+                return NGX_AGAIN;
+
+            if (ch != 'H' || *p != 'T' || *(p + 1) != 'T' || *(p + 2) != 'P'
+                          || *(p + 3) != '/')
+                return NGX_HTTP_PARSE_NO_HEADER;
+
+            p += 4;
+            state = sw_first_major_digit;
+            break;
+
+        /* first digit of major HTTP version */
+        case sw_first_major_digit:
+            if (ch < '1' || ch > '9')
+                return NGX_HTTP_PARSE_NO_HEADER;
+
+            state = sw_major_digit;
+            break;
+
+        /* major HTTP version or dot */
+        case sw_major_digit:
+            if (ch == '.') {
+                state = sw_first_minor_digit;
+                break;
+            }
+
+            if (ch < '0' || ch > '9')
+                return NGX_HTTP_PARSE_NO_HEADER;
+
+            break;
+
+        /* first digit of minor HTTP version */
+        case sw_first_minor_digit:
+            if (ch < '0' || ch > '9')
+                return NGX_HTTP_PARSE_NO_HEADER;
+
+            state = sw_minor_digit;
+            break;
+
+        /* minor HTTP version or end of request line */
+        case sw_minor_digit:
+            if (ch == ' ') {
+                state = sw_code;
+                break;
+            }
+
+            if (ch < '0' || ch > '9')
+                return NGX_HTTP_PARSE_NO_HEADER;
+
+            break;
+        }
+    }
+}
+#endif
+
 int ngx_read_http_header_line(ngx_http_request_t *r)
 {
-    char  c, ch;
-    char *p = r->header_in->pos.mem;
+    char   c, ch;
+    char  *p;
     enum  {
         sw_start = 0,
         sw_name,
@@ -323,7 +406,10 @@ int ngx_read_http_header_line(ngx_http_r
         sw_header_almost_done,
         sw_done,
         sw_header_done
-    } state = r->state;
+    } state;
+
+    state = r->state;
+    p = r->header_in->pos.mem;
 
     while (p < r->header_in->last.mem && state < sw_done) {
         ch = *p++;