nxt_h1proto.c (1401:c88f739aac1c) nxt_h1proto.c (1403:1cee885b7f10)
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_router.h>
8#include <nxt_http.h>

--- 803 unchanged lines hidden (view full) ---

812
813 return NXT_OK;
814}
815
816
817static void
818nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r)
819{
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_router.h>
8#include <nxt_http.h>

--- 803 unchanged lines hidden (view full) ---

812
813 return NXT_OK;
814}
815
816
817static void
818nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r)
819{
820 size_t size, body_length;
820 size_t size, body_length, body_buffer_size, body_rest;
821 ssize_t res;
822 nxt_str_t *tmp_path, tmp_name;
821 nxt_buf_t *in, *b;
822 nxt_conn_t *c;
823 nxt_h1proto_t *h1p;
824 nxt_http_status_t status;
825
823 nxt_buf_t *in, *b;
824 nxt_conn_t *c;
825 nxt_h1proto_t *h1p;
826 nxt_http_status_t status;
827
828 static const nxt_str_t tmp_name_pattern = nxt_string("/req-XXXXXXXX");
829
826 h1p = r->proto.h1;
827
828 nxt_debug(task, "h1p request body read %O te:%d",
829 r->content_length_n, h1p->transfer_encoding);
830
831 switch (h1p->transfer_encoding) {
832
833 case NXT_HTTP_TE_CHUNKED:

--- 10 unchanged lines hidden (view full) ---

844 }
845
846 if (r->content_length_n == -1 || r->content_length_n == 0) {
847 goto ready;
848 }
849
850 body_length = (size_t) r->content_length_n;
851
830 h1p = r->proto.h1;
831
832 nxt_debug(task, "h1p request body read %O te:%d",
833 r->content_length_n, h1p->transfer_encoding);
834
835 switch (h1p->transfer_encoding) {
836
837 case NXT_HTTP_TE_CHUNKED:

--- 10 unchanged lines hidden (view full) ---

848 }
849
850 if (r->content_length_n == -1 || r->content_length_n == 0) {
851 goto ready;
852 }
853
854 body_length = (size_t) r->content_length_n;
855
852 b = r->body;
856 body_buffer_size = nxt_min(r->conf->socket_conf->body_buffer_size,
857 body_length);
853
858
854 if (b == NULL) {
855 b = nxt_buf_mem_alloc(r->mem_pool, body_length, 0);
856 if (nxt_slow_path(b == NULL)) {
859 if (body_length > body_buffer_size) {
860 tmp_path = &r->conf->socket_conf->body_temp_path;
861
862 tmp_name.length = tmp_path->length + tmp_name_pattern.length;
863
864 b = nxt_buf_file_alloc(r->mem_pool,
865 body_buffer_size + sizeof(nxt_file_t)
866 + tmp_name.length + 1, 0);
867
868 } else {
869 /* This initialization required for CentOS 6, gcc 4.4.7. */
870 tmp_path = NULL;
871 tmp_name.length = 0;
872
873 b = nxt_buf_mem_alloc(r->mem_pool, body_buffer_size, 0);
874 }
875
876 if (nxt_slow_path(b == NULL)) {
877 status = NXT_HTTP_INTERNAL_SERVER_ERROR;
878 goto error;
879 }
880
881 r->body = b;
882
883 if (body_length > body_buffer_size) {
884 tmp_name.start = nxt_pointer_to(b->mem.start, sizeof(nxt_file_t));
885
886 memcpy(tmp_name.start, tmp_path->start, tmp_path->length);
887 memcpy(tmp_name.start + tmp_path->length, tmp_name_pattern.start,
888 tmp_name_pattern.length);
889 tmp_name.start[tmp_name.length] = '\0';
890
891 b->file = (nxt_file_t *) b->mem.start;
892 nxt_memzero(b->file, sizeof(nxt_file_t));
893 b->file->fd = -1;
894 b->file->size = body_length;
895
896 b->mem.start += sizeof(nxt_file_t) + tmp_name.length + 1;
897 b->mem.pos = b->mem.start;
898 b->mem.free = b->mem.start;
899
900 b->file->fd = mkstemp((char *) tmp_name.start);
901 if (nxt_slow_path(b->file->fd == -1)) {
902 nxt_log(task, NXT_LOG_ERR, "mkstemp() failed %E", nxt_errno);
903
857 status = NXT_HTTP_INTERNAL_SERVER_ERROR;
858 goto error;
859 }
860
904 status = NXT_HTTP_INTERNAL_SERVER_ERROR;
905 goto error;
906 }
907
861 r->body = b;
908 nxt_debug(task, "create body tmp file \"%V\", %d",
909 &tmp_name, b->file->fd);
910
911 unlink((char *) tmp_name.start);
862 }
863
912 }
913
914 body_rest = body_length;
915
864 in = h1p->conn->read;
865
866 size = nxt_buf_mem_used_size(&in->mem);
867
868 if (size != 0) {
916 in = h1p->conn->read;
917
918 size = nxt_buf_mem_used_size(&in->mem);
919
920 if (size != 0) {
869 if (size > body_length) {
870 size = body_length;
921 size = nxt_min(size, body_length);
922
923 if (nxt_buf_is_file(b)) {
924 res = nxt_fd_write(b->file->fd, in->mem.pos, size);
925 if (nxt_slow_path(res < (ssize_t) size)) {
926 status = NXT_HTTP_INTERNAL_SERVER_ERROR;
927 goto error;
928 }
929
930 b->file_end += size;
931
932 } else {
933 size = nxt_min(body_buffer_size, size);
934 b->mem.free = nxt_cpymem(b->mem.free, in->mem.pos, size);
935 body_buffer_size -= size;
871 }
872
936 }
937
873 b->mem.free = nxt_cpymem(b->mem.free, in->mem.pos, size);
874 in->mem.pos += size;
938 in->mem.pos += size;
939 body_rest -= size;
875 }
876
940 }
941
877 size = nxt_buf_mem_free_size(&b->mem);
942 nxt_debug(task, "h1p body rest: %uz", body_rest);
878
943
879 nxt_debug(task, "h1p body rest: %uz", size);
880
881 if (size != 0) {
944 if (body_rest != 0) {
882 in->next = h1p->buffers;
883 h1p->buffers = in;
884 h1p->nbuffers++;
885
886 c = h1p->conn;
887 c->read = b;
888 c->read_state = &nxt_h1p_read_body_state;
889
890 nxt_conn_read(task->thread->engine, c);
891 return;
892 }
893
945 in->next = h1p->buffers;
946 h1p->buffers = in;
947 h1p->nbuffers++;
948
949 c = h1p->conn;
950 c->read = b;
951 c->read_state = &nxt_h1p_read_body_state;
952
953 nxt_conn_read(task->thread->engine, c);
954 return;
955 }
956
957 if (nxt_buf_is_file(b)) {
958 b->mem.start = NULL;
959 b->mem.end = NULL;
960 b->mem.pos = NULL;
961 b->mem.free = NULL;
962 }
963
894ready:
895
896 r->state->ready_handler(task, r, NULL);
897
898 return;
899
900error:
901

--- 15 unchanged lines hidden (view full) ---

917 .timer_data = offsetof(nxt_socket_conf_t, body_read_timeout),
918 .timer_autoreset = 1,
919};
920
921
922static void
923nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, void *data)
924{
964ready:
965
966 r->state->ready_handler(task, r, NULL);
967
968 return;
969
970error:
971

--- 15 unchanged lines hidden (view full) ---

987 .timer_data = offsetof(nxt_socket_conf_t, body_read_timeout),
988 .timer_autoreset = 1,
989};
990
991
992static void
993nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, void *data)
994{
925 size_t size;
995 size_t size, body_rest;
996 ssize_t res;
997 nxt_buf_t *b;
926 nxt_conn_t *c;
927 nxt_h1proto_t *h1p;
928 nxt_http_request_t *r;
929 nxt_event_engine_t *engine;
930
931 c = obj;
932 h1p = data;
933
934 nxt_debug(task, "h1p conn request body read");
935
998 nxt_conn_t *c;
999 nxt_h1proto_t *h1p;
1000 nxt_http_request_t *r;
1001 nxt_event_engine_t *engine;
1002
1003 c = obj;
1004 h1p = data;
1005
1006 nxt_debug(task, "h1p conn request body read");
1007
936 size = nxt_buf_mem_free_size(&c->read->mem);
1008 r = h1p->request;
937
1009
938 nxt_debug(task, "h1p body rest: %uz", size);
939
940 engine = task->thread->engine;
941
1010 engine = task->thread->engine;
1011
942 if (size != 0) {
1012 b = c->read;
1013
1014 if (nxt_buf_is_file(b)) {
1015 body_rest = b->file->size - b->file_end;
1016
1017 size = nxt_buf_mem_used_size(&b->mem);
1018 size = nxt_min(size, body_rest);
1019
1020 res = nxt_fd_write(b->file->fd, b->mem.pos, size);
1021 if (nxt_slow_path(res < (ssize_t) size)) {
1022 nxt_h1p_request_error(task, h1p, r);
1023 return;
1024 }
1025
1026 b->file_end += size;
1027 body_rest -= res;
1028
1029 b->mem.pos += size;
1030
1031 if (b->mem.pos == b->mem.free) {
1032 if (body_rest >= (size_t) nxt_buf_mem_size(&b->mem)) {
1033 b->mem.free = b->mem.start;
1034
1035 } else {
1036 /* This required to avoid reading next request. */
1037 b->mem.free = b->mem.end - body_rest;
1038 }
1039
1040 b->mem.pos = b->mem.free;
1041 }
1042
1043 } else {
1044 body_rest = nxt_buf_mem_free_size(&c->read->mem);
1045 }
1046
1047 nxt_debug(task, "h1p body rest: %uz", body_rest);
1048
1049 if (body_rest != 0) {
943 nxt_conn_read(engine, c);
944
945 } else {
1050 nxt_conn_read(engine, c);
1051
1052 } else {
1053 if (nxt_buf_is_file(b)) {
1054 b->mem.start = NULL;
1055 b->mem.end = NULL;
1056 b->mem.pos = NULL;
1057 b->mem.free = NULL;
1058 }
1059
946 c->read = NULL;
1060 c->read = NULL;
947 r = h1p->request;
948
949 r->state->ready_handler(task, r, NULL);
950 }
951}
952
953
954static void
955nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r)

