1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_router.h> 8#include <nxt_http.h> 9 10 11static void nxt_http_request_send_error_body(nxt_task_t *task, void *r, 12 void *data); 13 14
| 1 2/* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7#include <nxt_router.h> 8#include <nxt_http.h> 9 10 11static void nxt_http_request_send_error_body(nxt_task_t *task, void *r, 12 void *data); 13 14
|
15static const nxt_http_request_state_t nxt_http_request_send_state;
| 15static const nxt_http_request_state_t nxt_http_request_send_error_body_state;
|
16 17 18static const char error[] = 19 "<html><head><title>Error</title><head>" 20 "<body>Error.</body></html>\r\n"; 21 22 23void 24nxt_http_request_error(nxt_task_t *task, nxt_http_request_t *r, 25 nxt_http_status_t status) 26{ 27 nxt_http_field_t *content_type; 28 29 nxt_debug(task, "http request error: %d", status); 30
| 16 17 18static const char error[] = 19 "<html><head><title>Error</title><head>" 20 "<body>Error.</body></html>\r\n"; 21 22 23void 24nxt_http_request_error(nxt_task_t *task, nxt_http_request_t *r, 25 nxt_http_status_t status) 26{ 27 nxt_http_field_t *content_type; 28 29 nxt_debug(task, "http request error: %d", status); 30
|
31 if (r->header_sent) {
| 31 if (r->header_sent || r->error) {
|
32 goto fail; 33 } 34
| 32 goto fail; 33 } 34
|
| 35 r->error = (status == NXT_HTTP_INTERNAL_SERVER_ERROR); 36
|
35 r->status = status; 36 37 r->resp.fields = nxt_list_create(r->mem_pool, 8, sizeof(nxt_http_field_t)); 38 if (nxt_slow_path(r == NULL)) { 39 goto fail; 40 } 41 42 content_type = nxt_list_zero_add(r->resp.fields); 43 if (nxt_slow_path(content_type == NULL)) { 44 goto fail; 45 } 46 47 nxt_http_field_set(content_type, "Content-Type", "text/html"); 48 49 r->resp.content_length = NULL; 50 r->resp.content_length_n = sizeof(error) - 1; 51
| 37 r->status = status; 38 39 r->resp.fields = nxt_list_create(r->mem_pool, 8, sizeof(nxt_http_field_t)); 40 if (nxt_slow_path(r == NULL)) { 41 goto fail; 42 } 43 44 content_type = nxt_list_zero_add(r->resp.fields); 45 if (nxt_slow_path(content_type == NULL)) { 46 goto fail; 47 } 48 49 nxt_http_field_set(content_type, "Content-Type", "text/html"); 50 51 r->resp.content_length = NULL; 52 r->resp.content_length_n = sizeof(error) - 1; 53
|
52 r->state = &nxt_http_request_send_state;
| 54 r->state = &nxt_http_request_send_error_body_state;
|
53 54 nxt_http_request_header_send(task, r); 55 return; 56 57fail: 58
| 55 56 nxt_http_request_header_send(task, r); 57 return; 58 59fail: 60
|
59 nxt_http_request_release(task, r);
| 61 nxt_http_request_error_handler(task, r, r->proto.any);
|
60} 61 62
| 62} 63 64
|
63static const nxt_http_request_state_t nxt_http_request_send_state
| 65static const nxt_http_request_state_t nxt_http_request_send_error_body_state
|
64 nxt_aligned(64) = 65{ 66 .ready_handler = nxt_http_request_send_error_body,
| 66 nxt_aligned(64) = 67{ 68 .ready_handler = nxt_http_request_send_error_body,
|
67 .error_handler = nxt_http_request_close_handler,
| 69 .error_handler = nxt_http_request_error_handler,
|
68}; 69 70 71static void 72nxt_http_request_send_error_body(nxt_task_t *task, void *obj, void *data) 73{
| 70}; 71 72 73static void 74nxt_http_request_send_error_body(nxt_task_t *task, void *obj, void *data) 75{
|
74 nxt_buf_t *out, *last;
| 76 nxt_buf_t *out;
|
75 nxt_http_request_t *r; 76 77 r = obj; 78 79 nxt_debug(task, "http request send error body"); 80
| 77 nxt_http_request_t *r; 78 79 r = obj; 80 81 nxt_debug(task, "http request send error body"); 82
|
81 out = nxt_buf_mem_alloc(r->mem_pool, 0, 0);
| 83 out = nxt_http_buf_mem(task, r, 0);
|
82 if (nxt_slow_path(out == NULL)) { 83 goto fail; 84 } 85 86 out->mem.start = (u_char *) error; 87 out->mem.pos = out->mem.start; 88 out->mem.free = out->mem.start + sizeof(error) - 1; 89 out->mem.end = out->mem.free; 90
| 84 if (nxt_slow_path(out == NULL)) { 85 goto fail; 86 } 87 88 out->mem.start = (u_char *) error; 89 out->mem.pos = out->mem.start; 90 out->mem.free = out->mem.start + sizeof(error) - 1; 91 out->mem.end = out->mem.free; 92
|
91 last = nxt_http_request_last_buffer(task, r); 92 if (nxt_slow_path(last == NULL)) { 93 goto fail; 94 }
| 93 out->next = nxt_http_buf_last(r);
|
95
| 94
|
96 out->next = last; 97
| |
98 nxt_http_request_send(task, r, out); 99 100 return; 101 102fail:
| 95 nxt_http_request_send(task, r, out); 96 97 return; 98 99fail:
|
103 // TODO 104 nxt_http_request_release(task, r);
| 100 101 nxt_http_request_error_handler(task, r, r->proto.any);
|
105}
| 102}
|