DAVROMANIAK

Welcome! Here you can paste sources and general debugging text, You can even set yourself a password if you want to keep it just for yourself.

Posted by davromaniak on December Wed 12th 5:53 PM - Never Expires

Download | New paste

  1. --- nginx-upload-module-2.2.0/ngx_http_upload_module.c  2010-09-27 20:54:15.000000000 +0200
  2. +++ nginx-1.3.9/debian/modules/nginx-upload-module/ngx_http_upload_module.c     2012-12-12 17:44:32.000000000 +0100
  3.  -233,6 +233,17 @@
  4.      unsigned int        raw_input:1;
  5.  } ngx_http_upload_ctx_t;
  6.  
  7. +static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
  8. +static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
  9. +
  10. +static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r);
  11. +static ngx_int_t ngx_http_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in);
  12. +
  13. +static ngx_int_t ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in);
  14. +static ngx_int_t ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in);
  15. +
  16. +static ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in);
  17. +
  18.  static ngx_int_t ngx_http_upload_handler(ngx_http_request_t *r);
  19.  static ngx_int_t ngx_http_upload_body_handler(ngx_http_request_t *r);
  20.  
  21.  -271,6 +282,7 @@
  22.  static ngx_int_t ngx_http_upload_merge_ranges(ngx_http_upload_ctx_t *u, ngx_http_upload_range_t *range_n);
  23.  static ngx_int_t ngx_http_upload_parse_range(ngx_str_t *range, ngx_http_upload_range_t *range_n);
  24.  
  25. +
  26.  static void ngx_http_read_upload_client_request_body_handler(ngx_http_request_t *r);
  27.  static ngx_int_t ngx_http_do_read_upload_client_request_body(ngx_http_request_t *r);
  28.  static ngx_int_t ngx_http_process_request_body(ngx_http_request_t *r, ngx_chain_t *body);
  29.  -2523,6 +2535,533 @@
  30.      return NGX_CONF_OK;
  31.  } /* }}} */
  32.  
  33. +static ngx_int_t
  34. +ngx_http_write_request_body(ngx_http_request_t *r)
  35. +{
  36. +    ssize_t                    n;
  37. +    ngx_chain_t               *cl;
  38. +    ngx_temp_file_t           *tf;
  39. +    ngx_http_request_body_t   *rb;
  40. +    ngx_http_core_loc_conf_t  *clcf;
  41. +
  42. +    rb = r->request_body;
  43. +
  44. +    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  45. +                   "http write client request body, bufs %p", rb->bufs);
  46. +
  47. +    if (rb->temp_file == NULL) {
  48. +        tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
  49. +        if (tf == NULL) {
  50. +            return NGX_ERROR;
  51. +        }
  52. +
  53. +        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  54. +
  55. +        tf->file.fd = NGX_INVALID_FILE;
  56. +        tf->file.log = r->connection->log;
  57. +        tf->path = clcf->client_body_temp_path;
  58. +        tf->pool = r->pool;
  59. +        tf->warn = "a client request body is buffered to a temporary file";
  60. +        tf->log_level = r->request_body_file_log_level;
  61. +        tf->persistent = r->request_body_in_persistent_file;
  62. +        tf->clean = r->request_body_in_clean_file;
  63. +
  64. +        if (r->request_body_file_group_access) {
  65. +            tf->access = 0660;
  66. +        }
  67. +
  68. +        rb->temp_file = tf;
  69. +
  70. +        if (rb->bufs == NULL) {
  71. +            /* empty body with r->request_body_in_file_only */
  72. +
  73. +            if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
  74. +                                     tf->persistent, tf->clean, tf->access)
  75. +                != NGX_OK)
  76. +            {
  77. +                return NGX_ERROR;
  78. +            }
  79. +
  80. +            return NGX_OK;
  81. +        }
  82. +    }
  83. +
  84. +    if (rb->bufs == NULL) {
  85. +        return NGX_OK;
  86. +    }
  87. +
  88. +    n = ngx_write_chain_to_temp_file(rb->temp_file, rb->bufs);
  89. +
  90. +    /* TODO: n == 0 or not complete and level event */
  91. +
  92. +    if (n == NGX_ERROR) {
  93. +        return NGX_ERROR;
  94. +    }
  95. +
  96. +    rb->temp_file->offset += n;
  97. +
  98. +    /* mark all buffers as written */
  99. +
  100. +    for (cl = rb->bufs; cl; cl = cl->next) {
  101. +        cl->buf->pos = cl->buf->last;
  102. +    }
  103. +
  104. +    rb->bufs = NULL;
  105. +
  106. +    return NGX_OK;
  107. +}
  108. +
  109. +static ngx_int_t
  110. +ngx_http_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
  111. +{
  112. +    if (r->headers_in.chunked) {
  113. +        return ngx_http_request_body_chunked_filter(r, in);
  114. +
  115. +    } else {
  116. +        return ngx_http_request_body_length_filter(r, in);
  117. +    }
  118. +}
  119. +
  120. +static ngx_int_t
  121. +ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
  122. +{
  123. +#if (NGX_DEBUG)
  124. +    ngx_chain_t               *cl;
  125. +#endif
  126. +    ngx_http_request_body_t   *rb;
  127. +
  128. +    rb = r->request_body;
  129. +
  130. +#if (NGX_DEBUG)
  131. +
  132. +    for (cl = rb->bufs; cl; cl = cl->next) {
  133. +        ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
  134. +                       "http body old buf t:%d f:%d %p, pos %p, size: %z "
  135. +                       "file: %O, size: %z",
  136. +                       cl->buf->temporary, cl->buf->in_file,
  137. +                       cl->buf->start, cl->buf->pos,
  138. +                       cl->buf->last - cl->buf->pos,
  139. +                       cl->buf->file_pos,
  140. +                       cl->buf->file_last - cl->buf->file_pos);
  141. +    }
  142. +
  143. +    for (cl = in; cl; cl = cl->next) {
  144. +        ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
  145. +                       "http body new buf t:%d f:%d %p, pos %p, size: %z "
  146. +                       "file: %O, size: %z",
  147. +                       cl->buf->temporary, cl->buf->in_file,
  148. +                       cl->buf->start, cl->buf->pos,
  149. +                       cl->buf->last - cl->buf->pos,
  150. +                       cl->buf->file_pos,
  151. +                       cl->buf->file_last - cl->buf->file_pos);
  152. +    }
  153. +
  154. +#endif
  155. +
  156. +    /* TODO: coalesce neighbouring buffers */
  157. +
  158. +    if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK) {
  159. +        return NGX_HTTP_INTERNAL_SERVER_ERROR;
  160. +    }
  161. +
  162. +    return NGX_OK;
  163. +}
  164. +
  165. +
  166. +static ngx_int_t
  167. +ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
  168. +{
  169. +    size_t                     size;
  170. +    ngx_int_t                  rc;
  171. +    ngx_buf_t                 *b;
  172. +    ngx_chain_t               *cl, *tl, *out, **ll;
  173. +    ngx_http_request_body_t   *rb;
  174. +
  175. +    rb = r->request_body;
  176. +
  177. +    if (rb->rest == -1) {
  178. +        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  179. +                       "http request body content length filter");
  180. +
  181. +        rb->rest = r->headers_in.content_length_n;
  182. +    }
  183. +
  184. +    out = NULL;
  185. +    ll = &out;
  186. +
  187. +    for (cl = in; cl; cl = cl->next) {
  188. +
  189. +        tl = ngx_chain_get_free_buf(r->pool, &rb->free);
  190. +        if (tl == NULL) {
  191. +            return NGX_HTTP_INTERNAL_SERVER_ERROR;
  192. +        }
  193. +
  194. +        b = tl->buf;
  195. +
  196. +        ngx_memzero(b, sizeof(ngx_buf_t));
  197. +
  198. +        b->temporary = 1;
  199. +        b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body;
  200. +        b->start = cl->buf->start;
  201. +        b->pos = cl->buf->pos;
  202. +        b->last = cl->buf->last;
  203. +        b->end = cl->buf->end;
  204. +
  205. +        size = cl->buf->last - cl->buf->pos;
  206. +
  207. +        if ((off_t) size < rb->rest) {
  208. +            cl->buf->pos = cl->buf->last;
  209. +            rb->rest -= size;
  210. +
  211. +        } else {
  212. +            cl->buf->pos += rb->rest;
  213. +            rb->rest = 0;
  214. +            b->last = cl->buf->pos;
  215. +            b->last_buf = 1;
  216. +        }
  217. +
  218. +        *ll = tl;
  219. +        ll = &tl->next;
  220. +    }
  221. +
  222. +    rc = ngx_http_request_body_save_filter(r, out);
  223. +
  224. +    ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
  225. +                            (ngx_buf_tag_t) &ngx_http_read_client_request_body);
  226. +
  227. +    return rc;
  228. +}
  229. +
  230. +static ngx_int_t
  231. +ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
  232. +{
  233. +    size_t                     size;
  234. +    ngx_int_t                  rc;
  235. +    ngx_buf_t                 *b;
  236. +    ngx_chain_t               *cl, *out, *tl, **ll;
  237. +    ngx_http_request_body_t   *rb;
  238. +    ngx_http_core_loc_conf_t  *clcf;
  239. +
  240. +    rb = r->request_body;
  241. +
  242. +    if (rb->rest == -1) {
  243. +
  244. +        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  245. +                       "http request body chunked filter");
  246. +
  247. +        rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t));
  248. +        if (rb->chunked == NULL) {
  249. +            return NGX_HTTP_INTERNAL_SERVER_ERROR;
  250. +        }
  251. +
  252. +        r->headers_in.content_length_n = 0;
  253. +        rb->rest = 3;
  254. +    }
  255. +
  256. +    out = NULL;
  257. +    ll = &out;
  258. +
  259. +    for (cl = in; cl; cl = cl->next) {
  260. +
  261. +        for ( ;; ) {
  262. +
  263. +            ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
  264. +                           "http body chunked buf "
  265. +                           "t:%d f:%d %p, pos %p, size: %z file: %O, size: %z",
  266. +                           cl->buf->temporary, cl->buf->in_file,
  267. +                           cl->buf->start, cl->buf->pos,
  268. +                           cl->buf->last - cl->buf->pos,
  269. +                           cl->buf->file_pos,
  270. +                           cl->buf->file_last - cl->buf->file_pos);
  271. +
  272. +            rc = ngx_http_parse_chunked(r, cl->buf, rb->chunked);
  273. +
  274. +            if (rc == NGX_OK) {
  275. +
  276. +                /* a chunk has been parsed successfully */
  277. +
  278. +                clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  279. +
  280. +                if (clcf->client_max_body_size
  281. +                    && clcf->client_max_body_size
  282. +                       < r->headers_in.content_length_n + rb->chunked->size)
  283. +                {
  284. +                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  285. +                                  "client intended to send too large chunked "
  286. +                                  "body: %O bytes",
  287. +                                  r->headers_in.content_length_n
  288. +                                  + rb->chunked->size);
  289. +
  290. +                    r->lingering_close = 1;
  291. +
  292. +                    return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
  293. +                }
  294. +
  295. +                tl = ngx_chain_get_free_buf(r->pool, &rb->free);
  296. +                if (tl == NULL) {
  297. +                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
  298. +                }
  299. +
  300. +                b = tl->buf;
  301. +
  302. +                ngx_memzero(b, sizeof(ngx_buf_t));
  303. +
  304. +                b->temporary = 1;
  305. +                b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body;
  306. +                b->start = cl->buf->start;
  307. +                b->pos = cl->buf->pos;
  308. +                b->last = cl->buf->last;
  309. +                b->end = cl->buf->end;
  310. +
  311. +                *ll = tl;
  312. +                ll = &tl->next;
  313. +
  314. +                size = cl->buf->last - cl->buf->pos;
  315. +
  316. +                if ((off_t) size > rb->chunked->size) {
  317. +                   cl->buf->pos += rb->chunked->size;
  318. +                    r->headers_in.content_length_n += rb->chunked->size;
  319. +                    rb->chunked->size = 0;
  320. +
  321. +                } else {
  322. +                    rb->chunked->size -= size;
  323. +                    r->headers_in.content_length_n += size;
  324. +                    cl->buf->pos = cl->buf->last;
  325. +                }
  326. +
  327. +                b->last = cl->buf->pos;
  328. +
  329. +                continue;
  330. +            }
  331. +
  332. +            if (rc == NGX_DONE) {
  333. +
  334. +                /* a whole response has been parsed successfully */
  335. +
  336. +                rb->rest = 0;
  337. +
  338. +                tl = ngx_chain_get_free_buf(r->pool, &rb->free);
  339. +                if (tl == NULL) {
  340. +                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
  341. +                }
  342. +
  343. +                b = tl->buf;
  344. +
  345. +                ngx_memzero(b, sizeof(ngx_buf_t));
  346. +
  347. +                b->last_buf = 1;
  348. +
  349. +                *ll = tl;
  350. +                ll = &tl->next;
  351. +
  352. +                break;
  353. +            }
  354. +
  355. +            if (rc == NGX_AGAIN) {
  356. +
  357. +                /* set rb->rest, amount of data we want to see next time */
  358. +
  359. +                rb->rest = rb->chunked->length;
  360. +
  361. +                break;
  362. +            }
  363. +
  364. +            /* invalid */
  365. +
  366. +            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  367. +                          "client sent invalid chunked body");
  368. +
  369. +            return NGX_HTTP_BAD_REQUEST;
  370. +        }
  371. +    }
  372. +
  373. +    rc = ngx_http_request_body_save_filter(r, out);
  374. +
  375. +    ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
  376. +                            (ngx_buf_tag_t) &ngx_http_read_client_request_body);
  377. +
  378. +    return rc;
  379. +}
  380. +
  381. +static ngx_int_t
  382. +ngx_http_do_read_client_request_body(ngx_http_request_t *r)
  383. +{
  384. +    off_t                      rest;
  385. +    size_t                     size;
  386. +    ssize_t                    n;
  387. +    ngx_int_t                  rc;
  388. +    ngx_buf_t                 *b;
  389. +    ngx_chain_t               *cl, out;
  390. +    ngx_connection_t          *c;
  391. +    ngx_http_request_body_t   *rb;
  392. +    ngx_http_core_loc_conf_t  *clcf;
  393. +
  394. +    c = r->connection;
  395. +    rb = r->request_body;
  396. +
  397. +    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
  398. +                   "http read client request body");
  399. +
  400. +    for ( ;; ) {
  401. +        for ( ;; ) {
  402. +            if (rb->buf->last == rb->buf->end) {
  403. +
  404. +                /* pass buffer to request body filter chain */
  405. +
  406. +                out.buf = rb->buf;
  407. +                out.next = NULL;
  408. +
  409. +                rc = ngx_http_request_body_filter(r, &out);
  410. +
  411. +                if (rc != NGX_OK) {
  412. +                    return rc;
  413. +                }
  414. +
  415. +                /* write to file */
  416. +
  417. +                if (ngx_http_write_request_body(r) != NGX_OK) {
  418. +                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
  419. +                }
  420. +
  421. +                /* update chains */
  422. +
  423. +                rc = ngx_http_request_body_filter(r, NULL);
  424. +
  425. +                if (rc != NGX_OK) {
  426. +                    return rc;
  427. +                }
  428. +
  429. +                if (rb->busy != NULL) {
  430. +                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
  431. +                }
  432. +
  433. +                rb->buf->pos = rb->buf->start;
  434. +                rb->buf->last = rb->buf->start;
  435. +            }
  436. +            size = rb->buf->end - rb->buf->last;
  437. +            rest = rb->rest - (rb->buf->last - rb->buf->pos);
  438. +
  439. +            if ((off_t) size > rest) {
  440. +                size = (size_t) rest;
  441. +            }
  442. +
  443. +            n = c->recv(c, rb->buf->last, size);
  444. +
  445. +            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  446. +                           "http client request body recv %z", n);
  447. +
  448. +            if (n == NGX_AGAIN) {
  449. +                break;
  450. +            }
  451. +
  452. +            if (n == 0) {
  453. +                ngx_log_error(NGX_LOG_INFO, c->log, 0,
  454. +                              "client prematurely closed connection");
  455. +            }
  456. +
  457. +            if (n == 0 || n == NGX_ERROR) {
  458. +                c->error = 1;
  459. +                return NGX_HTTP_BAD_REQUEST;
  460. +            }
  461. +
  462. +            rb->buf->last += n;
  463. +            r->request_length += n;
  464. +
  465. +            if (n == rest) {
  466. +                /* pass buffer to request body filter chain */
  467. +
  468. +                out.buf = rb->buf;
  469. +                out.next = NULL;
  470. +
  471. +                rc = ngx_http_request_body_filter(r, &out);
  472. +
  473. +                if (rc != NGX_OK) {
  474. +                    return rc;
  475. +                }
  476. +            }
  477. +
  478. +            if (rb->rest == 0) {
  479. +                break;
  480. +            }
  481. +
  482. +            if (rb->buf->last < rb->buf->end) {
  483. +                break;
  484. +            }
  485. +        }
  486. +
  487. +        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  488. +                       "http client request body rest %O", rb->rest);
  489. +                      if (rb->rest == 0) {
  490. +            break;
  491. +        }
  492. +
  493. +        if (!c->read->ready) {
  494. +            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  495. +            ngx_add_timer(c->read, clcf->client_body_timeout);
  496. +
  497. +            if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
  498. +                return NGX_HTTP_INTERNAL_SERVER_ERROR;
  499. +            }
  500. +
  501. +            return NGX_AGAIN;
  502. +        }
  503. +    }
  504. +
  505. +    if (c->read->timer_set) {
  506. +        ngx_del_timer(c->read);
  507. +    }
  508. +
  509. +    if (rb->temp_file || r->request_body_in_file_only) {
  510. +
  511. +        /* save the last part */
  512. +
  513. +        if (ngx_http_write_request_body(r) != NGX_OK) {
  514. +            return NGX_HTTP_INTERNAL_SERVER_ERROR;
  515. +        }
  516. +
  517. +        cl = ngx_chain_get_free_buf(r->pool, &rb->free);
  518. +        if (cl == NULL) {
  519. +            return NGX_HTTP_INTERNAL_SERVER_ERROR;
  520. +        }
  521. +
  522. +        b = cl->buf;
  523. +
  524. +        ngx_memzero(b, sizeof(ngx_buf_t));
  525. +
  526. +        b->in_file = 1;
  527. +        b->file_last = rb->temp_file->file.offset;
  528. +        b->file = &rb->temp_file->file;
  529. +
  530. +        rb->bufs = cl;
  531. +    }
  532. +
  533. +    r->read_event_handler = ngx_http_block_reading;
  534. +
  535. +    rb->post_handler(r);
  536. +
  537. +    return NGX_OK;
  538. +}
  539. +
  540. +
  541. +static void
  542. +ngx_http_read_client_request_body_handler(ngx_http_request_t *r)
  543. +{
  544. +    ngx_int_t  rc;
  545. +
  546. +    if (r->connection->read->timedout) {
  547. +        r->connection->timedout = 1;
  548. +        ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  549. +        return;
  550. +    }
  551. +
  552. +    rc = ngx_http_do_read_client_request_body(r);
  553. +
  554. +    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
  555. +        ngx_http_finalize_request(r, rc);
  556. +    }
  557. +}
  558. +
  559. +
  560.  ngx_int_t /* {{{ ngx_http_read_upload_client_request_body */
  561.  ngx_http_read_upload_client_request_body(ngx_http_request_t *r) {
  562.      ssize_t                    size, preread;
  563.  -2625,9 +3164,9 @@
  564.  
  565.              /* the whole request body may be placed in r->header_in */
  566.  
  567. -            rb->to_write = rb->bufs;
  568. -
  569. -            r->read_event_handler = ngx_http_read_upload_client_request_body_handler;
  570. +            rb->buf = r->header_in;
  571. +            r->read_event_handler = ngx_http_read_client_request_body_handler;
  572. +            r->write_event_handler = ngx_http_request_empty_handler;
  573.  
  574.              return ngx_http_do_read_upload_client_request_body(r);
  575.          }
  576.  -2684,7 +3223,9 @@
  577.  
  578.      *next = cl;
  579.  
  580. -    rb->to_write = rb->bufs;
  581. +    /*
  582. +     * rb->to_write = rb->bufs;
  583. +     */
  584.  
  585.      r->read_event_handler = ngx_http_read_upload_client_request_body_handler;
  586.  
  587.  -2766,7 +3307,7 @@
  588.          for ( ;; ) {
  589.              if (rb->buf->last == rb->buf->end) {
  590.  
  591. -                rc = ngx_http_process_request_body(r, rb->to_write);
  592. +                 rc = ngx_http_process_request_body(r, rb->bufs);
  593.  
  594.                  switch(rc) {
  595.                      case NGX_OK:
  596.  -2781,8 +3322,9 @@
  597.                      default:
  598.                          return NGX_HTTP_INTERNAL_SERVER_ERROR;
  599.                  }
  600. -
  601. -                rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs;
  602. +              /*
  603. +               * rb->to_write = rb->bufs->next ? rb->bufs->next : rb->bufs;
  604. +               */
  605.                  rb->buf->last = rb->buf->start;
  606.              }
  607.  
  608.  -2874,7 +3416,7 @@
  609.          ngx_del_timer(c->read);
  610.      }
  611.  
  612. -    rc = ngx_http_process_request_body(r, rb->to_write);
  613. +    rc = ngx_http_process_request_body(r, rb->bufs);
  614.  
  615.      switch(rc) {
  616.          case NGX_OK:
Language:
To highlight particular lines, prefix each line with @@



© 2014 - Powered by PASTE 1.0