comparison src/http/ngx_http_request_body.c @ 8839:fac88e160653 quic

Merged with the default branch.
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 01 Sep 2021 10:57:25 +0300
parents 6bd8ed493b85 9cf043a5d9ca
children 61d0fa67b55e
comparison
equal deleted inserted replaced
8838:d6e191a583cc 8839:fac88e160653
60 } 60 }
61 61
62 /* 62 /*
63 * set by ngx_pcalloc(): 63 * set by ngx_pcalloc():
64 * 64 *
65 * rb->temp_file = NULL;
65 * rb->bufs = NULL; 66 * rb->bufs = NULL;
66 * rb->buf = NULL; 67 * rb->buf = NULL;
67 * rb->free = NULL; 68 * rb->free = NULL;
68 * rb->busy = NULL; 69 * rb->busy = NULL;
69 * rb->chunked = NULL; 70 * rb->chunked = NULL;
71 * rb->received = 0;
72 * rb->filter_need_buffering = 0;
73 * rb->last_sent = 0;
74 * rb->last_saved = 0;
70 */ 75 */
71 76
72 rb->rest = -1; 77 rb->rest = -1;
73 rb->post_handler = post_handler; 78 rb->post_handler = post_handler;
74 79
149 if (rc != NGX_OK) { 154 if (rc != NGX_OK) {
150 goto done; 155 goto done;
151 } 156 }
152 } 157 }
153 158
154 if (rb->rest == 0) { 159 if (rb->rest == 0 && rb->last_saved) {
155 /* the whole request body was pre-read */ 160 /* the whole request body was pre-read */
156 r->request_body_no_buffering = 0; 161 r->request_body_no_buffering = 0;
157 post_handler(r); 162 post_handler(r);
158 return NGX_OK; 163 return NGX_OK;
159 } 164 }
177 182
178 if (r->request_body_in_single_buf) { 183 if (r->request_body_in_single_buf) {
179 size += preread; 184 size += preread;
180 } 185 }
181 186
187 if (size == 0) {
188 size++;
189 }
190
182 } else { 191 } else {
183 size = clcf->client_body_buffer_size; 192 size = clcf->client_body_buffer_size;
184 } 193 }
185 194
186 rb->buf = ngx_create_temp_buf(r->pool, size); 195 rb->buf = ngx_create_temp_buf(r->pool, size);
287 { 296 {
288 off_t rest; 297 off_t rest;
289 size_t size; 298 size_t size;
290 ssize_t n; 299 ssize_t n;
291 ngx_int_t rc; 300 ngx_int_t rc;
301 ngx_uint_t flush;
292 ngx_chain_t out; 302 ngx_chain_t out;
293 ngx_connection_t *c; 303 ngx_connection_t *c;
294 ngx_http_request_body_t *rb; 304 ngx_http_request_body_t *rb;
295 ngx_http_core_loc_conf_t *clcf; 305 ngx_http_core_loc_conf_t *clcf;
296 306
297 c = r->connection; 307 c = r->connection;
298 rb = r->request_body; 308 rb = r->request_body;
309 flush = 1;
299 310
300 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 311 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
301 "http read client request body"); 312 "http read client request body");
302 313
303 for ( ;; ) { 314 for ( ;; ) {
304 for ( ;; ) { 315 for ( ;; ) {
316 if (rb->rest == 0) {
317 break;
318 }
319
305 if (rb->buf->last == rb->buf->end) { 320 if (rb->buf->last == rb->buf->end) {
306 321
307 /* update chains */ 322 /* update chains */
308 323
309 rc = ngx_http_request_body_filter(r, NULL); 324 rc = ngx_http_request_body_filter(r, NULL);
323 } 338 }
324 339
325 return NGX_AGAIN; 340 return NGX_AGAIN;
326 } 341 }
327 342
343 if (rb->filter_need_buffering) {
344 clcf = ngx_http_get_module_loc_conf(r,
345 ngx_http_core_module);
346 ngx_add_timer(c->read, clcf->client_body_timeout);
347
348 if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
349 return NGX_HTTP_INTERNAL_SERVER_ERROR;
350 }
351
352 return NGX_AGAIN;
353 }
354
328 ngx_log_error(NGX_LOG_ALERT, c->log, 0, 355 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
329 "busy buffers after request body flush"); 356 "busy buffers after request body flush");
330 357
331 return NGX_HTTP_INTERNAL_SERVER_ERROR; 358 return NGX_HTTP_INTERNAL_SERVER_ERROR;
332 } 359 }
333 360
361 flush = 0;
334 rb->buf->pos = rb->buf->start; 362 rb->buf->pos = rb->buf->start;
335 rb->buf->last = rb->buf->start; 363 rb->buf->last = rb->buf->start;
336 } 364 }
337 365
338 size = rb->buf->end - rb->buf->last; 366 size = rb->buf->end - rb->buf->last;
339 rest = rb->rest - (rb->buf->last - rb->buf->pos); 367 rest = rb->rest - (rb->buf->last - rb->buf->pos);
340 368
341 if ((off_t) size > rest) { 369 if ((off_t) size > rest) {
342 size = (size_t) rest; 370 size = (size_t) rest;
371 }
372
373 if (size == 0) {
374 break;
343 } 375 }
344 376
345 n = c->recv(c, rb->buf->last, size); 377 n = c->recv(c, rb->buf->last, size);
346 378
347 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 379 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
364 rb->buf->last += n; 396 rb->buf->last += n;
365 r->request_length += n; 397 r->request_length += n;
366 398
367 /* pass buffer to request body filter chain */ 399 /* pass buffer to request body filter chain */
368 400
401 flush = 0;
369 out.buf = rb->buf; 402 out.buf = rb->buf;
370 out.next = NULL; 403 out.next = NULL;
371 404
372 rc = ngx_http_request_body_filter(r, &out); 405 rc = ngx_http_request_body_filter(r, &out);
373 406
385 } 418 }
386 419
387 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, 420 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
388 "http client request body rest %O", rb->rest); 421 "http client request body rest %O", rb->rest);
389 422
390 if (rb->rest == 0) { 423 if (flush) {
424 rc = ngx_http_request_body_filter(r, NULL);
425
426 if (rc != NGX_OK) {
427 return rc;
428 }
429 }
430
431 if (rb->rest == 0 && rb->last_saved) {
391 break; 432 break;
392 } 433 }
393 434
394 if (!c->read->ready) { 435 if (!c->read->ready || rb->rest == 0) {
395 436
396 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); 437 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
397 ngx_add_timer(c->read, clcf->client_body_timeout); 438 ngx_add_timer(c->read, clcf->client_body_timeout);
398 439
399 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { 440 if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
958 ngx_chain_t *cl, *tl, *out, **ll; 999 ngx_chain_t *cl, *tl, *out, **ll;
959 ngx_http_request_body_t *rb; 1000 ngx_http_request_body_t *rb;
960 1001
961 rb = r->request_body; 1002 rb = r->request_body;
962 1003
1004 out = NULL;
1005 ll = &out;
1006
963 if (rb->rest == -1) { 1007 if (rb->rest == -1) {
964 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1008 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
965 "http request body content length filter"); 1009 "http request body content length filter");
966 1010
967 rb->rest = r->headers_in.content_length_n; 1011 rb->rest = r->headers_in.content_length_n;
968 } 1012
969 1013 if (rb->rest == 0) {
970 out = NULL; 1014
971 ll = &out; 1015 tl = ngx_chain_get_free_buf(r->pool, &rb->free);
1016 if (tl == NULL) {
1017 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1018 }
1019
1020 b = tl->buf;
1021
1022 ngx_memzero(b, sizeof(ngx_buf_t));
1023
1024 b->last_buf = 1;
1025
1026 *ll = tl;
1027 ll = &tl->next;
1028 }
1029 }
972 1030
973 for (cl = in; cl; cl = cl->next) { 1031 for (cl = in; cl; cl = cl->next) {
974 1032
975 if (rb->rest == 0) { 1033 if (rb->rest == 0) {
976 break; 1034 break;
1030 ngx_http_core_loc_conf_t *clcf; 1088 ngx_http_core_loc_conf_t *clcf;
1031 ngx_http_core_srv_conf_t *cscf; 1089 ngx_http_core_srv_conf_t *cscf;
1032 1090
1033 rb = r->request_body; 1091 rb = r->request_body;
1034 1092
1093 out = NULL;
1094 ll = &out;
1095
1035 if (rb->rest == -1) { 1096 if (rb->rest == -1) {
1036 1097
1037 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1098 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1038 "http request body chunked filter"); 1099 "http request body chunked filter");
1039 1100
1045 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 1106 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1046 1107
1047 r->headers_in.content_length_n = 0; 1108 r->headers_in.content_length_n = 0;
1048 rb->rest = cscf->large_client_header_buffers.size; 1109 rb->rest = cscf->large_client_header_buffers.size;
1049 } 1110 }
1050
1051 out = NULL;
1052 ll = &out;
1053 1111
1054 for (cl = in; cl; cl = cl->next) { 1112 for (cl = in; cl; cl = cl->next) {
1055 1113
1056 b = NULL; 1114 b = NULL;
1057 1115
1205 1263
1206 ngx_int_t 1264 ngx_int_t
1207 ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in) 1265 ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
1208 { 1266 {
1209 ngx_buf_t *b; 1267 ngx_buf_t *b;
1210 ngx_chain_t *cl; 1268 ngx_chain_t *cl, *tl, **ll;
1211 ngx_http_request_body_t *rb; 1269 ngx_http_request_body_t *rb;
1212 1270
1213 rb = r->request_body; 1271 rb = r->request_body;
1214 1272
1215 #if (NGX_DEBUG) 1273 ll = &rb->bufs;
1274
1275 for (cl = rb->bufs; cl; cl = cl->next) {
1216 1276
1217 #if 0 1277 #if 0
1218 for (cl = rb->bufs; cl; cl = cl->next) {
1219 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, 1278 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
1220 "http body old buf t:%d f:%d %p, pos %p, size: %z " 1279 "http body old buf t:%d f:%d %p, pos %p, size: %z "
1221 "file: %O, size: %O", 1280 "file: %O, size: %O",
1222 cl->buf->temporary, cl->buf->in_file, 1281 cl->buf->temporary, cl->buf->in_file,
1223 cl->buf->start, cl->buf->pos, 1282 cl->buf->start, cl->buf->pos,
1224 cl->buf->last - cl->buf->pos, 1283 cl->buf->last - cl->buf->pos,
1225 cl->buf->file_pos, 1284 cl->buf->file_pos,
1226 cl->buf->file_last - cl->buf->file_pos); 1285 cl->buf->file_last - cl->buf->file_pos);
1227 }
1228 #endif 1286 #endif
1229 1287
1288 ll = &cl->next;
1289 }
1290
1230 for (cl = in; cl; cl = cl->next) { 1291 for (cl = in; cl; cl = cl->next) {
1292
1231 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0, 1293 ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
1232 "http body new buf t:%d f:%d %p, pos %p, size: %z " 1294 "http body new buf t:%d f:%d %p, pos %p, size: %z "
1233 "file: %O, size: %O", 1295 "file: %O, size: %O",
1234 cl->buf->temporary, cl->buf->in_file, 1296 cl->buf->temporary, cl->buf->in_file,
1235 cl->buf->start, cl->buf->pos, 1297 cl->buf->start, cl->buf->pos,
1236 cl->buf->last - cl->buf->pos, 1298 cl->buf->last - cl->buf->pos,
1237 cl->buf->file_pos, 1299 cl->buf->file_pos,
1238 cl->buf->file_last - cl->buf->file_pos); 1300 cl->buf->file_last - cl->buf->file_pos);
1239 } 1301
1240 1302 if (cl->buf->last_buf) {
1241 #endif 1303
1242 1304 if (rb->last_saved) {
1243 /* TODO: coalesce neighbouring buffers */ 1305 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1244 1306 "duplicate last buf in save filter");
1245 if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK) { 1307 *ll = NULL;
1246 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1308 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1247 } 1309 }
1310
1311 rb->last_saved = 1;
1312 }
1313
1314 tl = ngx_alloc_chain_link(r->pool);
1315 if (tl == NULL) {
1316 *ll = NULL;
1317 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1318 }
1319
1320 tl->buf = cl->buf;
1321 *ll = tl;
1322 ll = &tl->next;
1323 }
1324
1325 *ll = NULL;
1248 1326
1249 if (r->request_body_no_buffering) { 1327 if (r->request_body_no_buffering) {
1250 return NGX_OK; 1328 return NGX_OK;
1251 } 1329 }
1252 1330
1259 } 1337 }
1260 1338
1261 return NGX_OK; 1339 return NGX_OK;
1262 } 1340 }
1263 1341
1264 /* rb->rest == 0 */ 1342 if (!rb->last_saved) {
1343 return NGX_OK;
1344 }
1265 1345
1266 if (rb->temp_file || r->request_body_in_file_only) { 1346 if (rb->temp_file || r->request_body_in_file_only) {
1347
1348 if (rb->bufs && rb->bufs->buf->in_file) {
1349 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1350 "body already in file");
1351 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1352 }
1267 1353
1268 if (ngx_http_write_request_body(r) != NGX_OK) { 1354 if (ngx_http_write_request_body(r) != NGX_OK) {
1269 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1355 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1270 } 1356 }
1271 1357