Faraday: jsonとファイルをmultipart/form-dataとしてアップロードする際のサポートが必要

作成日 2020年01月05日  ·  3コメント  ·  ソース: lostisland/faraday

以下は私がアップロードする必要があるものです

-data-binary $'

------WebKitFormBoundaryInmulX6ait6ZMLdu\r\n
Content-Disposition: form-data; name="message"; filename="blob"\r\n
Content-Type: application/json
{
 "title":"title of the message to be sent",
 "body":"body of the message to be sent",
 "attachedFileName":null,
 "attachedFileName2":null,
 "attachedFileName3":null,
 "recipientIdList":[186554]
}
 ------WebKitFormBoundaryInmulX6ait6ZMLdu--\r\n' --compressed

サーバーが受け取るコンテンツタイプはmultipart/form-dataであることに注意してください

私の現在のコードは次のようになります。

client = Faraday::Connection.new(url: BASE_URL) do |builder|
    builder.use :cookie_jar
    builder.use :multipart
    builder.use :url_encoded
    builder.adapter :net_http
end

message = {title: "title", body: "body of message", recipientIdList:[186554]}
payload = {message: JSON.dump(message)}

response = @client.post(URL) do |request|
    request.headers['Content-Type'] = 'multipart/form-data'
    request.body = payload
end

ただし、サーバーから取得する応答は{"success"=>false, "errorCode"=>nil, "message"=>"Content type 'application/octet-stream' not supported", "data"=>nil}です。

コードを少しずつ調整して再試行し、グーグルで何時間も検索しましたが、解決策が見つかりませんでした。
誰かがこれを手伝ってくれると大歓迎です。
よろしくお願いします:D

PSこの問題はhttps://github.com/lostisland/faraday/issues/830#issue-372589645およびhttps://github.com/lostisland/faraday/issues/769#issue-295426091に関連しているようですが、私は解決策が見つかりません..助けてください..

最も参考になるコメント

問題は、ペイロードの構築方法にあります。 curl -data-binaryスニペットによると、サーバーはmessageフォーム値にapplication/jsonコンテンツタイプを持たせたいと考えています。 ただし、構築されたペイロードはこれをどこにも指定しません。

Faradayv1.0で修正する方法は次のとおりです。 マルチパートミドルウェアの詳細を見る…

-payload = {message: JSON.dump(message)}
+payload = { message: Faraday::ParamPart.new(JSON.dump(message), ‘application/json’) }

Faraday v0.1x(0.17.3で確認済み)。 これでも、メモリ内のIOオブジェクトから読み取っている「ファイル」が送信されることに注意してください。 うまくいけば、サーバーは余分なマルチパートヘッダー値を気にしません。 詳細は、このメッセージの下部にある3番目のリクエストで確認できます。

-payload = {message: JSON.dump(message)}
+{ message: Faraday::UploadIO.new(StringIO.new(JSON.dump(message)), 'application/json') }

ただし、サーバーが応答したエラーメッセージをどうすればよいかわかりません。

コンテンツタイプ'application/octet-stream'はサポートされていません

application/octet-streamがどこから来ているのかわからないので、マルチパートコンテンツタイプの問題を修正することで問題が解決することを期待しています。

他にご不明な点がありましたらお知らせください。

私の作品を見せて

動作するコードスニペットはmultipart.rb・GitHubで確認できます。 コードが参照するRequestBinはリクエスト情報を一時的に保持するだけなので、以下の詳細を記録しています。

ペイロードにコンテンツタイプがないリクエスト:

