xref: /unit/src/nxt_http_error.c (revision 1127:e60606d72d6b)
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     nxt_http_request_header_send(task, r);
55 
56     r->state = &nxt_http_request_send_error_body_state;
57 
58     nxt_work_queue_add(&task->thread->engine->fast_work_queue,
59                        nxt_http_request_send_error_body, task, r, NULL);
60     return;
61 
62 fail:
63 
64     nxt_http_request_error_handler(task, r, r->proto.any);
65 }
66 
67 
68 static const nxt_http_request_state_t  nxt_http_request_send_error_body_state
69     nxt_aligned(64) =
70 {
71     .error_handler = nxt_http_request_error_handler,
72 };
73 
74 
75 static void
76 nxt_http_request_send_error_body(nxt_task_t *task, void *obj, void *data)
77 {
78     nxt_buf_t           *out;
79     nxt_http_request_t  *r;
80 
81     r = obj;
82 
83     nxt_debug(task, "http request send error body");
84 
85     out = nxt_http_buf_mem(task, r, 0);
86     if (nxt_slow_path(out == NULL)) {
87         goto fail;
88     }
89 
90     out->mem.start = (u_char *) error;
91     out->mem.pos = out->mem.start;
92     out->mem.free = out->mem.start + nxt_length(error);
93     out->mem.end = out->mem.free;
94 
95     out->next = nxt_http_buf_last(r);
96 
97     nxt_http_request_send(task, r, out);
98 
99     return;
100 
101 fail:
102 
103     nxt_http_request_error_handler(task, r, r->proto.any);
104 }
105