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_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) { 32 goto fail; 33 } 34 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 52 r->state = &nxt_http_request_send_state; 53 54 nxt_http_request_header_send(task, r); 55 return; 56 57 fail: 58 59 nxt_http_request_release(task, r); 60 } 61 62 63 static const nxt_http_request_state_t nxt_http_request_send_state 64 nxt_aligned(64) = 65 { 66 .ready_handler = nxt_http_request_send_error_body, 67 .error_handler = nxt_http_request_close_handler, 68 }; 69 70 71 static void 72 nxt_http_request_send_error_body(nxt_task_t *task, void *obj, void *data) 73 { 74 nxt_buf_t *out, *last; 75 nxt_http_request_t *r; 76 77 r = obj; 78 79 nxt_debug(task, "http request send error body"); 80 81 out = nxt_buf_mem_alloc(r->mem_pool, 0, 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 91 last = nxt_http_request_last_buffer(task, r); 92 if (nxt_slow_path(last == NULL)) { 93 goto fail; 94 } 95 96 out->next = last; 97 98 nxt_http_request_send(task, r, out); 99 100 return; 101 102 fail: 103 // TODO 104 nxt_http_request_release(task, r); 105 } 106