comparison src/http/modules/proxy/ngx_http_proxy_parse.c @ 0:f0b350454894 NGINX_0_1_0

nginx 0.1.0 *) The first public version.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Oct 2004 00:00:00 +0400
parents
children cc9f381affaa
comparison
equal deleted inserted replaced
-1:000000000000 0:f0b350454894
1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_http.h>
10 #include <ngx_http_proxy_handler.h>
11
12
13 int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p)
14 {
15 u_char ch;
16 u_char *pos;
17 enum {
18 sw_start = 0,
19 sw_H,
20 sw_HT,
21 sw_HTT,
22 sw_HTTP,
23 sw_first_major_digit,
24 sw_major_digit,
25 sw_first_minor_digit,
26 sw_minor_digit,
27 sw_status,
28 sw_space_after_status,
29 sw_status_text,
30 sw_almost_done,
31 sw_done
32 } state;
33
34 state = p->parse_state;
35 pos = p->header_in->pos;
36
37 while (pos < p->header_in->last && state < sw_done) {
38 ch = *pos++;
39
40 switch (state) {
41
42 /* "HTTP/" */
43 case sw_start:
44 switch (ch) {
45 case 'H':
46 state = sw_H;
47 break;
48 default:
49 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
50 }
51 break;
52
53 case sw_H:
54 switch (ch) {
55 case 'T':
56 state = sw_HT;
57 break;
58 default:
59 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
60 }
61 break;
62
63 case sw_HT:
64 switch (ch) {
65 case 'T':
66 state = sw_HTT;
67 break;
68 default:
69 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
70 }
71 break;
72
73 case sw_HTT:
74 switch (ch) {
75 case 'P':
76 state = sw_HTTP;
77 break;
78 default:
79 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
80 }
81 break;
82
83 case sw_HTTP:
84 switch (ch) {
85 case '/':
86 state = sw_first_major_digit;
87 break;
88 default:
89 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
90 }
91 break;
92
93 /* the first digit of major HTTP version */
94 case sw_first_major_digit:
95 if (ch < '1' || ch > '9') {
96 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
97 }
98
99 state = sw_major_digit;
100 break;
101
102 /* the major HTTP version or dot */
103 case sw_major_digit:
104 if (ch == '.') {
105 state = sw_first_minor_digit;
106 break;
107 }
108
109 if (ch < '0' || ch > '9') {
110 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
111 }
112
113 break;
114
115 /* the first digit of minor HTTP version */
116 case sw_first_minor_digit:
117 if (ch < '0' || ch > '9') {
118 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
119 }
120
121 state = sw_minor_digit;
122 break;
123
124 /* the minor HTTP version or the end of the request line */
125 case sw_minor_digit:
126 if (ch == ' ') {
127 state = sw_status;
128 break;
129 }
130
131 if (ch < '0' || ch > '9') {
132 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
133 }
134
135 break;
136
137 /* HTTP status code */
138 case sw_status:
139 if (ch < '0' || ch > '9') {
140 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
141 }
142
143 p->status = p->status * 10 + ch - '0';
144
145 if (++p->status_count == 3) {
146 state = sw_space_after_status;
147 p->status_start = pos - 3;
148 }
149
150 break;
151
152 /* space or end of line */
153 case sw_space_after_status:
154 switch (ch) {
155 case ' ':
156 state = sw_status_text;
157 break;
158 case CR:
159 state = sw_almost_done;
160 break;
161 case LF:
162 state = sw_done;
163 break;
164 default:
165 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
166 }
167 break;
168
169 /* any text until end of line */
170 case sw_status_text:
171 switch (ch) {
172 case CR:
173 state = sw_almost_done;
174
175 break;
176 case LF:
177 state = sw_done;
178 break;
179 }
180 break;
181
182 /* end of request line */
183 case sw_almost_done:
184 p->status_end = pos - 2;
185 switch (ch) {
186 case LF:
187 state = sw_done;
188 break;
189 default:
190 return NGX_HTTP_PROXY_PARSE_NO_HEADER;
191 }
192 break;
193
194 /* suppress warning */
195 case sw_done:
196 break;
197 }
198 }
199
200 p->header_in->pos = pos;
201
202 if (state == sw_done) {
203 if (p->status_end == NULL) {
204 p->status_end = pos - 1;
205 }
206
207 p->parse_state = sw_start;
208 return NGX_OK;
209 }
210
211 p->parse_state = state;
212 return NGX_AGAIN;
213 }