view src/core/ngx_parse.c @ 647:95d7da23ea53 release-0.3.45

nginx-0.3.45-RELEASE import *) 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 and 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 <igor@sysoev.ru>
date Sat, 06 May 2006 16:28:56 +0000
parents 9c2f3ed7a247
children 39b7d7b33c91
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;
}