Mercurial > hg > nginx
annotate src/http/modules/ngx_http_empty_gif_module.c @ 3440:88741ec7731a stable-0.7
merge r3294, r3305:
Fix a bug introduced in r2032: After a child process has read a terminate
message from a channel, the process tries to read the channel again.
The kernel (at least FreeBSD) may preempt the process and sends a SIGIO
signal to a master process. The master process sends a new terminate message,
the kernel switches again to the the child process, and the child process
reads the messages instead of an EAGAIN error. And this may repeat over
and over. Being that the child process can not exit the cycle and test
the termination flag set by the message handler.
The fix disallow the master process to send a new terminate message on
SIGIO signal reception. It may send the message only on SIGALARM signal.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 01 Feb 2010 15:49:36 +0000 |
parents | aa5e003d30bf |
children | dd1570b6f237 |
rev | line source |
---|---|
577 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 #include <ngx_config.h> | |
7 #include <ngx_core.h> | |
8 #include <ngx_http.h> | |
9 | |
10 | |
11 static char *ngx_http_empty_gif(ngx_conf_t *cf, ngx_command_t *cmd, | |
12 void *conf); | |
13 | |
14 static ngx_command_t ngx_http_empty_gif_commands[] = { | |
15 | |
16 { ngx_string("empty_gif"), | |
17 NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, | |
18 ngx_http_empty_gif, | |
19 0, | |
20 0, | |
21 NULL }, | |
22 | |
23 ngx_null_command | |
24 }; | |
25 | |
26 | |
27 /* the minimal single pixel transparent GIF, 43 bytes */ | |
28 | |
29 static u_char ngx_empty_gif[] = { | |
30 | |
581 | 31 'G', 'I', 'F', '8', '9', 'a', /* header */ |
577 | 32 |
581 | 33 /* logical screen descriptor */ |
34 0x01, 0x00, /* logical screen width */ | |
35 0x01, 0x00, /* logical screen height */ | |
36 0x80, /* global 1-bit color table */ | |
37 0x01, /* background color #1 */ | |
38 0x00, /* no aspect ratio */ | |
577 | 39 |
581 | 40 /* global color table */ |
41 0x00, 0x00, 0x00, /* #0: black */ | |
42 0xff, 0xff, 0xff, /* #1: white */ | |
577 | 43 |
581 | 44 /* graphic control extension */ |
45 0x21, /* extension introducer */ | |
46 0xf9, /* graphic control label */ | |
47 0x04, /* block size */ | |
48 0x01, /* transparent color is given, */ | |
49 /* no disposal specified, */ | |
50 /* user input is not expected */ | |
51 0x00, 0x00, /* delay time */ | |
52 0x01, /* transparent color #1 */ | |
53 0x00, /* block terminator */ | |
577 | 54 |
581 | 55 /* image descriptor */ |
56 0x2c, /* image separator */ | |
57 0x00, 0x00, /* image left position */ | |
58 0x00, 0x00, /* image top position */ | |
59 0x01, 0x00, /* image width */ | |
60 0x01, 0x00, /* image height */ | |
61 0x00, /* no local color table, no interlaced */ | |
577 | 62 |
581 | 63 /* table based image data */ |
64 0x02, /* LZW minimum code size, */ | |
65 /* must be at least 2-bit */ | |
66 0x02, /* block size */ | |
577 | 67 0x4c, 0x01, /* compressed bytes 01_001_100, 0000000_1 */ |
581 | 68 /* 100: clear code */ |
69 /* 001: 1 */ | |
70 /* 101: end of information code */ | |
71 0x00, /* block terminator */ | |
577 | 72 |
581 | 73 0x3B /* trailer */ |
577 | 74 }; |
75 | |
76 | |
667 | 77 static ngx_http_module_t ngx_http_empty_gif_module_ctx = { |
577 | 78 NULL, /* preconfiguration */ |
79 NULL, /* postconfiguration */ | |
80 | |
81 NULL, /* create main configuration */ | |
82 NULL, /* init main configuration */ | |
83 | |
84 NULL, /* create server configuration */ | |
85 NULL, /* merge server configuration */ | |
86 | |
87 NULL, /* create location configuration */ | |
88 NULL /* merge location configuration */ | |
89 }; | |
90 | |
91 | |
92 ngx_module_t ngx_http_empty_gif_module = { | |
93 NGX_MODULE_V1, | |
94 &ngx_http_empty_gif_module_ctx, /* module context */ | |
95 ngx_http_empty_gif_commands, /* module directives */ | |
96 NGX_HTTP_MODULE, /* module type */ | |
97 NULL, /* init master */ | |
98 NULL, /* init module */ | |
99 NULL, /* init process */ | |
100 NULL, /* init thread */ | |
101 NULL, /* exit thread */ | |
102 NULL, /* exit process */ | |
103 NULL, /* exit master */ | |
104 NGX_MODULE_V1_PADDING | |
105 }; | |
106 | |
107 | |
108 static ngx_int_t | |
109 ngx_http_empty_gif_handler(ngx_http_request_t *r) | |
110 { | |
111 ngx_int_t rc; | |
112 ngx_buf_t *b; | |
113 ngx_chain_t out; | |
114 | |
645 | 115 if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { |
577 | 116 return NGX_HTTP_NOT_ALLOWED; |
117 } | |
118 | |
1370
cc114c85be0f
rename ngx_http_discard_body() to ngx_http_discard_request_body()
Igor Sysoev <igor@sysoev.ru>
parents:
1038
diff
changeset
|
119 rc = ngx_http_discard_request_body(r); |
577 | 120 |
1374 | 121 if (rc != NGX_OK) { |
577 | 122 return rc; |
123 } | |
124 | |
2508 | 125 r->headers_out.content_type_len = sizeof("image/gif") - 1; |
577 | 126 r->headers_out.content_type.len = sizeof("image/gif") - 1; |
127 r->headers_out.content_type.data = (u_char *) "image/gif"; | |
128 | |
129 if (r->method == NGX_HTTP_HEAD) { | |
130 r->headers_out.status = NGX_HTTP_OK; | |
1547
e114a16fc5be
add time and length to a HEAD request
Igor Sysoev <igor@sysoev.ru>
parents:
1471
diff
changeset
|
131 r->headers_out.content_length_n = sizeof(ngx_empty_gif); |
e114a16fc5be
add time and length to a HEAD request
Igor Sysoev <igor@sysoev.ru>
parents:
1471
diff
changeset
|
132 r->headers_out.last_modified_time = 23349600; |
577 | 133 |
1471
fc73de3e8df0
response to the HEAD request should be a header only
Igor Sysoev <igor@sysoev.ru>
parents:
1374
diff
changeset
|
134 return ngx_http_send_header(r); |
577 | 135 } |
136 | |
651 | 137 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); |
577 | 138 if (b == NULL) { |
139 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
140 } | |
141 | |
142 out.buf = b; | |
143 out.next = NULL; | |
144 | |
145 b->pos = ngx_empty_gif; | |
146 b->last = ngx_empty_gif + sizeof(ngx_empty_gif); | |
651 | 147 b->memory = 1; |
577 | 148 b->last_buf = 1; |
149 | |
150 r->headers_out.status = NGX_HTTP_OK; | |
613 | 151 r->headers_out.content_length_n = sizeof(ngx_empty_gif); |
577 | 152 r->headers_out.last_modified_time = 23349600; |
153 | |
154 rc = ngx_http_send_header(r); | |
155 | |
156 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | |
157 return rc; | |
158 } | |
159 | |
1038 | 160 return ngx_http_output_filter(r, &out); |
577 | 161 } |
162 | |
163 | |
164 static char * | |
165 ngx_http_empty_gif(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
166 { | |
167 ngx_http_core_loc_conf_t *clcf; | |
168 | |
169 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
170 clcf->handler = ngx_http_empty_gif_handler; | |
171 | |
172 return NGX_CONF_OK; | |
173 } |