在 Yaws 网络服务器上上传进度
Upload with progress on Yaws webserver
我正在 Yaws 2.0 上测试脚本 upload2.yaws ,但无法正常工作。该脚本是为 Yaws 1.57 开发的。
来自 Yaws 的日志是:
POST /html/upload2.yaws HTTP/1.1
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Host: 192.168.26.10
Referer: http://192.168.26.10/html/upload2.yaws
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
Cookie: gsScrollPos=0; gsScrollPos=0
Content-Length: 1587
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5zKIyUtdiK82R4de
Accept-Language: pt,en-US;q=0.8,en;q=0.6,pt-BR;q=0.4
Accept-Encoding: gzip, deflate
Https: 1
Origin: http://192.168.26.10
Cache-Control: max-age=0
upload.yaws:multipart/3 State=filename=undefined rlist=undefined data=undefined
upload.yaws:multipart/3 result
upload.yaws:process_part/4d State=filename=undefined rlist=undefined data=undefined
upload.yaws:multipart/3 done
upload.yaws:result_ehtml/3 error Reason=Error: filename not found in header.
Worker: <0.78.0>
[2015-07-24 13:50:54.795] ===== SRV -> CLI =====
HTTP/1.1 200 OK
Server: Yaws 2.0
Date: Fri, 24 Jul 2015 13:50:54 GMT
Content-Length: 532
Content-Type: text/html
当我将表单操作更改为使用 netcat 的侦听端口时,收到完整的 header 文件名:
代码:
show_form(A, Feedback) -> {ehtml,
[ {form
,[{enctype,"multipart/form-data"},{action,"http://192.168.26.10:8800"},{method,"post"}]
, [{p,[],"Choose a file and click Upload."}
,{p,[],{input,[{type,"file"},{name,"file"}],[]}}
,{p,[],{input,[{type,"submit"},{value,"Upload"}],[]}}
]
}
,{p,[],Feedback}
]}.
我启动了 nc
$ sudo nc -l 8800
然后显示如下header:
POST / HTTP/1.1
Host: 192.168.26.10:8800
Connection: keep-alive
Content-Length: 1587
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://192.168.26.10
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
HTTPS: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9iHQOXBtRE9CyRAZ
Referer: http://192.168.26.10/html/upload2.yaws
Accept-Encoding: gzip, deflate
Accept-Language: pt,en-US;q=0.8,en;q=0.6,pt-BR;q=0.4
Cookie: gsScrollPos=0
------WebKitFormBoundary9iHQOXBtRE9CyRAZ
Content-Disposition: form-data; name="file"; filename="signing_debian_packages.txt"
Content-Type: text/plain
我怀疑错误出在 multipart 函数上,但我是 Erlang 菜鸟:/
%%% Process part of a multi-part form post
%%% returns Ehtml | {get_more, Continuation, NewState}
multipart(A, State) when is_record(State,upload) ->
io:fwrite("upload.yaws:multipart/3 State=~s~n", [upload_to_string(State)]),
case yaws_api:parse_multipart_post(A) of
{cont, Cont, Part} ->
io:fwrite("upload.yaws:multipart/3 cont~n"),
case process_part(A, Part, State) of
{done, Result} ->
io:fwrite("upload.yaws:multipart/3 done~n"),
result_ehtml(A, Result);
{cont, NewState} ->
io:fwrite("upload.yaws:multipart/3 get_more NewState=~s~n", [upload_to_string(NewState)]),
{get_more, Cont, NewState}
end;
{result, Part} ->
io:fwrite("upload.yaws:multipart/3 result~n"),
case process_part(A, Part, State#upload{last=true}) of
{done, Result} ->
io:fwrite("upload.yaws:multipart/3 done~n"),
result_ehtml(A, Result);
{cont, _} ->
io:fwrite("upload.yaws:multipart/3 error~n"),
result_ehtml(A, {error, "Error During Upload"})
end;
[] -> result_ehtml(A, {error,"You must select a file to upload."})
end.
有人有想法吗?
问题出在处理 header:
的 process_part
函数子句中
%%% Process header
process_part(A, [{head, {"file", Opts}}|Tail], State ) ->
io:fwrite("upload.yaws:process_part/4d State=~s~n", [upload_to_string(State)]),
case lists:keysearch(filename, 1, Opts) of
{value, {_, UncheckedFileName}} ->
io:fwrite("upload.yaws:process_part/4d UncheckedFileName=~s~n", [UncheckedFileName]),
FileName = sanitize_filename(UncheckedFileName),
io:fwrite("upload.yaws:process_part/4d FileName=~s~n", [FileName]),
process_part(A, Tail, State#upload{filename=FileName,rlist=[]});
false ->
{done, {error, "Error: filename not found in header."}}
end;
调用 lists:keysearch/3
的第一个参数是原子 filename
,但它应该是字符串 "filename"
。修改后的函数为:
%%% Process header
process_part(A, [{head, {"file", Opts}}|Tail], State ) ->
io:fwrite("upload.yaws:process_part/4d State=~s~n", [upload_to_string(State)]),
case lists:keysearch("filename", 1, Opts) of
{value, {_, UncheckedFileName}} ->
io:fwrite("upload.yaws:process_part/4d UncheckedFileName=~s~n", [UncheckedFileName]),
FileName = sanitize_filename(UncheckedFileName),
io:fwrite("upload.yaws:process_part/4d FileName=~s~n", [FileName]),
process_part(A, Tail, State#upload{filename=FileName,rlist=[]});
false ->
{done, {error, "Error: filename not found in header."}}
end;
有了这个改变,upload2.yaws
对我来说在 Yaws 2.0 和 Erlang 18.0 上工作得很好。
我正在 Yaws 2.0 上测试脚本 upload2.yaws ,但无法正常工作。该脚本是为 Yaws 1.57 开发的。
来自 Yaws 的日志是:
POST /html/upload2.yaws HTTP/1.1
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Host: 192.168.26.10
Referer: http://192.168.26.10/html/upload2.yaws
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
Cookie: gsScrollPos=0; gsScrollPos=0
Content-Length: 1587
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5zKIyUtdiK82R4de
Accept-Language: pt,en-US;q=0.8,en;q=0.6,pt-BR;q=0.4
Accept-Encoding: gzip, deflate
Https: 1
Origin: http://192.168.26.10
Cache-Control: max-age=0
upload.yaws:multipart/3 State=filename=undefined rlist=undefined data=undefined
upload.yaws:multipart/3 result
upload.yaws:process_part/4d State=filename=undefined rlist=undefined data=undefined
upload.yaws:multipart/3 done
upload.yaws:result_ehtml/3 error Reason=Error: filename not found in header.
Worker: <0.78.0>
[2015-07-24 13:50:54.795] ===== SRV -> CLI =====
HTTP/1.1 200 OK
Server: Yaws 2.0
Date: Fri, 24 Jul 2015 13:50:54 GMT
Content-Length: 532
Content-Type: text/html
当我将表单操作更改为使用 netcat 的侦听端口时,收到完整的 header 文件名:
代码:
show_form(A, Feedback) -> {ehtml,
[ {form
,[{enctype,"multipart/form-data"},{action,"http://192.168.26.10:8800"},{method,"post"}]
, [{p,[],"Choose a file and click Upload."}
,{p,[],{input,[{type,"file"},{name,"file"}],[]}}
,{p,[],{input,[{type,"submit"},{value,"Upload"}],[]}}
]
}
,{p,[],Feedback}
]}.
我启动了 nc
$ sudo nc -l 8800
然后显示如下header:
POST / HTTP/1.1
Host: 192.168.26.10:8800
Connection: keep-alive
Content-Length: 1587
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://192.168.26.10
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36
HTTPS: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary9iHQOXBtRE9CyRAZ
Referer: http://192.168.26.10/html/upload2.yaws
Accept-Encoding: gzip, deflate
Accept-Language: pt,en-US;q=0.8,en;q=0.6,pt-BR;q=0.4
Cookie: gsScrollPos=0
------WebKitFormBoundary9iHQOXBtRE9CyRAZ
Content-Disposition: form-data; name="file"; filename="signing_debian_packages.txt"
Content-Type: text/plain
我怀疑错误出在 multipart 函数上,但我是 Erlang 菜鸟:/
%%% Process part of a multi-part form post
%%% returns Ehtml | {get_more, Continuation, NewState}
multipart(A, State) when is_record(State,upload) ->
io:fwrite("upload.yaws:multipart/3 State=~s~n", [upload_to_string(State)]),
case yaws_api:parse_multipart_post(A) of
{cont, Cont, Part} ->
io:fwrite("upload.yaws:multipart/3 cont~n"),
case process_part(A, Part, State) of
{done, Result} ->
io:fwrite("upload.yaws:multipart/3 done~n"),
result_ehtml(A, Result);
{cont, NewState} ->
io:fwrite("upload.yaws:multipart/3 get_more NewState=~s~n", [upload_to_string(NewState)]),
{get_more, Cont, NewState}
end;
{result, Part} ->
io:fwrite("upload.yaws:multipart/3 result~n"),
case process_part(A, Part, State#upload{last=true}) of
{done, Result} ->
io:fwrite("upload.yaws:multipart/3 done~n"),
result_ehtml(A, Result);
{cont, _} ->
io:fwrite("upload.yaws:multipart/3 error~n"),
result_ehtml(A, {error, "Error During Upload"})
end;
[] -> result_ehtml(A, {error,"You must select a file to upload."})
end.
有人有想法吗?
问题出在处理 header:
的process_part
函数子句中
%%% Process header
process_part(A, [{head, {"file", Opts}}|Tail], State ) ->
io:fwrite("upload.yaws:process_part/4d State=~s~n", [upload_to_string(State)]),
case lists:keysearch(filename, 1, Opts) of
{value, {_, UncheckedFileName}} ->
io:fwrite("upload.yaws:process_part/4d UncheckedFileName=~s~n", [UncheckedFileName]),
FileName = sanitize_filename(UncheckedFileName),
io:fwrite("upload.yaws:process_part/4d FileName=~s~n", [FileName]),
process_part(A, Tail, State#upload{filename=FileName,rlist=[]});
false ->
{done, {error, "Error: filename not found in header."}}
end;
调用 lists:keysearch/3
的第一个参数是原子 filename
,但它应该是字符串 "filename"
。修改后的函数为:
%%% Process header
process_part(A, [{head, {"file", Opts}}|Tail], State ) ->
io:fwrite("upload.yaws:process_part/4d State=~s~n", [upload_to_string(State)]),
case lists:keysearch("filename", 1, Opts) of
{value, {_, UncheckedFileName}} ->
io:fwrite("upload.yaws:process_part/4d UncheckedFileName=~s~n", [UncheckedFileName]),
FileName = sanitize_filename(UncheckedFileName),
io:fwrite("upload.yaws:process_part/4d FileName=~s~n", [FileName]),
process_part(A, Tail, State#upload{filename=FileName,rlist=[]});
false ->
{done, {error, "Error: filename not found in header."}}
end;
有了这个改变,upload2.yaws
对我来说在 Yaws 2.0 和 Erlang 18.0 上工作得很好。