I am trying to send a pdf file along with a SOAP request using the Savon gem.
All the similar questions I found are either 5+ years old (Savon v1) or without any answer.
While testing the request in SoapUI I was able to successfully send a file with the following request + the file in attachments:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="link" xmlns:nir="link">
<soapenv:Header>
<ws:nvheader>
<ws:nvcommand>
<ws:nv_user>nv_user</ws:nv_user>
<ws:nv_password>nv_password</ws:nv_password>
</ws:nvcommand>
</ws:nvheader>
</soapenv:Header>
<soapenv:Body>
<ws:order_create_IN>
<ws:action type="string">ORDER_CREATE</ws:action>>
<ws:document type="file" extension="pdf" prefix="" suffix="">
<nir:data>cid:pdf_file_name.pdf</nir:data>
</ws:document>
<ws:document_name type="string">df_file_name.pdf</ws:document_name>
<ws:get_proof type="string">NO</ws:get_proof>
<ws:identifier type="indstringlist" case-sensitive="?">
<nir:data key="LOGIN">login</nir:data>
<nir:data key="PASSWORD">password</nir:data>
</ws:identifier>
<ws:mailing_type type="string">UNIQUE</ws:mailing_type>
<ws:service_profile type="indstringlist" case-sensitive="?">
<nir:data key="service_id">MAIL</nir:data>
</ws:service_profile>
</ws:order_create_IN>
</soapenv:Body>
</soapenv:Envelope>
What I tried to make this request using Savon:
My latest attempt looks like this:
client = Savon.client(wsdl: "wsdl_link",
convert_request_keys_to: :none, logger: Rails.logger,
log_level: :debug,
log: true,
pretty_print_xml: true)
soap_header = { nvheader:
{ nvcommand:
{ nv_user: ENV["postgreen_nv_user"],
nv_password: ENV["postgreen_nv_pwd"] } } }
body = "<ws:action type=\"string\">ORDER_CREATE</ws:action>>
<ws:document type=\"file\" extension=\"pdf\" prefix=\"\" suffix=\"\">
<nir:data>cid:pdf_file_name.pdf</nir:data>
</ws:document>
<ws:document_name type=\"string\">pdf_file_name.pdf</ws:document_name>
<ws:get_proof type=\"string\">NO</ws:get_proof>
<ws:identifier type=\"indstringlist\" case-sensitive=\"?\">
<nir:data key=\"LOGIN\">login</nir:data>
<nir:data key=\"PASSWORD\">password</nir:data>
</ws:identifier>
<ws:mailing_type type=\"string\">UNIQUE</ws:mailing_type>
<ws:service_profile type=\"indstringlist\" case-sensitive=\"?\">
<nir:data key=\"service_id\">MAIL</nir:data>
</ws:service_profile>"
response = client.call(:order_create,
soap_header: soap_header,
message: body,
attachments: { 'pdf_file_name.pdf' => 'storage/pdf_file_name.pdf' })
If I send the request without the "attachments", I get a response (saying that there's no file).
But when I send the same request with a file, I get a generic error response as if it didn't understood the request at all.
In the logs I have the following for the request without attachment:
SOAP request: Endpoint Link
SOAPAction: "order_create"
Content-Type: text/xml;charset=UTF-8
Content-Length: 2092
<?xml version="1.0" encoding="UTF-8"?>
...
--- "my xml message" ---
...
HTTPI /peer POST request to rct.post-green.net (net_http)
SOAP response (status 200)
date: Tue, 21 Aug 2018 12:18:54 GMT
server: NIRVA HTTP server
cache-control: no-cache
content-type: text/xml
expires: Wed, 26 Feb 1997 08:21:57 GMT
pragma: no-cache
set-cookie: NvSessionId=; expires=Thu, 01-Jan-1970 00:00:00 GMT
vary: Accept-Encoding
content-length: 906
...
--- "xml response message" ---
...
And this for the request with an attachment:
SOAP request: Endpoint Link
SOAPAction: "order_create"
Content-Type: multipart/related; boundary="--==_mimepart_5b7c03832ef1_24772b1c76b4a65010330"; type="text/xml"; start="<soap-request-body@soap>"
Content-Length: 207653
<?xml version="1.0"?>
...
--- "Nothing there as if there's no message or it's too large to show" ---
...
HTTPI /peer POST request to rct.post-green.net (net_http)
SOAP response (status 500)
date: Tue, 21 Aug 2018 12:20:19 GMT
server: Apache
last-modified: Fri, 19 May 2017 12:14:25 GMT
etag: "8df-54fdf7660c649"
accept-ranges: bytes
content-length: 2271
connection: close
content-type: text/html
...
--- "html response message" ---
...
So in the end I'm kinda lost, I was trying different approaches for 2-3 days without any success now.
Does anybody has a solution for this? Maybe there is another method/gem to achieve this?
You should try to add your file in your xml request, transforming you file into a Base64 file.
file_data = Base64.encode64(File.binread("/path/to/your/file"))
Integrate that file_data
into your xml, and your full request will be something like this :
body = "<ws:action type=\"string\">ORDER_CREATE</ws:action>>
<ws:document type=\"file\" extension=\"pdf\" prefix=\"\" suffix=\"\">
<nir:data>#{file_data}</nir:data>
</ws:document>
<ws:document_name type=\"string\">pdf_file_name.pdf</ws:document_name>
<ws:get_proof type=\"string\">NO</ws:get_proof>
<ws:identifier type=\"indstringlist\" case-sensitive=\"?\">
<nir:data key=\"LOGIN\">login</nir:data>
<nir:data key=\"PASSWORD\">password</nir:data>
</ws:identifier>
<ws:mailing_type type=\"string\">UNIQUE</ws:mailing_type>
<ws:service_profile type=\"indstringlist\" case-sensitive=\"?\">
<nir:data key=\"service_id\">MAIL</nir:data>
</ws:service_profile>"
In your client.call(:order_create, soap_header: soap_header, message: body)
This should work I think !