1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_router.h>
8 #include <nxt_http.h>
9 
10 
11 static nxt_int_t nxt_http_response_status(void *ctx, nxt_http_field_t *field,
12     uintptr_t data);
13 static nxt_int_t nxt_http_response_skip(void *ctx, nxt_http_field_t *field,
14     uintptr_t data);
15 static nxt_int_t nxt_http_response_field(void *ctx, nxt_http_field_t *field,
16     uintptr_t offset);
17 
18 
19 nxt_lvlhsh_t  nxt_response_fields_hash;
20 
21 static nxt_http_field_proc_t   nxt_response_fields[] = {
22     { nxt_string("Status"),         &nxt_http_response_status, 0 },
23     { nxt_string("Server"),         &nxt_http_response_skip, 0 },
24     { nxt_string("Date"),           &nxt_http_response_field,
25         offsetof(nxt_http_request_t, resp.date) },
26     { nxt_string("Connection"),     &nxt_http_response_skip, 0 },
27     { nxt_string("Content-Type"),   &nxt_http_response_field,
28         offsetof(nxt_http_request_t, resp.content_type) },
29     { nxt_string("Content-Length"), &nxt_http_response_field,
30         offsetof(nxt_http_request_t, resp.content_length) },
31     { nxt_string("Upgrade"),        &nxt_http_response_skip, 0 },
32     { nxt_string("Sec-WebSocket-Accept"), &nxt_http_response_skip, 0 },
33 };
34 
35 
36 nxt_int_t
nxt_http_response_hash_init(nxt_task_t * task)37 nxt_http_response_hash_init(nxt_task_t *task)
38 {
39     return nxt_http_fields_hash(&nxt_response_fields_hash,
40                     nxt_response_fields, nxt_nitems(nxt_response_fields));
41 }
42 
43 
44 nxt_int_t
nxt_http_response_status(void * ctx,nxt_http_field_t * field,uintptr_t data)45 nxt_http_response_status(void *ctx, nxt_http_field_t *field,
46     uintptr_t data)
47 {
48     nxt_int_t           status;
49     nxt_http_request_t  *r;
50 
51     r = ctx;
52 
53     field->skip = 1;
54 
55     if (field->value_length >= 3) {
56         status = nxt_int_parse(field->value, 3);
57 
58         if (status >= 100 && status <= 999) {
59             r->status = status;
60             return NXT_OK;
61         }
62     }
63 
64     return NXT_ERROR;
65 }
66 
67 
68 nxt_int_t
nxt_http_response_skip(void * ctx,nxt_http_field_t * field,uintptr_t data)69 nxt_http_response_skip(void *ctx, nxt_http_field_t *field, uintptr_t data)
70 {
71     field->skip = 1;
72 
73     return NXT_OK;
74 }
75 
76 
77 nxt_int_t
nxt_http_response_field(void * ctx,nxt_http_field_t * field,uintptr_t offset)78 nxt_http_response_field(void *ctx, nxt_http_field_t *field, uintptr_t offset)
79 {
80     nxt_http_request_t  *r;
81 
82     r = ctx;
83 
84     nxt_value_at(nxt_http_field_t *, r, offset) = field;
85 
86     return NXT_OK;
87 }
88