--- 1179 unchanged lines hidden (view full) ---

2135 header->mem.free = p;
2136 size = p - header->mem.pos;
2137
2138 c = peer->proto.h1->conn;
2139 c->write = header;
2140 c->write_state = &nxt_h1p_peer_header_send_state;
2141
2142 if (r->body != NULL) {
1061
1062 r->state->ready_handler(task, r, NULL);
1063 }
1064}
1065
1066
1067static void
1068nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r)

--- 1179 unchanged lines hidden (view full) ---

2248 header->mem.free = p;
2249 size = p - header->mem.pos;
2250
2251 c = peer->proto.h1->conn;
2252 c->write = header;
2253 c->write_state = &nxt_h1p_peer_header_send_state;
2254
2255 if (r->body != NULL) {
2143 body = nxt_buf_mem_alloc(r->mem_pool, 0, 0);
2256 if (nxt_buf_is_file(r->body)) {
2257 body = nxt_buf_file_alloc(r->mem_pool, 0, 0);
2258
2259 } else {
2260 body = nxt_buf_mem_alloc(r->mem_pool, 0, 0);
2261 }
2262
2144 if (nxt_slow_path(body == NULL)) {
2145 r->state->error_handler(task, r, peer);
2146 return;
2147 }
2148
2149 header->next = body;
2150
2263 if (nxt_slow_path(body == NULL)) {
2264 r->state->error_handler(task, r, peer);
2265 return;
2266 }
2267
2268 header->next = body;
2269
2151 body->mem = r->body->mem;
2152 size += nxt_buf_mem_used_size(&body->mem);
2270 if (nxt_buf_is_file(r->body)) {
2271 body->file = r->body->file;
2272 body->file_end = r->body->file_end;
2153
2273
2274 } else {
2275 body->mem = r->body->mem;
2276 }
2277
2278 size += nxt_buf_used_size(body);
2279
2154// nxt_mp_retain(r->mem_pool);
2155 }
2156
2157 if (size > 16384) {
2158 /* Use proxy_send_timeout instead of proxy_timeout. */
2159 c->write_state = &nxt_h1p_peer_header_body_send_state;
2160 }
2161

