xref: /unit/src/nxt_http_error.c (revision 1148:f93deb2432da)
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