Mercurial > hg > nginx-vendor-0-8
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 } |