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;