view src/imap/ngx_imap_parse.c @ 509:9b8c906f6e63 release-0.1.29

nginx-0.1.29-RELEASE import *) Feature: the ngx_http_ssi_module supports "include virtual" command. *) Feature: the ngx_http_ssi_module supports the condition command like 'if expr="$NAME"' and "else" and "endif" commands. Only one nested level is supported. *) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and DATE_GMT variables and "config timefmt" command. *) Feature: the "ssi_ignore_recycled_buffers" directive. *) Bugfix: the "echo" command did not show the default value for the empty QUERY_STRING variable. *) Change: the ngx_http_proxy_module was rewritten. *) Feature: the "proxy_redirect", "proxy_pass_request_headers", "proxy_pass_request_body", and "proxy_method" directives. *) Feature: the "proxy_set_header" directive. The "proxy_x_var" was canceled and must be replaced with the proxy_set_header directive. *) Change: the "proxy_preserve_host" is canceled and must be replaced with the "proxy_set_header Host $host" and the "proxy_redirect off" directives, the "proxy_set_header Host $host:$proxy_port" directive and the appropriate proxy_redirect directives. *) Change: the "proxy_set_x_real_ip" is canceled and must be replaced with the "proxy_set_header X-Real-IP $remote_addr" directive. *) Change: the "proxy_add_x_forwarded_for" is canceled and must be replaced with the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for" directive. *) Change: the "proxy_set_x_url" is canceled and must be replaced with the "proxy_set_header X-URL http://$host:$server_port$request_uri" directive. *) Feature: the "fastcgi_param" directive. *) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params" directive are canceled and must be replaced with the fastcgi_param directives. *) Feature: the "index" directive can use the variables. *) Feature: the "index" directive can be used at http and server levels. *) Change: the last index only in the "index" directive can be absolute. *) Feature: the "rewrite" directive can use the variables. *) Feature: the "internal" directive. *) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR, SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME, REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables. *) Change: nginx now passes the invalid lines in a client request headers or a backend response header. *) Bugfix: if the backend did not transfer response for a long time and the "send_timeout" was less than "proxy_read_timeout", then nginx returned the 408 response. *) Bugfix: the segmentation fault was occurred if the backend sent an invalid line in response header; the bug had appeared in 0.1.26. *) Bugfix: the segmentation fault may occurred in FastCGI fault tolerance configuration. *) Bugfix: the "expires" directive did not remove the previous "Expires" and "Cache-Control" headers. *) Bugfix: nginx did not take into account trailing dot in "Host" header line. *) Bugfix: the ngx_http_auth_module did not work under Linux. *) Bugfix: the rewrite directive worked incorrectly, if the arguments were in a request. *) Bugfix: nginx could not be built on MacOS X.
author Igor Sysoev <igor@sysoev.ru>
date Thu, 12 May 2005 14:58:06 +0000
parents d4ea69372b94
children 7fa11e5c6e96
line wrap: on
line source


/*
 * Copyright (C) Igor Sysoev
 */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_imap.h>


ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
{
    u_char      ch, *p, *c;
    ngx_str_t  *arg;
    enum {
        sw_start = 0,
        sw_spaces_before_argument,
        sw_argument,
        sw_almost_done,
        sw_done
    } state;

    state = s->state;
    p = s->buffer->pos;

    while (p < s->buffer->last && state < sw_done) {
        ch = *p++;

        switch (state) {

        /* POP3 command */

        case sw_start:
            if (ch == ' ' || ch == CR || ch == LF) {
                c = s->buffer->start;

                if (p - 1 - c == 4) {

                    if (c[0] == 'U' && c[1] == 'S'
                        && c[2] == 'E' && c[3] == 'R')
                    {
                        s->command = NGX_POP3_USER;

                    } else if (c[0] == 'P' && c[1] == 'A'
                               && c[2] == 'S' && c[3] == 'S')
                    {
                        s->command = NGX_POP3_PASS;

                    } else if (c[0] == 'Q' && c[1] == 'U'
                               && c[2] == 'I' && c[3] == 'T')
                    {
                        s->command = NGX_POP3_QUIT;

#if 0
                    } else if (c[0] == 'N' && c[1] == 'O'
                               && c[2] == 'O' && c[3] == 'P')
                    {
                        s->command = NGX_POP3_NOOP;
#endif

                    } else {
                        s->state = sw_start;
                        return NGX_IMAP_PARSE_INVALID_COMMAND;
                    }

                } else {
                    s->state = sw_start;
                    return NGX_IMAP_PARSE_INVALID_COMMAND;
                }

                switch (ch) {
                case ' ':
                    state = sw_spaces_before_argument;
                    break;
                case CR:
                    state = sw_almost_done;
                    break;
                case LF:
                    state = sw_done;
                    break;
                }
                break;
            }

            if (ch < 'A' || ch > 'Z') {
                s->state = sw_start;
                return NGX_IMAP_PARSE_INVALID_COMMAND;
            }

            break;

        /* the spaces before the argument */
        case sw_spaces_before_argument:
            switch (ch) {
            case ' ':
                break;
            case CR:
                state = sw_almost_done;
                s->arg_end = p - 1;
                break;
            case LF:
                state = sw_done;
                s->arg_end = p - 1;
                break;
            default:
                if (s->args.nelts > 2) {
                    s->state = sw_start;
                    return NGX_IMAP_PARSE_INVALID_COMMAND;
                }

                state = sw_argument;
                s->arg_start = p - 1;
                break;
            }
            break;

        /* the argument */
        case sw_argument:
            switch (ch) {
            case ' ':
            case CR:
            case LF:
                arg = ngx_array_push(&s->args);
                if (arg == NULL) {
                    return NGX_ERROR;
                }
                arg->len = p - 1 - s->arg_start;
                arg->data = s->arg_start;
                s->arg_start = NULL;

                switch (ch) {
                case ' ':
                    state = sw_spaces_before_argument;
                    break;
                case CR:
                    state = sw_almost_done;
                    break;
                case LF:
                    state = sw_done;
                    break;
                }
                break;

            default:
                break;
            }
            break;

        /* end of request line */
        case sw_almost_done:
            switch (ch) {
            case LF:
                state = sw_done;
                break;
            default:
                s->state = sw_start;
                return NGX_IMAP_PARSE_INVALID_COMMAND;
            }
            break;

        /* suppress warning */
        case sw_done:
            break;
        }
    }

    s->buffer->pos = p;

    if (state == sw_done) {
        if (s->arg_start) {
            arg = ngx_array_push(&s->args);
            if (arg == NULL) {
                return NGX_ERROR;
            }
            arg->len = s->arg_end - s->arg_start;
            arg->data = s->arg_start;
            s->arg_start = NULL;
        }

        s->state = sw_start;
        return NGX_OK;

    } else {
        s->state = state;
        return NGX_AGAIN;
    }
}