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 11 static void nxt_http_request_send_error_body(nxt_task_t *task, void *r, 12 void *data); 13 14 15 static const nxt_http_request_state_t nxt_http_request_send_error_body_state; 16 17 18 static const char error[] = 19 "<html><head><title>Error</title></head>" 20 "<body>Error.</body></html>\r\n"; 21 22 23 void 24 nxt_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 || r->error) { 32 goto fail; 33 } 34 35 r->error = (status == NXT_HTTP_INTERNAL_SERVER_ERROR); 36 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->resp.fields == 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 = nxt_length(error); 53 54 r->state = &nxt_http_request_send_error_body_state; 55 56 nxt_http_request_header_send(task, r, nxt_http_request_send_error_body); 57 58 return; 59 60 fail: 61 62 nxt_http_request_error_handler(task, r, r->proto.any); 63 } 64 65 66 static const nxt_http_request_state_t nxt_http_request_send_error_body_state 67 nxt_aligned(64) = 68 { 69 .error_handler = nxt_http_request_error_handler, 70 }; 71 72 73 static void 74 nxt_http_request_send_error_body(nxt_task_t *task, void *obj, void *data) 75 { 76 nxt_buf_t *out; 77 nxt_http_request_t *r; 78 79 r = obj; 80 81 nxt_debug(task, "http request send error body"); 82 83 out = nxt_http_buf_mem(task, r, 0); 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 + nxt_length(error); 91 out->mem.end = out->mem.free; 92 93 out->next = nxt_http_buf_last(r); 94 95 nxt_http_request_send(task, r, out); 96 97 return; 98 99 fail: 100 101 nxt_http_request_error_handler(task, r, r->proto.any); 102 } 103