diff src/http/modules/ngx_http_proxy_module.c @ 4925:32030fa8cb14

Request body: chunked parsing moved to ngx_http_parse.c from proxy. No functional changes.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 21 Nov 2012 00:59:16 +0000
parents 8036fc6af2df
children 93294110728f
line wrap: on
line diff
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -81,13 +81,10 @@ typedef struct {
 
 typedef struct {
     ngx_http_status_t              status;
+    ngx_http_chunked_t             chunked;
     ngx_http_proxy_vars_t          vars;
     size_t                         internal_body_length;
 
-    ngx_uint_t                     state;
-    off_t                          size;
-    off_t                          length;
-
     ngx_uint_t                     head;  /* unsigned  head:1 */
 } ngx_http_proxy_ctx_t;
 
@@ -1252,7 +1249,7 @@ ngx_http_proxy_reinit_request(ngx_http_r
     ctx->status.count = 0;
     ctx->status.start = NULL;
     ctx->status.end = NULL;
-    ctx->state = 0;
+    ctx->chunked.state = 0;
 
     r->upstream->process_header = ngx_http_proxy_process_status_line;
     r->upstream->pipe->input_filter = ngx_http_proxy_copy_filter;
@@ -1617,265 +1614,6 @@ ngx_http_proxy_copy_filter(ngx_event_pip
 }
 
 
-static ngx_inline ngx_int_t
-ngx_http_proxy_parse_chunked(ngx_http_request_t *r, ngx_buf_t *buf)
-{
-    u_char                *pos, ch, c;
-    ngx_int_t              rc;
-    ngx_http_proxy_ctx_t  *ctx;
-    enum {
-        sw_chunk_start = 0,
-        sw_chunk_size,
-        sw_chunk_extension,
-        sw_chunk_extension_almost_done,
-        sw_chunk_data,
-        sw_after_data,
-        sw_after_data_almost_done,
-        sw_last_chunk_extension,
-        sw_last_chunk_extension_almost_done,
-        sw_trailer,
-        sw_trailer_almost_done,
-        sw_trailer_header,
-        sw_trailer_header_almost_done
-    } state;
-
-    ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
-    if (ctx == NULL) {
-        return NGX_ERROR;
-    }
-
-    state = ctx->state;
-
-    if (state == sw_chunk_data && ctx->size == 0) {
-        state = sw_after_data;
-    }
-
-    rc = NGX_AGAIN;
-
-    for (pos = buf->pos; pos < buf->last; pos++) {
-
-        ch = *pos;
-
-        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http proxy chunked byte: %02Xd s:%d", ch, state);
-
-        switch (state) {
-
-        case sw_chunk_start:
-            if (ch >= '0' && ch <= '9') {
-                state = sw_chunk_size;
-                ctx->size = ch - '0';
-                break;
-            }
-
-            c = (u_char) (ch | 0x20);
-
-            if (c >= 'a' && c <= 'f') {
-                state = sw_chunk_size;
-                ctx->size = c - 'a' + 10;
-                break;
-            }
-
-            goto invalid;
-
-        case sw_chunk_size:
-            if (ch >= '0' && ch <= '9') {
-                ctx->size = ctx->size * 16 + (ch - '0');
-                break;
-            }
-
-            c = (u_char) (ch | 0x20);
-
-            if (c >= 'a' && c <= 'f') {
-                ctx->size = ctx->size * 16 + (c - 'a' + 10);
-                break;
-            }
-
-            if (ctx->size == 0) {
-
-                switch (ch) {
-                case CR:
-                    state = sw_last_chunk_extension_almost_done;
-                    break;
-                case LF:
-                    state = sw_trailer;
-                    break;
-                case ';':
-                case ' ':
-                case '\t':
-                    state = sw_last_chunk_extension;
-                    break;
-                default:
-                    goto invalid;
-                }
-
-                break;
-            }
-
-            switch (ch) {
-            case CR:
-                state = sw_chunk_extension_almost_done;
-                break;
-            case LF:
-                state = sw_chunk_data;
-                break;
-            case ';':
-            case ' ':
-            case '\t':
-                state = sw_chunk_extension;
-                break;
-            default:
-                goto invalid;
-            }
-
-            break;
-
-        case sw_chunk_extension:
-            switch (ch) {
-            case CR:
-                state = sw_chunk_extension_almost_done;
-                break;
-            case LF:
-                state = sw_chunk_data;
-            }
-            break;
-
-        case sw_chunk_extension_almost_done:
-            if (ch == LF) {
-                state = sw_chunk_data;
-                break;
-            }
-            goto invalid;
-
-        case sw_chunk_data:
-            rc = NGX_OK;
-            goto data;
-
-        case sw_after_data:
-            switch (ch) {
-            case CR:
-                state = sw_after_data_almost_done;
-                break;
-            case LF:
-                state = sw_chunk_start;
-            }
-            break;
-
-        case sw_after_data_almost_done:
-            if (ch == LF) {
-                state = sw_chunk_start;
-                break;
-            }
-            goto invalid;
-
-        case sw_last_chunk_extension:
-            switch (ch) {
-            case CR:
-                state = sw_last_chunk_extension_almost_done;
-                break;
-            case LF:
-                state = sw_trailer;
-            }
-            break;
-
-        case sw_last_chunk_extension_almost_done:
-            if (ch == LF) {
-                state = sw_trailer;
-                break;
-            }
-            goto invalid;
-
-        case sw_trailer:
-            switch (ch) {
-            case CR:
-                state = sw_trailer_almost_done;
-                break;
-            case LF:
-                goto done;
-            default:
-                state = sw_trailer_header;
-            }
-            break;
-
-        case sw_trailer_almost_done:
-            if (ch == LF) {
-                goto done;
-            }
-            goto invalid;
-
-        case sw_trailer_header:
-            switch (ch) {
-            case CR:
-                state = sw_trailer_header_almost_done;
-                break;
-            case LF:
-                state = sw_trailer;
-            }
-            break;
-
-        case sw_trailer_header_almost_done:
-            if (ch == LF) {
-                state = sw_trailer;
-                break;
-            }
-            goto invalid;
-
-        }
-    }
-
-data:
-
-    ctx->state = state;
-    buf->pos = pos;
-
-    switch (state) {
-
-    case sw_chunk_start:
-        ctx->length = 3 /* "0" LF LF */;
-        break;
-    case sw_chunk_size:
-        ctx->length = 2 /* LF LF */
-                      + (ctx->size ? ctx->size + 4 /* LF "0" LF LF */ : 0);
-        break;
-    case sw_chunk_extension:
-    case sw_chunk_extension_almost_done:
-        ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */;
-        break;
-    case sw_chunk_data:
-        ctx->length = ctx->size + 4 /* LF "0" LF LF */;
-        break;
-    case sw_after_data:
-    case sw_after_data_almost_done:
-        ctx->length = 4 /* LF "0" LF LF */;
-        break;
-    case sw_last_chunk_extension:
-    case sw_last_chunk_extension_almost_done:
-        ctx->length = 2 /* LF LF */;
-        break;
-    case sw_trailer:
-    case sw_trailer_almost_done:
-        ctx->length = 1 /* LF */;
-        break;
-    case sw_trailer_header:
-    case sw_trailer_header_almost_done:
-        ctx->length = 2 /* LF LF */;
-        break;
-
-    }
-
-    return rc;
-
-done:
-
-    return NGX_DONE;
-
-invalid:
-
-    return NGX_ERROR;
-}
-
-
 static ngx_int_t
 ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
 {
@@ -1901,7 +1639,7 @@ ngx_http_proxy_chunked_filter(ngx_event_
 
     for ( ;; ) {
 
-        rc = ngx_http_proxy_parse_chunked(r, buf);
+        rc = ngx_http_parse_chunked(r, buf, &ctx->chunked);
 
         if (rc == NGX_OK) {
 
@@ -1952,16 +1690,16 @@ ngx_http_proxy_chunked_filter(ngx_event_
             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
                            "input buf #%d %p", b->num, b->pos);
 
-            if (buf->last - buf->pos >= ctx->size) {
-
-                buf->pos += ctx->size;
+            if (buf->last - buf->pos >= ctx->chunked.size) {
+
+                buf->pos += ctx->chunked.size;
                 b->last = buf->pos;
-                ctx->size = 0;
+                ctx->chunked.size = 0;
 
                 continue;
             }
 
-            ctx->size -= buf->last - buf->pos;
+            ctx->chunked.size -= buf->last - buf->pos;
             buf->pos = buf->last;
             b->last = buf->last;
 
@@ -1982,7 +1720,7 @@ ngx_http_proxy_chunked_filter(ngx_event_
 
             /* set p->length, minimal amount of data we want to see */
 
-            p->length = ctx->length;
+            p->length = ctx->chunked.length;
 
             break;
         }
@@ -1997,7 +1735,7 @@ ngx_http_proxy_chunked_filter(ngx_event_
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http proxy chunked state %d, length %d",
-                   ctx->state, p->length);
+                   ctx->chunked.state, p->length);
 
     if (b) {
         b->shadow = buf;
@@ -2094,7 +1832,7 @@ ngx_http_proxy_non_buffered_chunked_filt
 
     for ( ;; ) {
 
-        rc = ngx_http_proxy_parse_chunked(r, buf);
+        rc = ngx_http_parse_chunked(r, buf, &ctx->chunked);
 
         if (rc == NGX_OK) {
 
@@ -2116,13 +1854,13 @@ ngx_http_proxy_non_buffered_chunked_filt
             b->pos = buf->pos;
             b->tag = u->output.tag;
 
-            if (buf->last - buf->pos >= ctx->size) {
-                buf->pos += ctx->size;
+            if (buf->last - buf->pos >= ctx->chunked.size) {
+                buf->pos += ctx->chunked.size;
                 b->last = buf->pos;
-                ctx->size = 0;
+                ctx->chunked.size = 0;
 
             } else {
-                ctx->size -= buf->last - buf->pos;
+                ctx->chunked.size -= buf->last - buf->pos;
                 buf->pos = buf->last;
                 b->last = buf->last;
             }