| 2252 | } |
| 2253 | |
| 2254 | static int |
| 2255 | http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { |
| 2256 | assert(u->field_set & (1 << UF_HOST)); |
| 2257 | enum http_host_state s; |
| 2258 | |
| 2259 | const char *p; |
| 2260 | size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; |
| 2261 | |
| 2262 | u->field_data[UF_HOST].len = 0; |
| 2263 | |
| 2264 | s = found_at ? s_http_userinfo_start : s_http_host_start; |
| 2265 | |
| 2266 | for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { |
| 2267 | enum http_host_state new_s = http_parse_host_char(s, *p); |
| 2268 | |
| 2269 | if (new_s == s_http_host_dead) { |
| 2270 | return 1; |
| 2271 | } |
| 2272 | |
| 2273 | switch(new_s) { |
| 2274 | case s_http_host: |
| 2275 | if (s != s_http_host) { |
| 2276 | u->field_data[UF_HOST].off = p - buf; |
| 2277 | } |
| 2278 | u->field_data[UF_HOST].len++; |
| 2279 | break; |
| 2280 | |
| 2281 | case s_http_host_v6: |
| 2282 | if (s != s_http_host_v6) { |
| 2283 | u->field_data[UF_HOST].off = p - buf; |
| 2284 | } |
| 2285 | u->field_data[UF_HOST].len++; |
| 2286 | break; |
| 2287 | |
| 2288 | case s_http_host_v6_zone_start: |
| 2289 | case s_http_host_v6_zone: |
| 2290 | u->field_data[UF_HOST].len++; |
| 2291 | break; |
| 2292 | |
| 2293 | case s_http_host_port: |
| 2294 | if (s != s_http_host_port) { |
| 2295 | u->field_data[UF_PORT].off = p - buf; |
| 2296 | u->field_data[UF_PORT].len = 0; |
| 2297 | u->field_set |= (1 << UF_PORT); |
| 2298 | } |
| 2299 | u->field_data[UF_PORT].len++; |
| 2300 | break; |
| 2301 | |
| 2302 | case s_http_userinfo: |
| 2303 | if (s != s_http_userinfo) { |
| 2304 | u->field_data[UF_USERINFO].off = p - buf ; |
| 2305 | u->field_data[UF_USERINFO].len = 0; |
| 2306 | u->field_set |= (1 << UF_USERINFO); |
| 2307 | } |
| 2308 | u->field_data[UF_USERINFO].len++; |
| 2309 | break; |
| 2310 | |
| 2311 | default: |
no test coverage detected