upstream nginx-0.7.36
[nginx.git] / nginx / src / http / modules / ngx_http_stub_status_module.c
1
2 /*
3  * Copyright (C) Igor Sysoev
4  */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_http.h>
10
11
12 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd,
13                                  void *conf);
14
15 static ngx_command_t  ngx_http_status_commands[] = {
16
17     { ngx_string("stub_status"),
18       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
19       ngx_http_set_status,
20       0,
21       0,
22       NULL },
23
24       ngx_null_command
25 };
26
27
28
29 static ngx_http_module_t  ngx_http_stub_status_module_ctx = {
30     NULL,                                  /* preconfiguration */
31     NULL,                                  /* postconfiguration */
32
33     NULL,                                  /* create main configuration */
34     NULL,                                  /* init main configuration */
35
36     NULL,                                  /* create server configuration */
37     NULL,                                  /* merge server configuration */
38
39     NULL,                                  /* create location configuration */
40     NULL                                   /* merge location configuration */
41 };
42
43
44 ngx_module_t  ngx_http_stub_status_module = {
45     NGX_MODULE_V1,
46     &ngx_http_stub_status_module_ctx,      /* module context */
47     ngx_http_status_commands,              /* module directives */
48     NGX_HTTP_MODULE,                       /* module type */
49     NULL,                                  /* init master */
50     NULL,                                  /* init module */
51     NULL,                                  /* init process */
52     NULL,                                  /* init thread */
53     NULL,                                  /* exit thread */
54     NULL,                                  /* exit process */
55     NULL,                                  /* exit master */
56     NGX_MODULE_V1_PADDING
57 };
58
59
60 static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
61 {
62     size_t             size;
63     ngx_int_t          rc;
64     ngx_buf_t         *b;
65     ngx_chain_t        out;
66     ngx_atomic_int_t   ap, hn, ac, rq, rd, wr;
67
68     if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
69         return NGX_HTTP_NOT_ALLOWED;
70     }
71
72     rc = ngx_http_discard_request_body(r);
73
74     if (rc != NGX_OK) {
75         return rc;
76     }
77
78     r->headers_out.content_type.len = sizeof("text/plain") - 1;
79     r->headers_out.content_type.data = (u_char *) "text/plain";
80
81     if (r->method == NGX_HTTP_HEAD) {
82         r->headers_out.status = NGX_HTTP_OK;
83
84         rc = ngx_http_send_header(r);
85
86         if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
87             return rc;
88         }
89     }
90
91     size = sizeof("Active connections:  \n") + NGX_ATOMIC_T_LEN
92            + sizeof("server accepts handled requests\n") - 1
93            + 6 + 3 * NGX_ATOMIC_T_LEN
94            + sizeof("Reading:  Writing:  Waiting:  \n") + 3 * NGX_ATOMIC_T_LEN;
95
96     b = ngx_create_temp_buf(r->pool, size);
97     if (b == NULL) {
98         return NGX_HTTP_INTERNAL_SERVER_ERROR;
99     }
100
101     out.buf = b;
102     out.next = NULL;
103
104     ap = *ngx_stat_accepted;
105     hn = *ngx_stat_handled;
106     ac = *ngx_stat_active;
107     rq = *ngx_stat_requests;
108     rd = *ngx_stat_reading;
109     wr = *ngx_stat_writing;
110
111     b->last = ngx_sprintf(b->last, "Active connections: %uA \n", ac);
112
113     b->last = ngx_cpymem(b->last, "server accepts handled requests\n",
114                          sizeof("server accepts handled requests\n") - 1);
115
116     b->last = ngx_sprintf(b->last, " %uA %uA %uA \n", ap, hn, rq);
117
118     b->last = ngx_sprintf(b->last, "Reading: %uA Writing: %uA Waiting: %uA \n",
119                           rd, wr, ac - (rd + wr));
120
121     r->headers_out.status = NGX_HTTP_OK;
122     r->headers_out.content_length_n = b->last - b->pos;
123
124     b->last_buf = 1;
125
126     rc = ngx_http_send_header(r);
127
128     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
129         return rc;
130     }
131
132     return ngx_http_output_filter(r, &out);
133 }
134
135
136 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
137 {
138     ngx_http_core_loc_conf_t  *clcf;
139
140     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
141     clcf->handler = ngx_http_status_handler;
142
143     return NGX_CONF_OK;
144 }