view src/core/ngx_parse.c @ 196:8759b346e431 NGINX_0_3_45

nginx 0.3.45 *) Feature: the "ssl_verify_client", "ssl_verify_depth", and "ssl_client_certificate" directives. *) Change: the $request_method variable now returns the main request method. *) Change: the ° symbol codes were changed in koi-win conversion table. *) Feature: the euro и N symbols were added to koi-win conversion table. *) Bugfix: if nginx distributed the requests among several backends and some backend failed, then requests intended for this backend was directed to one live backend only instead of being distributed among the rest.
author Igor Sysoev <http://sysoev.ru>
date Sat, 06 May 2006 00:00:00 +0400
parents 408f195b3482
children d2ae1c9f1fd3
line wrap: on
line source


/*
 * Copyright (C) Igor Sysoev
 */


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


ssize_t
ngx_parse_size(ngx_str_t *line)
{
    u_char     last;
    size_t     len;
    ssize_t    size;
    ngx_int_t  scale;

    len = line->len;
    last = line->data[len - 1];

    switch (last) {
    case 'K':
    case 'k':
        len--;
        scale = 1024;
        break;

    case 'M':
    case 'm':
        len--;
        scale = 1024 * 1024;
        break;

    default:
        scale = 1;
    }

    size = ngx_atosz(line->data, len);
    if (size == NGX_ERROR) {
        return NGX_ERROR;
    }

    size *= scale;

    return size;
}


ngx_int_t
ngx_parse_time(ngx_str_t *line, ngx_int_t sec)
{
    size_t      len;
    u_char     *start, last;
    ngx_int_t   value, total, scale;
    ngx_uint_t  max, i;
    enum {
        st_start = 0,
        st_year,
        st_month,
        st_week,
        st_day,
        st_hour,
        st_min,
        st_sec,
        st_msec,
        st_last
    } step;


    start = line->data;
    len = 0;
    total = 0;
    step = sec ? st_start : st_month;

    for (i = 0; /* void */ ; i++) {

        if (i < line->len) {
            if (line->data[i] != ' ') {
                len++;
                continue;
            }

            if (line->data[i] == ' ' && len == 0) {
                start = &line->data[i + 1];
                continue;
            }
        }

        if (len == 0) {
            break;
        }

        last = line->data[i - 1];

        switch (last) {
        case 'y':
            if (step > st_start) {
                return NGX_ERROR;
            }
            step = st_year;
            len--;
            max = 68;
            scale = 60 * 60 * 24 * 365;
            break;

        case 'M':
            if (step > st_year) {
                return NGX_ERROR;
            }
            step = st_month;
            len--;
            max = 828;
            scale = 60 * 60 * 24 * 30;
            break;

        case 'w':
            if (step > st_month) {
                return NGX_ERROR;
            }
            step = st_week;
            len--;
            max = 3550;
            scale = 60 * 60 * 24 * 7;
            break;

        case 'd':
            if (step > st_week) {
                return NGX_ERROR;
            }
            step = st_day;
            len--;
            max = 24855;
            scale = 60 * 60 * 24;
            break;

        case 'h':
            if (step > st_day) {
                return NGX_ERROR;
            }
            step = st_hour;
            len--;
            max = 596523;
            scale = 60 * 60;
            break;

        case 'm':
            if (step > st_hour) {
                return NGX_ERROR;
            }
            step = st_min;
            len--;
            max = 35791394;
            scale = 60;
            break;

        case 's':
            len--;

            if (line->data[i - 2] == 'm') {
                if (sec || step > st_sec) {
                    return NGX_ERROR;
                }
                step = st_msec;
                len--;
                max = 2147483647;
                scale = 1;
                break;
            }

            if (step > st_min) {
                return NGX_ERROR;
            }

            step = st_sec;
            max = 2147483647;
            scale = 1;
            break;

        default:
            step = st_last;
            max = 2147483647;
            scale = 1;
        }

        value = ngx_atoi(start, len);
        if (value == NGX_ERROR) {
            return NGX_ERROR;
        }

        if (step != st_msec && !sec) {
            scale *= 1000;
            max /= 1000;
        }

        if ((u_int) value > max) {
            return NGX_PARSE_LARGE_TIME;
        }

        total += value * scale;

        if ((u_int) total > 2147483647) {
            return NGX_PARSE_LARGE_TIME;
        }

        if (i >= line->len) {
            break;
        }

        len = 0;
        start = &line->data[i + 1];
    }

    return total;
}