1use strict;
2use warnings;
3
4use File::Basename qw(dirname);
5
6use lib dirname(__FILE__) . "/lib";
7
8use Test::Nginx::Socket tests => 27;
9use Test::Nginx::UploadModule;
10
11
12our $config = <<'_EOC_';
13location = /upload/ {
14    upload_pass @upstream;
15    upload_resumable on;
16
17    upload_set_form_field upload_file_name $upload_file_name;
18    upload_set_form_field upload_file_number $upload_file_number;
19    upload_set_form_field "upload_field_name" "$upload_field_name";
20    upload_set_form_field "upload_content_type" "$upload_content_type";
21    upload_set_form_field "upload_tmp_path" "$upload_tmp_path";
22    upload_set_form_field "upload_content_range" "$upload_content_range";
23    upload_max_file_size 0;
24    upload_pass_args on;
25    upload_cleanup 400 404 499 500-505;
26}
27_EOC_
28
29no_long_string();
30no_shuffle();
31run_tests();
32
33__DATA__
34=== TEST 1: single chunk upload
35--- config eval: $::config
36--- more_headers
37X-Content-Range: bytes 0-3/4
38Session-ID: 0000000001
39Content-Type: text/plain
40Content-Disposition: form-data; name="file"; filename="test.txt"
41--- request eval
42qq{POST /upload/
43test}
44--- error_code: 200
45--- response_body eval
46qq{upload_content_range = bytes 0-3/4
47upload_content_type = text/plain
48upload_field_name = file
49upload_file_name = test.txt
50upload_file_number = 1
51upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/1/0000000001
52}
53--- upload_file_like eval
54qr/^test$/
55
56=== TEST 2: multiple chunk uploads
57--- http_config eval: $::http_config
58--- config eval: $::config
59--- more_headers eval
60[qq{X-Content-Range: bytes 0-1/4
61Session-ID: 0000000002
62Content-Type: text/plain
63Content-Disposition: form-data; name="file"; filename="test.txt"},
64qq{X-Content-Range: bytes 2-3/4
65Session-ID: 0000000002
66Content-Type: text/plain
67Content-Disposition: form-data; name="file"; filename="test.txt"}]
68--- request eval
69[["POST /upload/\r\n",
70"te"],
71["POST /upload/\r\n",
72"st"]]
73--- error_code eval
74[201, 200]
75--- response_body eval
76["0-1/4", qq{upload_content_range = bytes 2-3/4
77upload_content_type = text/plain
78upload_field_name = file
79upload_file_name = test.txt
80upload_file_number = 1
81upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/2/0000000002
82}]
83--- upload_file_like eval
84qr/^test$/
85
86=== Test 3: large multiple chunk uploads
87--- config eval: $::config
88--- more_headers eval
89[qq{X-Content-Range: bytes 0-131071/262144
90Session-ID: 0000000003
91Content-Type: text/plain
92Content-Disposition: form-data; name="file"; filename="test.txt"},
93qq{X-Content-Range: bytes 131072-262143/262144
94Session-ID: 0000000003
95Content-Type: text/plain
96Content-Disposition: form-data; name="file"; filename="test.txt"}]
97--- request eval
98[["POST /upload/\r\n",
99"x" x 131072],
100["POST /upload/\r\n",
101"x" x 131072]]
102--- error_code eval
103[201, 200]
104--- response_body eval
105["0-131071/262144", qq{upload_content_range = bytes 131072-262143/262144
106upload_content_type = text/plain
107upload_field_name = file
108upload_file_name = test.txt
109upload_file_number = 1
110upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/3/0000000003
111}]
112--- upload_file_like eval
113qr/^(??{'x' x 262144})$/
114
115=== Test 4: upload_limit_rate
116--- config
117location = /upload/ {
118    upload_pass @upstream;
119    upload_resumable on;
120    upload_set_form_field "upload_tmp_path" "$upload_tmp_path";
121    upload_max_file_size 0;
122    upload_pass_args on;
123    upload_cleanup 400 404 499 500-505;
124    upload_limit_rate 32768;
125}
126--- timeout: 5
127--- more_headers eval
128[qq{X-Content-Range: bytes 0-131071/262144
129Session-ID: 0000000004
130Content-Type: text/plain
131Content-Disposition: form-data; name="file"; filename="test.txt"},
132qq{X-Content-Range: bytes 131072-262143/262144
133Session-ID: 0000000004
134Content-Type: text/plain
135Content-Disposition: form-data; name="file"; filename="test.txt"}]
136--- request eval
137[["POST /upload/\r\n",
138"x" x 131072],
139["POST /upload/\r\n",
140"x" x 131072]]
141--- error_code eval
142[201, 200]
143--- response_body eval
144["0-131071/262144", qq{upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/4/0000000004
145}]
146--- upload_file_like eval
147qr/^(??{'x' x 262144})$/
148--- access_log eval
149# should have taken 4 seconds, with 1 second possible error
150# (Test::Nginx::UploadModule::http_config adds request time to the end of
151# the access log)
152[qr/[34]\.\d\d\d$/, qr/[34]\.\d\d\d$/]
153
154=== TEST 5: multiple chunk uploads out-of-order
155--- config eval: $::config
156--- more_headers eval
157[qq{X-Content-Range: bytes 131072-262143/262144
158Session-ID: 0000000005
159Content-Type: text/plain
160Content-Disposition: form-data; name="file"; filename="test.txt"},
161qq{X-Content-Range: bytes 0-131071/262144
162Session-ID: 0000000005
163Content-Type: text/plain
164Content-Disposition: form-data; name="file"; filename="test.txt"}]
165--- request eval
166[["POST /upload/\r\n",
167"b" x 131072],
168["POST /upload/\r\n",
169"a" x 131072]]
170--- error_code eval
171[201, 200]
172--- response_body eval
173["131072-262143/262144", qq{upload_content_range = bytes 0-131071/262144
174upload_content_type = text/plain
175upload_field_name = file
176upload_file_name = test.txt
177upload_file_number = 1
178upload_tmp_path = ${ENV{TEST_NGINX_UPLOAD_PATH}}/store/5/0000000005
179}]
180--- upload_file_like eval
181qr/^(??{'a' x 131072 . 'b' x 131072})$/
182