如何http:在erlang中使用httpc:request发布文件?

时间:2016-08-30 08:33:29

标签: http post erlang

我曾经这样编码:

inets:start(),
ssl:start(),
ParaUrl = io_lib:format("http://xxx/passport?accessn=~s",[Access]),
ParaStr = io_lib:format("id=~p",[Id]),
RegUsr = httpc:request(post,{ParaUrl, [],"application/x-www-form-urlencoded", list_to_binary(ParaStr)},[],[])

但它只是字符串而不是二进制文件,谁能告诉我如何用httpc:request发布二进制文件?

2 个答案:

答案 0 :(得分:2)

它对我有用:

 {ok, F} = file:read_file("warning.gif"),
    httpc:request(post,{Url, [],"multipart/form-data", F},[],[]).

我在牛仔网络服务器上收到了函数cowboy_req:body(Req)

{ok,<<71,73,70,56,57,97,11,0,11,0,230,64,0............>>,
     {http_req,#Port<0.65562>,ranch_tcp,keepalive,<0.8736.0>,<<"POST">>,
               'HTTP/1.1',
               {{127,0,0,1},58154},
               <<"localhost">>,undefined,8000,<<"/test1">>,
               [<<"test1">>],
               <<>>,undefined,[],
               [{<<"content-type">>,<<"multipart/form-data">>},
                {<<"content-length">>,<<"516">>},
                {<<"te">>,<<>>},
                {<<"host">>,<<"localhost:8000">>},
                {<<"connection">>,<<"keep-alive">>}],
               [{<<"content-length">>,516},
                {<<"expect">>,undefined},
                {<<"content-length">>,516},
                {<<"connection">>,[<<"keep-alive">>]}],undefined,[],done,undefined,<<>>,true,waiting,[],<<>>,
               undefined}}

答案 1 :(得分:1)

受[http://code.activestate.com/recipes/146306/]的启发,改为[http://lethain.com/formatting-multipart-formdata-in-erlang/]谢谢!

format_multipart_formdata(Boundary, Fields, Files) ->
    FieldParts = lists:map(fun({FieldName, FieldContent}) ->
        [lists:concat(["--", Boundary]),
            lists:concat(["Content-Disposition: form-data; name=\"",atom_to_list(FieldName),"\""]),
            "", FieldContent]
                           end, Fields),

    FieldParts2 = lists:append(FieldParts),


    FileParts = lists:map(fun({FieldName, FileName, FileContent}) ->

        [lists:concat(["--", Boundary]),
            lists:concat(["Content-Disposition: form-data; name=\"",atom_to_list(FieldName),"\"; filename=\"",FileName,"\""]),
            lists:concat(["Content-Type: ", "application/octet-stream"]), "", FileContent]
                          end, Files),
    FileParts2 = lists:append(FileParts),
    EndingParts = [lists:concat(["--", Boundary, "--"]), ""],
    Parts = lists:append([FieldParts2, FileParts2, EndingParts]),
    string:join(Parts, "\r\n").

用法:

{ok,BinStream} = file:read_file("./images/avatar.png"),
Data = binary_to_list(BinStream), 
Boundary = "------WebKitFormBoundaryUscTgwn7KiuepIr1",
ReqBody = format_multipart_formdata(Boundary, [{uid,"123"}], [{avatar, "avatar", Data}]),
ContentType = lists:concat(["multipart/form-data; boundary=", Boundary]),
ReqHeader = [{"Content-Length", integer_to_list(length(ReqBody))}],

inets:start(),
ParaUrl = string:join(["http://www.example.com/avatar?access_token=",binary_to_list(token)],""),
RegUsr = httpc:request(post,{ParaUrl, ReqHeader,ContentType, ReqBody},[],[])