ngx_http_parse_status_line()
This commit is contained in:
parent
cff6dbbb59
commit
b509ddb93d
2 changed files with 215 additions and 0 deletions
|
@ -51,6 +51,14 @@ struct ngx_http_log_ctx_s {
|
|||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t code;
|
||||
ngx_uint_t count;
|
||||
u_char *start;
|
||||
u_char *end;
|
||||
} ngx_http_status_t;
|
||||
|
||||
|
||||
#define ngx_http_get_module_ctx(r, module) (r)->ctx[module.ctx_index]
|
||||
#define ngx_http_set_ctx(r, c, module) r->ctx[module.ctx_index] = c;
|
||||
|
||||
|
@ -70,6 +78,8 @@ int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
|
|||
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);
|
||||
ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r,
|
||||
ngx_uint_t merge_slashes);
|
||||
ngx_int_t ngx_http_parse_status_line(ngx_http_request_t *r, ngx_buf_t *b,
|
||||
ngx_http_status_t *status);
|
||||
ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
ngx_str_t *args, ngx_uint_t *flags);
|
||||
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
|
||||
|
|
|
@ -1317,6 +1317,211 @@ args:
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_status_line(ngx_http_request_t *r, ngx_buf_t *b,
|
||||
ngx_http_status_t *status)
|
||||
{
|
||||
u_char ch;
|
||||
u_char *p;
|
||||
enum {
|
||||
sw_start = 0,
|
||||
sw_H,
|
||||
sw_HT,
|
||||
sw_HTT,
|
||||
sw_HTTP,
|
||||
sw_first_major_digit,
|
||||
sw_major_digit,
|
||||
sw_first_minor_digit,
|
||||
sw_minor_digit,
|
||||
sw_status,
|
||||
sw_space_after_status,
|
||||
sw_status_text,
|
||||
sw_almost_done
|
||||
} state;
|
||||
|
||||
state = r->state;
|
||||
|
||||
for (p = b->pos; p < b->last; p++) {
|
||||
ch = *p;
|
||||
|
||||
switch (state) {
|
||||
|
||||
/* "HTTP/" */
|
||||
case sw_start:
|
||||
switch (ch) {
|
||||
case 'H':
|
||||
state = sw_H;
|
||||
break;
|
||||
default:
|
||||
return NGX_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case sw_H:
|
||||
switch (ch) {
|
||||
case 'T':
|
||||
state = sw_HT;
|
||||
break;
|
||||
default:
|
||||
return NGX_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case sw_HT:
|
||||
switch (ch) {
|
||||
case 'T':
|
||||
state = sw_HTT;
|
||||
break;
|
||||
default:
|
||||
return NGX_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case sw_HTT:
|
||||
switch (ch) {
|
||||
case 'P':
|
||||
state = sw_HTTP;
|
||||
break;
|
||||
default:
|
||||
return NGX_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case sw_HTTP:
|
||||
switch (ch) {
|
||||
case '/':
|
||||
state = sw_first_major_digit;
|
||||
break;
|
||||
default:
|
||||
return NGX_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
/* the first digit of major HTTP version */
|
||||
case sw_first_major_digit:
|
||||
if (ch < '1' || ch > '9') {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
state = sw_major_digit;
|
||||
break;
|
||||
|
||||
/* the major HTTP version or dot */
|
||||
case sw_major_digit:
|
||||
if (ch == '.') {
|
||||
state = sw_first_minor_digit;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch < '0' || ch > '9') {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* the first digit of minor HTTP version */
|
||||
case sw_first_minor_digit:
|
||||
if (ch < '0' || ch > '9') {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
state = sw_minor_digit;
|
||||
break;
|
||||
|
||||
/* the minor HTTP version or the end of the request line */
|
||||
case sw_minor_digit:
|
||||
if (ch == ' ') {
|
||||
state = sw_status;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch < '0' || ch > '9') {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* HTTP status code */
|
||||
case sw_status:
|
||||
if (ch == ' ') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch < '0' || ch > '9') {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
status->code = status->code * 10 + ch - '0';
|
||||
|
||||
if (++status->count == 3) {
|
||||
state = sw_space_after_status;
|
||||
status->start = p - 2;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* space or end of line */
|
||||
case sw_space_after_status:
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
state = sw_status_text;
|
||||
break;
|
||||
case '.': /* IIS may send 403.1, 403.2, etc */
|
||||
state = sw_status_text;
|
||||
break;
|
||||
case CR:
|
||||
state = sw_almost_done;
|
||||
break;
|
||||
case LF:
|
||||
goto done;
|
||||
default:
|
||||
return NGX_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
/* any text until end of line */
|
||||
case sw_status_text:
|
||||
switch (ch) {
|
||||
case CR:
|
||||
state = sw_almost_done;
|
||||
|
||||
break;
|
||||
case LF:
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
/* end of status line */
|
||||
case sw_almost_done:
|
||||
status->end = p - 1;
|
||||
switch (ch) {
|
||||
case LF:
|
||||
goto done;
|
||||
default:
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b->pos = p;
|
||||
r->state = state;
|
||||
|
||||
return NGX_AGAIN;
|
||||
|
||||
done:
|
||||
|
||||
b->pos = p + 1;
|
||||
|
||||
if (status->end == NULL) {
|
||||
status->end = p;
|
||||
}
|
||||
|
||||
r->state = sw_start;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
ngx_str_t *args, ngx_uint_t *flags)
|
||||
|
|
Loading…
Reference in a new issue