Faraday: Precisa de ajuda com o upload de json e arquivo como multipart/form-data

Criado em 5 jan. 2020  ·  3Comentários  ·  Fonte: lostisland/faraday

Abaixo está o que eu preciso enviar

-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

Observe que o tipo de conteúdo que o servidor recebe é multipart/form-data

meu código atual está assim:

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

No entanto, a resposta que recebo do servidor é {"success"=>false, "errorCode"=>nil, "message"=>"Content type 'application/octet-stream' not supported", "data"=>nil}

Eu ajustei o código aos poucos e tentei novamente, e procurei no google por horas, mas não consegui encontrar a solução.
Agradeceria muito se alguém pudesse me ajudar com isso.
Agradeço antecipadamente

PS, este problema parece estar relacionado a https://github.com/lostisland/faraday/issues/830#issue -372589645 e https://github.com/lostisland/faraday/issues/769#issue -295426091 , mas eu não consigo encontrar solução.. Por favor, ajude..

Comentários muito úteis

O problema está na forma como a carga útil é construída. De acordo com seu snippet curl -data-binary , seu servidor quer que o valor do formulário message tenha o tipo de conteúdo application/json . No entanto, a carga útil construída não especifica isso em nenhum lugar.

Veja como corrigi-lo em Faraday v1.0. Veja mais sobre o Middleware Multipart

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

Em Faraday v0.1x (confirmado em 0.17.3). Observe que isso ainda envia um “arquivo” que está apenas lendo de um objeto de E/S na memória. Espero que o servidor não se importe com os valores extras de cabeçalho de várias partes. Você pode ver os detalhes na terceira solicitação na parte inferior desta mensagem.

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

Não sei o que fazer com a mensagem de erro com a qual seu servidor respondeu.

Tipo de conteúdo 'application/octet-stream' não suportado

Espero que corrigir o problema do tipo de conteúdo de várias partes o resolva, pois não vejo de onde vem application/octet-stream .

Deixe-me saber se você tiver mais perguntas!

Mostrando meu trabalho

Você pode ver os trechos de código de trabalho em multipart.rb · GitHub . Como o RequestBin que o código faz referência apenas mantém as informações da solicitação temporariamente, estou registrando os detalhes abaixo:

Solicitação sem tipo de conteúdo no payload:

# 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——————

Solicitar COM tipo de conteúdo (Faraday 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——————

Solicitar COM tipo de conteúdo (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—

Todos 3 comentários

O problema está na forma como a carga útil é construída. De acordo com seu snippet curl -data-binary , seu servidor quer que o valor do formulário message tenha o tipo de conteúdo application/json . No entanto, a carga útil construída não especifica isso em nenhum lugar.

Veja como corrigi-lo em Faraday v1.0. Veja mais sobre o Middleware Multipart

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

Em Faraday v0.1x (confirmado em 0.17.3). Observe que isso ainda envia um “arquivo” que está apenas lendo de um objeto de E/S na memória. Espero que o servidor não se importe com os valores extras de cabeçalho de várias partes. Você pode ver os detalhes na terceira solicitação na parte inferior desta mensagem.

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

Não sei o que fazer com a mensagem de erro com a qual seu servidor respondeu.

Tipo de conteúdo 'application/octet-stream' não suportado

Espero que corrigir o problema do tipo de conteúdo de várias partes o resolva, pois não vejo de onde vem application/octet-stream .

Deixe-me saber se você tiver mais perguntas!

Mostrando meu trabalho

Você pode ver os trechos de código de trabalho em multipart.rb · GitHub . Como o RequestBin que o código faz referência apenas mantém as informações da solicitação temporariamente, estou registrando os detalhes abaixo:

Solicitação sem tipo de conteúdo no payload:

# 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——————

Solicitar COM tipo de conteúdo (Faraday 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——————

Solicitar COM tipo de conteúdo (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—

Muito obrigado por sua ajuda, @technoweenie ! Você é incrível!!
A solicitação agora funciona bem com o payload recém-construído e não reclama mais do application/octet-stream .
Espero que você tenha um ótimo dia :D

Fico feliz em saber que funciona como esperado agora!
Muito bem @technoweenie , obrigado por resolver esse problema complicado tão rapidamente 👏 !

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

mokolabs picture mokolabs  ·  3Comentários

jordansissel picture jordansissel  ·  5Comentários

Lewiscowles1986 picture Lewiscowles1986  ·  4Comentários

JasonBarnabe picture JasonBarnabe  ·  4Comentários

yusefu picture yusefu  ·  3Comentários