--- 38 unchanged lines hidden (view full) ---

2200 peer = data;
2201
2202 nxt_debug(task, "h1p peer header sent");
2203
2204 engine = task->thread->engine;
2205
2206 c->write = nxt_sendbuf_completion(task, &engine->fast_work_queue, c->write);
2207
2280// nxt_mp_retain(r->mem_pool);
2281 }
2282
2283 if (size > 16384) {
2284 /* Use proxy_send_timeout instead of proxy_timeout. */
2285 c->write_state = &nxt_h1p_peer_header_body_send_state;
2286 }
2287

--- 38 unchanged lines hidden (view full) ---

2326 peer = data;
2327
2328 nxt_debug(task, "h1p peer header sent");
2329
2330 engine = task->thread->engine;
2331
2332 c->write = nxt_sendbuf_completion(task, &engine->fast_work_queue, c->write);
2333
2208 if (c->write == NULL) {
2209 r = peer->request;
2210 r->state->ready_handler(task, r, peer);
2334 if (c->write != NULL) {
2335 nxt_conn_write(engine, c);
2211 return;
2212 }
2213
2336 return;
2337 }
2338
2214 nxt_conn_write(engine, c);
2339 r = peer->request;
2340 r->state->ready_handler(task, r, peer);
2215}
2216
2217
2218static void
2219nxt_h1p_peer_header_read(nxt_task_t *task, nxt_http_peer_t *peer)
2220{
2221 nxt_conn_t *c;
2222

--- 401 unchanged lines hidden ---
2341}
2342
2343
2344static void
2345nxt_h1p_peer_header_read(nxt_task_t *task, nxt_http_peer_t *peer)
2346{
2347 nxt_conn_t *c;
2348

--- 401 unchanged lines hidden ---