# AMZ/Cloudfront headers removed
Content-Type: multipart/form-data; boundary=—————RubyMultipartPost-10fbc5eb433c89c0eca87785f09ae45d
Connection: close
Connect-Time: 1
X-Request-Id: e802a260-56a9-4d01-a4ee-77f652380185
Content-Length: 253
Host: requestbin.io
User-Agent: Faraday v1.0.0
Accept: */*

——————RubyMultipartPost-10fbc5eb433c89c0eca87785f09ae45d
Content-Disposition: form-data; name=“message”

{“title”:”title”,”body":"body of message”,”recipientIdList":[186554]}
——————RubyMultipartPost-10fbc5eb433c89c0eca87785f09ae45d——————

WITHコンテンツタイプのリクエスト(ファラデー1.0)

Content-Type: multipart/form-data; boundary=—————RubyMultipartPost-9d77ee5700e0658dddb09ac41fad5fa4

Connection: close
Connect-Time: 0
Content-Length: 285
User-Agent: Faraday v1.0.0
X-Request-Id: 2bbb3705-42ec-4de2-877c-2afd588ed679
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
Host: requestbin.io

——————RubyMultipartPost-9d77ee5700e0658dddb09ac41fad5fa4
Content-Disposition: form-data; name=“message”
Content-Type: application/json

{“title”:”title”,”body":"body of message”,”recipientIdList”:[186554]}
——————RubyMultipartPost-9d77ee5700e0658dddb09ac41fad5fa4——————

WITHコンテンツタイプのリクエスト(Faraday v0.17.3)

Content-Type: multipart/form-data; boundary=—————RubyMultipartPost-697c8614200bc0d7ae2fcc0215a2a697
Connection: close
Content-Length: 363
User-Agent: Faraday v0.17.3
X-Request-Id: af65fc06-3914-4ab6-8dbf-b347a1ac498a
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
Host: requestbin.io

——————RubyMultipartPost-697c8614200bc0d7ae2fcc0215a2a697
Content-Disposition: form-data; name=“message”; filename=“local.path"
Content-Length: 69
Content-Type: application/json
Content-Transfer-Encoding: binary

{“title”:”title”,”body”:”body of message”,”recipientIdList”:[186554]}
——————RubyMultipartPost-697c8614200bc0d7ae2fcc0215a2a697—

全てのコメント3件

問題は、ペイロードの構築方法にあります。 curl -data-binaryスニペットによると、サーバーはmessageフォーム値にapplication/jsonコンテンツタイプを持たせたいと考えています。 ただし、構築されたペイロードはこれをどこにも指定しません。

Faradayv1.0で修正する方法は次のとおりです。 マルチパートミドルウェアの詳細を見る…

-payload = {message: JSON.dump(message)}
+payload = { message: Faraday::ParamPart.new(JSON.dump(message), ‘application/json’) }

Faraday v0.1x(0.17.3で確認済み)。 これでも、メモリ内のIOオブジェクトから読み取っている「ファイル」が送信されることに注意してください。 うまくいけば、サーバーは余分なマルチパートヘッダー値を気にしません。 詳細は、このメッセージの下部にある3番目のリクエストで確認できます。

-payload = {message: JSON.dump(message)}
+{ message: Faraday::UploadIO.new(StringIO.new(JSON.dump(message)), 'application/json') }

ただし、サーバーが応答したエラーメッセージをどうすればよいかわかりません。

コンテンツタイプ'application/octet-stream'はサポートされていません

application/octet-streamがどこから来ているのかわからないので、マルチパートコンテンツタイプの問題を修正することで問題が解決することを期待しています。

他にご不明な点がありましたらお知らせください。

私の作品を見せて

動作するコードスニペットはmultipart.rb・GitHubで確認できます。 コードが参照するRequestBinはリクエスト情報を一時的に保持するだけなので、以下の詳細を記録しています。

ペイロードにコンテンツタイプがないリクエスト:

# AMZ/Cloudfront headers removed
Content-Type: multipart/form-data; boundary=—————RubyMultipartPost-10fbc5eb433c89c0eca87785f09ae45d
Connection: close
Connect-Time: 1
X-Request-Id: e802a260-56a9-4d01-a4ee-77f652380185
Content-Length: 253
Host: requestbin.io
User-Agent: Faraday v1.0.0
Accept: */*

——————RubyMultipartPost-10fbc5eb433c89c0eca87785f09ae45d
Content-Disposition: form-data; name=“message”

{“title”:”title”,”body":"body of message”,”recipientIdList":[186554]}
——————RubyMultipartPost-10fbc5eb433c89c0eca87785f09ae45d——————

WITHコンテンツタイプのリクエスト(ファラデー1.0)

Content-Type: multipart/form-data; boundary=—————RubyMultipartPost-9d77ee5700e0658dddb09ac41fad5fa4

Connection: close
Connect-Time: 0
Content-Length: 285
User-Agent: Faraday v1.0.0
X-Request-Id: 2bbb3705-42ec-4de2-877c-2afd588ed679
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
Host: requestbin.io

——————RubyMultipartPost-9d77ee5700e0658dddb09ac41fad5fa4
Content-Disposition: form-data; name=“message”
Content-Type: application/json

{“title”:”title”,”body":"body of message”,”recipientIdList”:[186554]}
——————RubyMultipartPost-9d77ee5700e0658dddb09ac41fad5fa4——————

WITHコンテンツタイプのリクエスト(Faraday v0.17.3)

Content-Type: multipart/form-data; boundary=—————RubyMultipartPost-697c8614200bc0d7ae2fcc0215a2a697
Connection: close
Content-Length: 363
User-Agent: Faraday v0.17.3
X-Request-Id: af65fc06-3914-4ab6-8dbf-b347a1ac498a
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
Host: requestbin.io

——————RubyMultipartPost-697c8614200bc0d7ae2fcc0215a2a697
Content-Disposition: form-data; name=“message”; filename=“local.path"
Content-Length: 69
Content-Type: application/json
Content-Transfer-Encoding: binary

{“title”:”title”,”body”:”body of message”,”recipientIdList”:[186554]}
——————RubyMultipartPost-697c8614200bc0d7ae2fcc0215a2a697—

助けてくれてありがとう、 @ technoweenie ! あなたは素晴らしいです!
リクエストは、新しく構築されたペイロードで問題なく機能するようになり、 application/octet-streamについて文句を言うことはなくなりました。
素晴らしい一日をお過ごしください:D

期待どおりに動作することを聞いてうれしいです!
よくやった@technoweenie 、このトリッキーな問題にとても早く取り組んでくれてありがとう👏!

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

yykamei picture yykamei  ·  4コメント

olleolleolle picture olleolleolle  ·  5コメント

jedeleh picture jedeleh  ·  3コメント

t3hk0d3 picture t3hk0d3  ·  3コメント

jordansissel picture jordansissel  ·  5コメント