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)