xref: /unit/src/nxt_http_error.c (revision 431:5817734dd9b9)
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