Mercurial > hg > nginx-quic
comparison src/http/ngx_http_event.c @ 66:4876cd4a36bb
nginx-0.0.1-2003-03-05-20:30:51 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 05 Mar 2003 17:30:51 +0000 |
parents | 4222c496acb3 |
children | 5a7d1aaa1618 |
comparison
equal
deleted
inserted
replaced
65:4222c496acb3 | 66:4876cd4a36bb |
---|---|
240 } | 240 } |
241 | 241 |
242 r->header_in->last.mem += n; | 242 r->header_in->last.mem += n; |
243 } | 243 } |
244 | 244 |
245 /* state_handlers are called in following order: | 245 /* the state_handlers are called in the following order: |
246 ngx_http_process_request_line(r) | 246 ngx_http_process_request_line(r) |
247 ngx_http_process_request_headers(r) */ | 247 ngx_http_process_request_headers(r) */ |
248 | 248 |
249 do { | 249 do { |
250 /* state_handlers return NGX_OK when whole header done */ | 250 /* state_handlers return NGX_OK when the whole header done */ |
251 rc = (r->state_handler)(r); | 251 rc = (r->state_handler)(r); |
252 | 252 |
253 if (rc == NGX_ERROR) | 253 if (rc == NGX_ERROR) |
254 return rc; | 254 return rc; |
255 | 255 |
295 ngx_connection_t *c; | 295 ngx_connection_t *c; |
296 ngx_http_log_ctx_t *ctx; | 296 ngx_http_log_ctx_t *ctx; |
297 | 297 |
298 rc = ngx_read_http_request_line(r); | 298 rc = ngx_read_http_request_line(r); |
299 | 299 |
300 /* If it's a pipelined request and a request line is not complete | |
301 then we need to copy it to the start of r->header_in hunk. | |
302 We need to copy it here only if the large client headers are enabled | |
303 otherwise a request line had already copied to start | |
304 of r->header_in hunk in ngx_http_set_keepalive() */ | |
305 | |
306 if (ngx_http_large_client_header | |
307 && rc == NGX_AGAIN | |
308 && r->header_in->last.mem == r->header_in->end) | |
309 { | |
310 offset = r->request_start - r->header_in->start; | |
311 | |
312 if (offset == 0) { | |
313 return ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, | |
314 NGX_HTTP_REQUEST_URI_TOO_LARGE); | |
315 } | |
316 | |
317 ngx_memcpy(r->header_in->start, r->request_start, | |
318 r->header_in->last.mem - r->request_start); | |
319 | |
320 r->header_in->pos.mem -= offset; | |
321 r->header_in->last.mem -= offset; | |
322 r->request_start = r->header_in->start; | |
323 r->request_end -= offset; | |
324 r->uri_start -= offset; | |
325 r->uri_end -= offset; | |
326 if (r->uri_ext) { | |
327 r->uri_ext -= offset; | |
328 } | |
329 if (r->args_start) { | |
330 r->args_start -= offset; | |
331 } | |
332 } | |
333 | |
334 c = r->connection; | 300 c = r->connection; |
335 | 301 |
302 /* a request line has been parsed successfully */ | |
336 if (rc == NGX_OK) { | 303 if (rc == NGX_OK) { |
337 /* copy URI */ | 304 /* copy URI */ |
338 r->uri.len = (r->args_start ? r->args_start - 1 : r->uri_end) | 305 r->uri.len = (r->args_start ? r->args_start - 1 : r->uri_end) |
339 - r->uri_start; | 306 - r->uri_start; |
340 ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1), | 307 ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1), |
341 ngx_http_close_request(r)); | 308 ngx_http_close_request(r)); |
342 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); | 309 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); |
343 | 310 |
344 /* if large client headers is supported then | 311 /* if the large client headers is enabled then |
345 we need to copy request line */ | 312 we need to copy a request line */ |
346 | 313 |
347 r->request_line.len = r->request_end - r->request_start; | 314 r->request_line.len = r->request_end - r->request_start; |
348 if (ngx_http_large_client_header) { | 315 if (ngx_http_large_client_header) { |
349 ngx_test_null(r->request_line.data, | 316 ngx_test_null(r->request_line.data, |
350 ngx_palloc(r->pool, r->request_line.len + 1), | 317 ngx_palloc(r->pool, r->request_line.len + 1), |
385 ngx_palloc(r->pool, r->uri_end - r->uri_start + 1), | 352 ngx_palloc(r->pool, r->uri_end - r->uri_start + 1), |
386 ngx_http_close_request(r)); | 353 ngx_http_close_request(r)); |
387 ngx_cpystrn(ctx->url, r->uri_start, r->uri_end - r->uri_start + 1); | 354 ngx_cpystrn(ctx->url, r->uri_start, r->uri_end - r->uri_start + 1); |
388 } | 355 } |
389 | 356 |
390 if (r->http_version == NGX_HTTP_VERSION_9) | 357 /* if we need to parse the headers then return NGX_AGAIN |
358 becuase of HTTP/0.9 has no headers so return NGX_OK */ | |
359 | |
360 if (r->http_version == NGX_HTTP_VERSION_9) { | |
361 r->state_handler = NULL; | |
391 return NGX_OK; | 362 return NGX_OK; |
363 } | |
392 | 364 |
393 r->headers_in.headers = ngx_create_table(r->pool, 10); | 365 r->headers_in.headers = ngx_create_table(r->pool, 10); |
394 | 366 |
395 r->state_handler = ngx_http_process_request_headers; | 367 r->state_handler = ngx_http_process_request_headers; |
396 ctx->action = "reading client request headers"; | 368 ctx->action = "reading client request headers"; |
397 | 369 |
398 return NGX_AGAIN; | 370 return NGX_AGAIN; |
399 } | 371 |
372 /* there was error while a request line parsing */ | |
373 } else if (rc != NGX_AGAIN) { | |
374 return ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); | |
375 } | |
376 | |
377 /* NGX_AGAIN: a request line parsing is still not complete */ | |
400 | 378 |
401 if (r->header_in->last.mem == r->header_in->end) { | 379 if (r->header_in->last.mem == r->header_in->end) { |
402 return ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI, | 380 |
403 NGX_HTTP_REQUEST_URI_TOO_LARGE); | 381 /* If it's a pipelined request and a request line is not complete |
404 | 382 then we need to copy it to the start of r->header_in hunk. |
405 } else if (rc == NGX_AGAIN) { | 383 We need to copy it here only if the large client header |
406 return NGX_AGAIN; | 384 is enabled otherwise a request line had been already copied |
407 } | 385 to the start of r->header_in hunk in ngx_http_set_keepalive() */ |
408 | 386 |
409 return ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); | 387 if (ngx_http_large_client_header) { |
388 offset = r->request_start - r->header_in->start; | |
389 | |
390 if (offset == 0) { | |
391 return ngx_http_header_parse_error(r, | |
392 NGX_HTTP_PARSE_TOO_LONG_URI, | |
393 NGX_HTTP_REQUEST_URI_TOO_LARGE); | |
394 } | |
395 | |
396 ngx_memcpy(r->header_in->start, r->request_start, | |
397 r->header_in->last.mem - r->request_start); | |
398 | |
399 r->header_in->pos.mem -= offset; | |
400 r->header_in->last.mem -= offset; | |
401 r->request_start = r->header_in->start; | |
402 r->request_end -= offset; | |
403 r->uri_start -= offset; | |
404 r->uri_end -= offset; | |
405 if (r->uri_ext) { | |
406 r->uri_ext -= offset; | |
407 } | |
408 if (r->args_start) { | |
409 r->args_start -= offset; | |
410 } | |
411 | |
412 } else { | |
413 return ngx_http_header_parse_error(r, | |
414 NGX_HTTP_PARSE_TOO_LONG_URI, | |
415 NGX_HTTP_REQUEST_URI_TOO_LARGE); | |
416 } | |
417 } | |
418 | |
419 return NGX_AGAIN; | |
410 } | 420 } |
411 | 421 |
412 | 422 |
413 static int ngx_http_process_request_headers(ngx_http_request_t *r) | 423 static int ngx_http_process_request_headers(ngx_http_request_t *r) |
414 { | 424 { |
417 ngx_http_log_ctx_t *ctx; | 427 ngx_http_log_ctx_t *ctx; |
418 | 428 |
419 for ( ;; ) { | 429 for ( ;; ) { |
420 rc = ngx_read_http_header_line(r, r->header_in); | 430 rc = ngx_read_http_header_line(r, r->header_in); |
421 | 431 |
422 /* if large client header is supported then | 432 /* a header line has been parsed successfully */ |
423 we need to compact r->header_in hunk */ | 433 if (rc == NGX_OK) { |
424 | |
425 if (ngx_http_large_client_header | |
426 && rc == NGX_AGAIN | |
427 && r->header_in->pos.mem == r->header_in->end) | |
428 { | |
429 offset = r->header_name_start - r->header_in->start; | |
430 | |
431 if (offset == 0) { | |
432 return ngx_http_header_parse_error(r, | |
433 NGX_HTTP_PARSE_TOO_LONG_HEADER, | |
434 NGX_HTTP_BAD_REQUEST); | |
435 } | |
436 | |
437 ngx_memcpy(r->header_in->start, r->header_name_start, | |
438 r->header_in->last.mem - r->header_name_start); | |
439 | |
440 r->header_in->last.mem -= offset; | |
441 r->header_in->pos.mem -= offset; | |
442 r->header_name_start = r->header_in->start; | |
443 r->header_name_end -= offset; | |
444 r->header_start -= offset; | |
445 r->header_end -= offset; | |
446 } | |
447 | |
448 if (rc == NGX_OK) { /* header line is ready */ | |
449 if (ngx_http_process_request_header_line(r) == NGX_ERROR) { | 434 if (ngx_http_process_request_header_line(r) == NGX_ERROR) { |
450 return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 435 return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
451 } | 436 } |
452 | 437 |
453 return NGX_AGAIN; | 438 return NGX_AGAIN; |
454 | 439 |
440 /* the whole header has been parsed successfully */ | |
455 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { | 441 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { |
456 ngx_log_debug(r->connection->log, "HTTP header done"); | 442 ngx_log_debug(r->connection->log, "HTTP header done"); |
457 | 443 |
458 if (r->headers_in.host) { | 444 if (r->headers_in.host) { |
459 for (len = 0; len < r->headers_in.host->value.len; len++) { | 445 for (len = 0; len < r->headers_in.host->value.len; len++) { |
470 NGX_HTTP_BAD_REQUEST); | 456 NGX_HTTP_BAD_REQUEST); |
471 } | 457 } |
472 r->headers_in.host_name_len = 0; | 458 r->headers_in.host_name_len = 0; |
473 } | 459 } |
474 | 460 |
461 r->state_handler = NULL; | |
475 return NGX_OK; | 462 return NGX_OK; |
476 | 463 |
477 } else if (!ngx_http_large_client_header | 464 /* there was error while a header line parsing */ |
478 && r->header_in->last.mem == r->header_in->end) { | 465 } else if (rc != NGX_AGAIN) { |
479 return ngx_http_header_parse_error(r, | 466 return ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST); |
467 } | |
468 | |
469 /* NGX_AGAIN: a header line parsing is still not complete */ | |
470 | |
471 if (r->header_in->last.mem == r->header_in->end) { | |
472 | |
473 /* if the large client header is enabled then | |
474 we need to compact r->header_in hunk */ | |
475 | |
476 if (ngx_http_large_client_header) { | |
477 offset = r->header_name_start - r->header_in->start; | |
478 | |
479 if (offset == 0) { | |
480 return ngx_http_header_parse_error(r, | |
481 NGX_HTTP_PARSE_TOO_LONG_HEADER, | |
482 NGX_HTTP_BAD_REQUEST); | |
483 } | |
484 | |
485 ngx_memcpy(r->header_in->start, r->header_name_start, | |
486 r->header_in->last.mem - r->header_name_start); | |
487 | |
488 r->header_in->last.mem -= offset; | |
489 r->header_in->pos.mem -= offset; | |
490 r->header_name_start = r->header_in->start; | |
491 r->header_name_end -= offset; | |
492 r->header_start -= offset; | |
493 r->header_end -= offset; | |
494 | |
495 } else { | |
496 return ngx_http_header_parse_error(r, | |
480 NGX_HTTP_PARSE_TOO_LONG_HEADER, | 497 NGX_HTTP_PARSE_TOO_LONG_HEADER, |
481 NGX_HTTP_BAD_REQUEST); | 498 NGX_HTTP_BAD_REQUEST); |
482 | 499 } |
483 } else if (rc == NGX_AGAIN) { | 500 |
484 return NGX_AGAIN; | 501 } |
485 } | 502 |
503 return NGX_AGAIN; | |
486 } | 504 } |
487 } | 505 } |
488 | 506 |
489 | 507 |
490 static int ngx_http_process_request_header_line(ngx_http_request_t *r) | 508 static int ngx_http_process_request_header_line(ngx_http_request_t *r) |
492 int i; | 510 int i; |
493 ngx_table_elt_t *h; | 511 ngx_table_elt_t *h; |
494 | 512 |
495 ngx_test_null(h, ngx_push_table(r->headers_in.headers), NGX_ERROR); | 513 ngx_test_null(h, ngx_push_table(r->headers_in.headers), NGX_ERROR); |
496 | 514 |
497 /* if large client headers is supported then | 515 /* if large client header is enabled then |
498 we need to copy header name and value */ | 516 we need to copy header name and value */ |
499 | 517 |
500 h->key.len = r->header_name_end - r->header_name_start; | 518 h->key.len = r->header_name_end - r->header_name_start; |
501 h->value.len = r->header_end - r->header_start; | 519 h->value.len = r->header_end - r->header_start; |
502 | 520 |
546 if (rev->timer_set) { | 564 if (rev->timer_set) { |
547 ngx_del_timer(rev); | 565 ngx_del_timer(rev); |
548 rev->timer_set = 0; | 566 rev->timer_set = 0; |
549 } | 567 } |
550 | 568 |
551 r->state_handler = NULL; | |
552 rev->event_handler = ngx_http_block_read; | 569 rev->event_handler = ngx_http_block_read; |
553 | 570 |
554 ctx = r->connection->log->data; | 571 ctx = r->connection->log->data; |
555 ctx->action = "processing client request"; | 572 ctx->action = "processing client request"; |
556 | 573 |
838 h = c->buffer; | 855 h = c->buffer; |
839 | 856 |
840 /* pipelined request */ | 857 /* pipelined request */ |
841 if (h->pos.mem < h->last.mem) { | 858 if (h->pos.mem < h->last.mem) { |
842 | 859 |
843 /* clients that support pipelined requests (Mozilla 1.x, Opera 6.x) | 860 /* We do not know here whether pipelined request is complete |
844 are rare now so this copy should also be rare */ | 861 so we need to copy it to the start of c->buffer if the large |
862 client header is not enabled. This copy should be rare | |
863 because clients that support pipelined requests (Mozilla 1.x, | |
864 Opera 6.x) are still rare */ | |
845 | 865 |
846 if (!ngx_http_large_client_header) { | 866 if (!ngx_http_large_client_header) { |
847 len = h->last.mem - h->pos.mem; | 867 len = h->last.mem - h->pos.mem; |
848 ngx_memcpy(h->start, h->pos.mem, len); | 868 ngx_memcpy(h->start, h->pos.mem, len); |
849 h->pos.mem = h->start; | 869 h->pos.mem = h->start; |