1use strict;
2use warnings;
3
4use File::Basename qw(dirname);
5
6use lib dirname(__FILE__) . "/lib";
7
8use Test::Nginx::Socket tests => 24;
9use Test::Nginx::UploadModule;
10
11our $configs = {
12    hash_funcs => q[
13        location = /upload/ {
14            upload_pass @upstream;
15            upload_resumable on;
16            upload_aggregate_form_field "upload_file_crc32" "$upload_file_crc32";
17            upload_aggregate_form_field "upload_file_md5" "$upload_file_md5";
18            upload_aggregate_form_field "upload_file_md5_uc" "$upload_file_md5_uc";
19            upload_aggregate_form_field "upload_file_sha1" "$upload_file_sha1";
20            upload_aggregate_form_field "upload_file_sha1_uc" "$upload_file_sha1_uc";
21            upload_aggregate_form_field "upload_file_sha256" "$upload_file_sha256";
22            upload_aggregate_form_field "upload_file_sha256_uc" "$upload_file_sha256_uc";
23            upload_aggregate_form_field "upload_file_sha512" "$upload_file_sha512";
24            upload_aggregate_form_field "upload_file_sha512_uc" "$upload_file_sha512_uc";
25            upload_set_form_field "upload_tmp_path" "$upload_tmp_path";
26        }
27    ],
28    simple => q[
29        location = /upload/ {
30            upload_pass @upstream;
31            upload_resumable on;
32            upload_aggregate_form_field "upload_file_number" "$upload_file_number";
33            upload_aggregate_form_field "upload_file_size" "$upload_file_size";
34            upload_set_form_field "upload_tmp_path" "$upload_tmp_path";
35        }
36    ],
37};
38
39our $session_id = 0;
40
41our $requests = {
42    single_chunk => {
43        headers => sub { join("\n",
44            'X-Content-Range: bytes 0-3/4',
45            'Session-ID: ' . ++$session_id,
46            'Content-Type: text/plain',
47            'Content-Disposition: form-data; name="file"; filename="test.txt"');
48        },
49        body => "POST /upload/\ntest",
50    },
51    multi_chunk => {
52        headers => sub { [
53            join("\n",
54                'X-Content-Range: bytes 0-131071/262144',
55                'Session-ID: ' . ++$session_id,
56                'Content-Type: text/plain',
57                'Content-Disposition: form-data; name="file"; filename="test.txt"'),
58            join("\n",
59                'X-Content-Range: bytes 131072-262143/262144',
60                'Session-ID: ' . $session_id,
61                'Content-Type: text/plain',
62                'Content-Disposition: form-data; name="file"; filename="test.txt"'),
63        ] },
64        body => [
65            ["POST /upload/\r\n", "a" x 131072],
66            ["POST /upload/\r\n", "b" x 131072],
67        ],
68    },
69    standard => {
70        raw_request => sub { join("\r\n",
71            "POST /upload/ HTTP/1.1",
72            "Host: 127.0.0.1",
73            "Connection: Close",
74            "Content-Type: multipart/form-data; boundary=------123456789",
75            "Content-Length: 262252",
76            "",
77            "--------123456789",
78            "Content-Disposition: form-data; name=\"file\"; filename=\"test.txt\"",
79            "",
80            ("a" x 131072) . ("b" x 131072),
81            "--------123456789",
82            "");
83        },
84    },
85};
86
87no_long_string();
88no_shuffle();
89run_tests();
90
91__DATA__
92=== TEST 1: single chunk upload
93--- config eval: $::configs->{simple}
94--- more_headers eval: $::requests->{single_chunk}->{headers}->()
95--- request eval: $::requests->{single_chunk}->{body}
96--- error_code: 200
97--- response_body eval
98qq{upload_file_number = 1
99upload_file_size = 4
100upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/$::session_id/$::session_id
101}
102--- upload_file_like eval
103qr/^test$/
104
105=== TEST 2: single chunk upload (http2)
106--- config eval: $::configs->{simple}
107--- http2
108--- skip_nginx
1093: < 1.10.0
110--- more_headers eval: $::requests->{single_chunk}->{headers}->()
111--- request eval: $::requests->{single_chunk}->{body}
112--- error_code: 200
113--- response_body eval
114qq{upload_file_number = 1
115upload_file_size = 4
116upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/$::session_id/$::session_id
117}
118--- upload_file_like eval
119qr/^test$/
120
121=== TEST 3: multi-chunk uploads
122--- config eval: $::configs->{simple}
123--- more_headers eval: $::requests->{multi_chunk}->{headers}->()
124--- request eval: $::requests->{multi_chunk}->{body}
125--- error_code eval
126[201, 200]
127--- response_body eval
128["0-131071/262144", qq{upload_file_number = 1
129upload_file_size = 262144
130upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/$::session_id/$::session_id
131}]
132--- upload_file_like eval
133qr/^(??{'a' x 131072 . 'b' x 131072})$/
134
135=== TEST 4: multi-chunk uploads (hash funcs)
136--- config eval: $::configs->{hash_funcs}
137--- more_headers eval: $::requests->{multi_chunk}->{headers}->()
138--- request eval: $::requests->{multi_chunk}->{body}
139--- error_code eval
140[201, 200]
141--- response_body eval
142["0-131071/262144", qq{upload_file_crc32 =
143upload_file_md5 =
144upload_file_md5_uc =
145upload_file_sha1 =
146upload_file_sha1_uc =
147upload_file_sha256 =
148upload_file_sha256_uc =
149upload_file_sha512 =
150upload_file_sha512_uc =
151upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/$::session_id/$::session_id
152}]
153--- upload_file_like eval
154qr/^(??{'a' x 131072 . 'b' x 131072})$/
155
156=== TEST 5: multi-chunk uploads out of order
157--- todo
1582: BUG https://github.com/fdintino/nginx-upload-module/issues/106
159--- config eval: $::configs->{simple}
160--- more_headers eval: [ CORE::reverse @{$::requests->{multi_chunk}->{headers}->()} ]
161--- request eval: [ CORE::reverse @{$::requests->{multi_chunk}->{body}}]
162--- error_code eval
163[201, 200]
164--- response_body eval
165["131072-262143/262144", qq{upload_file_number = 1
166upload_file_size = 262144
167upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/$::session_id/$::session_id
168}]
169
170=== TEST 6: multipart/form-data
171--- config eval: $::configs->{simple}
172--- raw_request eval: $::requests->{standard}->{raw_request}->()
173--- error_code: 200
174--- response_body eval
175qq{upload_file_number = 1
176upload_file_size = 262144
177upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/1/0000000001
178}
179--- upload_file_like eval
180qr/^(??{'a' x 131072 . 'b' x 131072})$/
181
182=== TEST 7: multipart/form-data (hash fields)
183--- config eval: $::configs->{hash_funcs}
184--- raw_request eval: $::requests->{standard}->{raw_request}->()
185--- error_code: 200
186--- response_body eval
187qq{upload_file_crc32 = db99345e
188upload_file_md5 = 01f2c9f3ccdf9c44f733ff443228e66d
189upload_file_md5_uc = 01F2C9F3CCDF9C44F733FF443228E66D
190upload_file_sha1 = a2eb84a7bee5e2263e9a3cffae44a4a11044bb2e
191upload_file_sha1_uc = A2EB84A7BEE5E2263E9A3CFFAE44A4A11044BB2E
192upload_file_sha256 = 58a200a96c5ef282be0d02ab6906655513584bf281bef027b842c2e66b1c56c7
193upload_file_sha256_uc = 58A200A96C5EF282BE0D02AB6906655513584BF281BEF027B842C2E66B1C56C7
194upload_file_sha512 = fa5af601c85900b80f40865a74a71a74ba382b51336543ba72b31d2e0af80867c1862051763ea9309f637b2ad6133b6e170e4f088a2951a3d05d6fe3a5bcd0e9
195upload_file_sha512_uc = FA5AF601C85900B80F40865A74A71A74BA382B51336543BA72B31D2E0AF80867C1862051763EA9309F637B2AD6133B6E170E4F088A2951A3D05D6FE3A5BCD0E9
196upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/8/0000123458
197}
198--- upload_file_like eval
199qr/^(??{'a' x 131072 . 'b' x 131072})$/
200