Upload module fails in some cases

Hello,

I and using nginx 1.0.15 with the third-party module
nginx_upload_module-2.2.0/

When I am using an html form all works perfectly and I can see the
uploaded files and the post values as expected.

But, when I send the HTTP Post request from a Poco application, it does
not work. (pocoproject.org)

I am pasting below the code of that C++ Poco app. I don’t think that you
need to be an expert at Poco to understand it.

114 std::ostringstream content;
115 content << “------WebKitFormBoundaryq2BIJhJChD7qIY1W\r\n”;
116 content << “Content-Disposition: form-data;
name="submit"\r\n\r\n”
117 “Upload\r\n”
118 “------WebKitFormBoundaryq2BIJhJChD7qIY1W\r\n”;
119 content << “Content-Disposition: form-data; name="file";
filename="test.txt"\r\n\r\n”
120 “Content-Type: text/plain\r\n”
121 “This is a test.\r\n”
122 “------WebKitFormBoundaryq2BIJhJChD7qIY1W–”;
123
124 std::ostringstream os;
125 os << “POST /upload HTTP/1.0\r\n”
126 “Host: ip:31000\r\n”
127 “User-Agent: AAA\r\n”
128 “Accept:
text/plain,application/xhtml+xml,application/xml;q=0.9,/;q=0.8\r\n”
129 “Accept-Language:
en-us,ko;q=0.9,ja;q=0.7,cs;q=0.6,th;q=0.4,zh;q=0.3,en;q=0.1\r\n”
130 “Accept-Encoding: gzip,deflate\r\n”
131 “Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n”
132 “Referer: ip\r\n”
133 “Content-Type: multipart/form-data;
boundary=------WebKitFormBoundaryq2BIJhJChD7qIY1W\r\n”;
134
135 os << "Content-Length: " << strlen(content.str().c_str()) <<
“\r\n\r\n”;
136 os << content.str();
137
138 Poco::Net::SocketAddress sa(“ip”, 31000);
139 Poco::Net::StreamSocket socket(sa);
140 Poco::Net::SocketStream str(socket);
141 str << os.str();
142 str.flush();
143 Poco::StreamCopier::copyStream(str, std::cout);
144 return;

I am getting this from the server
HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Mon, 23 Apr 2012 02:00:45 GMT
Content-Type: text/html
Connection: close
X-Powered-By: PHP/5.1.6
Content-Length: 98


POST
Array
(
[<ngx_upload_module_dummy>] =>
)

FILES
Array
(
)




Drilling into
nginx_upload_module-2.2.0/ngx_http_upload_module.c
It seems that the problem is inside the function
static ngx_int_t upload_process_buf(ngx_http_upload_ctx_t *upload_ctx,
u_char *start, u_char *end)
and more precisely, it appears that from the html from the scope below
is entered while from the poco app it is never entered

3509 if(upload_ctx->boundary_pos == upload_ctx->boundary.data +
upload_ctx->boundary.len)
3510 {
3512 upload_ctx->state = upload_state_after_boundary;
3513 upload_ctx->boundary_start = upload_ctx->boundary.data;
3514 upload_ctx->boundary_pos = upload_ctx->boundary_start;
3515 }

maybe my header is wrong… I am running out of ideas to make this work

I am pasting below the config file:
1 #user nobody;
2 worker_processes 1;
3 #error_log logs/error.log;
4 error_log logs/debug.log debug;
5 #error_log logs/error.log info;
6 #pid logs/nginx.pid;
7 events {
8 worker_connections 1024;
9 }
10 http {
11
12 proxy_buffering on;
13 proxy_buffer_size 8k;
14 proxy_buffers 2048 8k;
15
16 include mime.types;
17 default_type application/octet-stream;
18 log_format main '$request_body $remote_addr - $remote_user
[$time_local] “$request” ’
19 '$status $body_bytes_sent “$http_referer” ’
20 ‘“$http_user_agent” “$http_x_forwarded_for”’;
21 access_log logs/access.log main;
22 sendfile on;
23 server_names_hash_max_size 1024;
24 server_names_hash_bucket_size 128;
25 client_body_temp_path /usr/local/nginx/uploads;
26 keepalive_timeout 65;
27
28 chunkin on;
29
30 server {
31 client_max_body_size 100m;
32 listen ip:31000;
33
34 #location /upload.php {
35 #location ~ .php$ {
36
37 error_page 411 = @my_error;
38 location @my_error {
39 chunkin_resume;
40 }
41 location /upload{
42
43 chunkin_resume;
44
45 # Pass altered request body to this location
46 upload_pass @uploadfiles;
47 upload_store /usr/local/nginx/uploads;
48 #upload_store_access user:r;
49 # Set specified fields in request body
50 upload_set_form_field $upload_field_name.name
“$upload_file_name”;
51 upload_set_form_field $upload_field_name.content_type
“$upload_content_type”;
52 upload_set_form_field $upload_field_name.path
“$upload_tmp_path”;
53 # Inform backend about hash and size of a file
54 #upload_aggregate_form_field “$upload_field_name.md5”
“$upload_file_md5”;
55 upload_aggregate_form_field “$upload_field_name.size”
“$upload_file_size”;
56 upload_pass_form_field “^username$|^password$”;
57 #upload_pass_form_field “.*”;
58 upload_cleanup 400 404 499 500-505;
59 upload_pass_args on;
60 upload_max_part_header_len 100m;
61 upload_max_output_body_len 0;
62 }
63 location ~ .php$ {
64 proxy_pass http://127.0.0.1:80;
65 }
66 location = /favicon.ico {
67 access_log off;
68 log_not_found off;
69 }
70 location /hello{
71 hello;
72 }
73 location @uploadfiles{
74 rewrite ^ /upload.php last;
75 #proxy_pass http://127.0.0.1:80;
76 }
77 location = /boom{
78 }
79 #location / {
80 # root html;
81 # index index.html index.htm;
82 #}
83 error_page 500 502 503 504 /50x.html;
84 #location = /50x.html {
85 # root html;
86 #}
87 }
88 }

Note that if I disable the module
'–add-module=/root/nginx/agentzh-chunkin-nginx-module-ddc0dd5", the
issue remains

Thanks in advance for any idea

Posted at Nginx Forum:

Hello!

On Sun, Apr 22, 2012 at 10:25:16PM -0400, JCR wrote:

119 content << “Content-Disposition: form-data; name=“file”;
filename=“test.txt”\r\n\r\n”
120 “Content-Type: text/plain\r\n”
121 “This is a test.\r\n”
122 “------WebKitFormBoundaryq2BIJhJChD7qIY1W–”;

4 dashes in the boundary here (following the ‘"–" boundary’
syntax as per RFC 2046).

131 “Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n”
132 “Referer: ip\r\n”
133 “Content-Type: multipart/form-data;
boundary=------WebKitFormBoundaryq2BIJhJChD7qIY1W\r\n”;

And 6 dashes here. This is unlikely to work.

Maxim D.

Hello Maxim

Thanks a lot! I went back to RFC 2046 and understood clearly my mistake

Posted at Nginx Forum: