xref: /unit/src/nxt_http_error.c (revision 1270)
1431Sigor@sysoev.ru 
2431Sigor@sysoev.ru /*
3431Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
4431Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
5431Sigor@sysoev.ru  */
6431Sigor@sysoev.ru 
7431Sigor@sysoev.ru #include <nxt_router.h>
8431Sigor@sysoev.ru #include <nxt_http.h>
9431Sigor@sysoev.ru 
10431Sigor@sysoev.ru 
11431Sigor@sysoev.ru static void nxt_http_request_send_error_body(nxt_task_t *task, void *r,
12431Sigor@sysoev.ru     void *data);
13431Sigor@sysoev.ru 
14431Sigor@sysoev.ru 
15608Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_request_send_error_body_state;
16431Sigor@sysoev.ru 
17431Sigor@sysoev.ru 
18431Sigor@sysoev.ru static const char  error[] =
191218Svbart@nginx.com     "<!DOCTYPE html>"
201218Svbart@nginx.com     "<title>Error %03d</title>"
211218Svbart@nginx.com     "<p>Error %03d.\r\n";
221218Svbart@nginx.com 
231218Svbart@nginx.com /* Two %03d (4 chars) patterns are replaced by status code (3 chars). */
241218Svbart@nginx.com #define NXT_HTTP_ERROR_LEN  (nxt_length(error) - 2)
25431Sigor@sysoev.ru 
26431Sigor@sysoev.ru 
27431Sigor@sysoev.ru void
28431Sigor@sysoev.ru nxt_http_request_error(nxt_task_t *task, nxt_http_request_t *r,
29431Sigor@sysoev.ru     nxt_http_status_t status)
30431Sigor@sysoev.ru {
31431Sigor@sysoev.ru     nxt_http_field_t  *content_type;
32431Sigor@sysoev.ru 
33431Sigor@sysoev.ru     nxt_debug(task, "http request error: %d", status);
34431Sigor@sysoev.ru 
35608Sigor@sysoev.ru     if (r->header_sent || r->error) {
36431Sigor@sysoev.ru         goto fail;
37431Sigor@sysoev.ru     }
38431Sigor@sysoev.ru 
39608Sigor@sysoev.ru     r->error = (status == NXT_HTTP_INTERNAL_SERVER_ERROR);
40608Sigor@sysoev.ru 
41431Sigor@sysoev.ru     r->status = status;
42431Sigor@sysoev.ru 
43431Sigor@sysoev.ru     r->resp.fields = nxt_list_create(r->mem_pool, 8, sizeof(nxt_http_field_t));
44906Sigor@sysoev.ru     if (nxt_slow_path(r->resp.fields == NULL)) {
45431Sigor@sysoev.ru         goto fail;
46431Sigor@sysoev.ru     }
47431Sigor@sysoev.ru 
48431Sigor@sysoev.ru     content_type = nxt_list_zero_add(r->resp.fields);
49431Sigor@sysoev.ru     if (nxt_slow_path(content_type == NULL)) {
50431Sigor@sysoev.ru         goto fail;
51431Sigor@sysoev.ru     }
52431Sigor@sysoev.ru 
53431Sigor@sysoev.ru     nxt_http_field_set(content_type, "Content-Type", "text/html");
54431Sigor@sysoev.ru 
55431Sigor@sysoev.ru     r->resp.content_length = NULL;
561218Svbart@nginx.com     r->resp.content_length_n = NXT_HTTP_ERROR_LEN;
57431Sigor@sysoev.ru 
58608Sigor@sysoev.ru     r->state = &nxt_http_request_send_error_body_state;
59431Sigor@sysoev.ru 
60*1270Sigor@sysoev.ru     nxt_http_request_header_send(task, r,
61*1270Sigor@sysoev.ru                                  nxt_http_request_send_error_body, NULL);
62431Sigor@sysoev.ru     return;
63431Sigor@sysoev.ru 
64431Sigor@sysoev.ru fail:
65431Sigor@sysoev.ru 
66608Sigor@sysoev.ru     nxt_http_request_error_handler(task, r, r->proto.any);
67431Sigor@sysoev.ru }
68431Sigor@sysoev.ru 
69431Sigor@sysoev.ru 
70608Sigor@sysoev.ru static const nxt_http_request_state_t  nxt_http_request_send_error_body_state
71431Sigor@sysoev.ru     nxt_aligned(64) =
72431Sigor@sysoev.ru {
73608Sigor@sysoev.ru     .error_handler = nxt_http_request_error_handler,
74431Sigor@sysoev.ru };
75431Sigor@sysoev.ru 
76431Sigor@sysoev.ru 
77431Sigor@sysoev.ru static void
78431Sigor@sysoev.ru nxt_http_request_send_error_body(nxt_task_t *task, void *obj, void *data)
79431Sigor@sysoev.ru {
80608Sigor@sysoev.ru     nxt_buf_t           *out;
81431Sigor@sysoev.ru     nxt_http_request_t  *r;
82431Sigor@sysoev.ru 
83431Sigor@sysoev.ru     r = obj;
84431Sigor@sysoev.ru 
85431Sigor@sysoev.ru     nxt_debug(task, "http request send error body");
86431Sigor@sysoev.ru 
871218Svbart@nginx.com     out = nxt_http_buf_mem(task, r, NXT_HTTP_ERROR_LEN);
88431Sigor@sysoev.ru     if (nxt_slow_path(out == NULL)) {
89431Sigor@sysoev.ru         goto fail;
90431Sigor@sysoev.ru     }
91431Sigor@sysoev.ru 
921218Svbart@nginx.com     out->mem.free = nxt_sprintf(out->mem.pos, out->mem.end, error,
931218Svbart@nginx.com                                 r->status, r->status);
94431Sigor@sysoev.ru 
95608Sigor@sysoev.ru     out->next = nxt_http_buf_last(r);
96431Sigor@sysoev.ru 
97431Sigor@sysoev.ru     nxt_http_request_send(task, r, out);
98431Sigor@sysoev.ru 
99431Sigor@sysoev.ru     return;
100431Sigor@sysoev.ru 
101431Sigor@sysoev.ru fail:
102608Sigor@sysoev.ru 
103608Sigor@sysoev.ru     nxt_http_request_error_handler(task, r, r->proto.any);
104431Sigor@sysoev.ru }
105