Mercurial > hg > nginx
comparison src/http/ngx_http_request_body.c @ 4923:57174af2e695
Request body: fixed socket leak on errors.
The r->main->count reference counter was always incremented in
ngx_http_read_client_request_body(), while it is only needs to be
incremented on positive returns.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 21 Nov 2012 00:57:16 +0000 |
parents | dfa586842962 |
children | caca5603bded |
comparison
equal
deleted
inserted
replaced
4922:dfa586842962 | 4923:57174af2e695 |
---|---|
29 ngx_http_read_client_request_body(ngx_http_request_t *r, | 29 ngx_http_read_client_request_body(ngx_http_request_t *r, |
30 ngx_http_client_body_handler_pt post_handler) | 30 ngx_http_client_body_handler_pt post_handler) |
31 { | 31 { |
32 size_t preread; | 32 size_t preread; |
33 ssize_t size; | 33 ssize_t size; |
34 ngx_int_t rc; | |
34 ngx_buf_t *b; | 35 ngx_buf_t *b; |
35 ngx_chain_t *cl, **next; | 36 ngx_chain_t *cl, **next; |
36 ngx_http_request_body_t *rb; | 37 ngx_http_request_body_t *rb; |
37 ngx_http_core_loc_conf_t *clcf; | 38 ngx_http_core_loc_conf_t *clcf; |
38 | 39 |
42 post_handler(r); | 43 post_handler(r); |
43 return NGX_OK; | 44 return NGX_OK; |
44 } | 45 } |
45 | 46 |
46 if (ngx_http_test_expect(r) != NGX_OK) { | 47 if (ngx_http_test_expect(r) != NGX_OK) { |
47 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 48 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
49 goto done; | |
48 } | 50 } |
49 | 51 |
50 rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); | 52 rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); |
51 if (rb == NULL) { | 53 if (rb == NULL) { |
52 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 54 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
55 goto done; | |
53 } | 56 } |
54 | 57 |
55 r->request_body = rb; | 58 r->request_body = rb; |
56 | 59 |
57 if (r->headers_in.content_length_n < 0) { | 60 if (r->headers_in.content_length_n < 0) { |
63 | 66 |
64 if (r->headers_in.content_length_n == 0) { | 67 if (r->headers_in.content_length_n == 0) { |
65 | 68 |
66 if (r->request_body_in_file_only) { | 69 if (r->request_body_in_file_only) { |
67 if (ngx_http_write_request_body(r, NULL) != NGX_OK) { | 70 if (ngx_http_write_request_body(r, NULL) != NGX_OK) { |
68 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 71 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
72 goto done; | |
69 } | 73 } |
70 } | 74 } |
71 | 75 |
72 post_handler(r); | 76 post_handler(r); |
73 | 77 |
93 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 97 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
94 "http client request body preread %uz", preread); | 98 "http client request body preread %uz", preread); |
95 | 99 |
96 b = ngx_calloc_buf(r->pool); | 100 b = ngx_calloc_buf(r->pool); |
97 if (b == NULL) { | 101 if (b == NULL) { |
98 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 102 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
103 goto done; | |
99 } | 104 } |
100 | 105 |
101 b->temporary = 1; | 106 b->temporary = 1; |
102 b->start = r->header_in->pos; | 107 b->start = r->header_in->pos; |
103 b->pos = r->header_in->pos; | 108 b->pos = r->header_in->pos; |
104 b->last = r->header_in->last; | 109 b->last = r->header_in->last; |
105 b->end = r->header_in->end; | 110 b->end = r->header_in->end; |
106 | 111 |
107 rb->bufs = ngx_alloc_chain_link(r->pool); | 112 rb->bufs = ngx_alloc_chain_link(r->pool); |
108 if (rb->bufs == NULL) { | 113 if (rb->bufs == NULL) { |
109 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 114 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
115 goto done; | |
110 } | 116 } |
111 | 117 |
112 rb->bufs->buf = b; | 118 rb->bufs->buf = b; |
113 rb->bufs->next = NULL; | 119 rb->bufs->next = NULL; |
114 | 120 |
122 r->request_length += r->headers_in.content_length_n; | 128 r->request_length += r->headers_in.content_length_n; |
123 b->last = r->header_in->pos; | 129 b->last = r->header_in->pos; |
124 | 130 |
125 if (r->request_body_in_file_only) { | 131 if (r->request_body_in_file_only) { |
126 if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) { | 132 if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) { |
127 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 133 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
134 goto done; | |
128 } | 135 } |
129 } | 136 } |
130 | 137 |
131 post_handler(r); | 138 post_handler(r); |
132 | 139 |
149 | 156 |
150 rb->to_write = rb->bufs; | 157 rb->to_write = rb->bufs; |
151 | 158 |
152 r->read_event_handler = ngx_http_read_client_request_body_handler; | 159 r->read_event_handler = ngx_http_read_client_request_body_handler; |
153 | 160 |
154 return ngx_http_do_read_client_request_body(r); | 161 rc = ngx_http_do_read_client_request_body(r); |
162 goto done; | |
155 } | 163 } |
156 | 164 |
157 next = &rb->bufs->next; | 165 next = &rb->bufs->next; |
158 | 166 |
159 } else { | 167 } else { |
179 b = NULL; | 187 b = NULL; |
180 } | 188 } |
181 | 189 |
182 rb->buf = ngx_create_temp_buf(r->pool, size); | 190 rb->buf = ngx_create_temp_buf(r->pool, size); |
183 if (rb->buf == NULL) { | 191 if (rb->buf == NULL) { |
184 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 192 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
193 goto done; | |
185 } | 194 } |
186 | 195 |
187 cl = ngx_alloc_chain_link(r->pool); | 196 cl = ngx_alloc_chain_link(r->pool); |
188 if (cl == NULL) { | 197 if (cl == NULL) { |
189 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 198 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
199 goto done; | |
190 } | 200 } |
191 | 201 |
192 cl->buf = rb->buf; | 202 cl->buf = rb->buf; |
193 cl->next = NULL; | 203 cl->next = NULL; |
194 | 204 |
209 rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs; | 219 rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs; |
210 } | 220 } |
211 | 221 |
212 r->read_event_handler = ngx_http_read_client_request_body_handler; | 222 r->read_event_handler = ngx_http_read_client_request_body_handler; |
213 | 223 |
214 return ngx_http_do_read_client_request_body(r); | 224 rc = ngx_http_do_read_client_request_body(r); |
225 | |
226 done: | |
227 | |
228 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | |
229 r->main->count--; | |
230 } | |
231 | |
232 return rc; | |
215 } | 233 } |
216 | 234 |
217 | 235 |
218 static void | 236 static void |
219 ngx_http_read_client_request_body_handler(ngx_http_request_t *r) | 237 ngx_http_read_client_request_body_handler(ngx_http_request_t *r) |