Including Content-Transfer-Encoding header in RestSharp multi-part messages? - http-headers

I am using RestSharp to upload multi-part messages (basically, form data with a file attached at the end). The receiving service seems to require that I specify the Content-Transfer-Encoding header on each part or I get a 400 error on the POST.
I can't find any way in RestSharp to set this, or to specify "headers" that are actually inside the body of the parts. What I need to produce is a payload that looks like this:
POST http://server/object/create HTTP/1.1
User-Agent: RestSharp/105.2.3.0
Content-Type: multipart/form-data; boundary=-----------------------------28947758029299
Host: server:8080
Content-Length: 540
-------------------------------28947758029299
Content-Type: application/xml;charset=US-ASCII
Content-Disposition: form-data; name="form"
Content-Transfer-Encoding: 8bit
<form>this is some form data in XML format</form>
-------------------------------28947758029299
Content-Disposition: form-data; name="1.eml"; filename="1.email"
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
This is arbitrary file content to attach to the form.
-------------------------------28947758029299--
So far, this is what I've got (I'm prototyping in PowerShell but the results are identical in C#):
$request = New-Object RestSharp.RestRequest("iss", [RestSharp.Method]::POST)
$request.AddParameter("application/xml;charset=UTF-8", $form, [RestSharp.ParameterType]::RequestBody) | Out-Null
$request.AddFile("att.txt", "C:\Development\att.txt", "application/octet-stream; charset=ISO-8859-1") | Out-Null
$response = $rest.Execute($request)
which does everything I need except the Content-Transfer-Encoding part.
Is this possible with RestSharp, or should I drop down to use the HTTP client directly?

Related

HTTP Post Request (CSV File to ebay) with VBA

The eBay CSV Manager enables to upload a CSV file to mark all paid and sent items as sent in eBays seller tool. My Excel Macro creates such a CSV file. Now, I want to upload this file via HTTP Post Request.
In eBays CSV Manager manual they say:
Files can only be uploaded via Token. This Token has to be send with the file every upload. It is virtually the key for the entry to the CSV Manager.
I already have the Token.
It goes on to say that
a HTTP Post request has to be sent to the eBay CSV Manager Server to upload the file via script. The HTTPS connection has to be started and the data has to be send together with the Token to the CSV Manager web adress https://bulksell.ebay.com/ws/eBayISA...ExchangeUpload
eBay has an example for the request in its CSV Manager manual:
POST /path/to/upload/script HTTP/1.0
Connection: Keep-Alive
User-Agent: My Client App v1.0
Host:
https://bulksell.ebay.com/ws/eBayISA...ExchangeUpload
Content-type: multipart/form-data;
boundary=THIS_STRING_SEPARATES
Content-Length: 256
--THIS_STRING_SEPARATES
Content-Disposition: form-data; name="token"
12345678987654321
--THIS_STRING_SEPARATES
Content-Disposition: form-data; name="file";
filename="listings.csv"
Content-Type: text/csv
... contents of listings.csv ...
--THIS_STRING_SEPARATES
The explanation of the example is:
State which method has to be applied to the ressource:
POST /path/to/upload/script HTTP/1.0
Connection type, user-agent and information to the host:
Connection: Keep-Alive
User-Agent: My Client App v1.0
Host:https://bulksell.ebay.com/ws/eBayISA...ExchangeUpload
Header with information to the content and the lenght of the file:
Content-type: multipart/form-data; boundary=THIS_STRING_SEPARATES
Content-Length: 256
Safety Token and content to be uploaded:
--THIS_STRING_SEPARATES
Content-Disposition: form-data; name="token"
12345678987654321
--THIS_STRING_SEPARATES
Content-Disposition: form-data; name="file"; filename="listings.csv"
Content-Type: text/csv
... contents of listings.csv ...
--THIS_STRING_SEPARATES
How to do the HTTP Request and how to integrate it to the VBA Code?
The concept of REST API is that you post a data file to the API end point. You need to use one of microsoft http add-on to conscruct the payload which contains the header and body and post it to the require API.
You would have multi part in your macro to achieve this function
A login function where you would store the token
A body constructor where you would read your excel data and transform it into a json format.
A header constructor
A post function where post the relevant data to the gateway api using the microsoft http document handler.
But if you are planning to send the CSV as data then its best to write a vbscript to quickly post the file to the API.

Is it possible to list all the ContentWorkspaces (including private ones) using admin token with 'Query All Files' perms?

As a system administrator, I want to fetch all the libraries from my organization. To achieve my goal I tried to use the request to GET /services/data/v48.0/query/?q=SELECT+Id+FROM+ContentWorkspace.
But I did not get private 'ContentWorkspaces'.
Another problem that I faced was trying to create a file in user`s private library.
Example 1
POST /services/data/v48.0/sobjects/ContentVersion/
--boundary_string
Content-Disposition: form-data; name="entity_content";
Content-type: application/json
{"PathOnClient":"FILE.txt", "OwnerId":"0051v000006lmLuAAI", "FirstPublishLocationId":"0581v000000dacWAAQ"}
--boundary_string
Content-Type: application/octet-stream
Content-Disposition: form-data; name="VersionData"; filename="FILE.txt"
Binary data goes here.
--boundary_string--
Example 2
POST /services/data/v48.0/sobjects/ContentVersion/
--boundary_string
Content-Disposition: form-data; name="entity_content";
Content-type: application/json
{"PathOnClient":"FILE.txt", "OwnerId":"0051v000006lmLuAAI"}
--boundary_string
Content-Type: application/octet-stream
Content-Disposition: form-data; name="VersionData"; filename="FILE.txt"
Binary data goes here.
--boundary_string--
Is it possible to achieve everything that I mentioned above using the system admin token with 'Query All Files' perms or it is impossible?

File not being sent in Postman

I'm trying to send a file in Postman native to test our API, but I can't get it sent. I've set Request method POST, chosen BODY and added a file (using the file selector) and given the file the key I want it to have. I've also added another key-value (string), which gets sent. This is the request:
POST /api/user/1901594/17406/foto HTTP/1.1
Host: hidden.domain.com
tp-api-token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImF4a3Jpc3RpYW5zZW4iLCJ0dGwiOjE1NTYwNDQ0NDh9.7MAp43_4jnPM_QQluc2Ozx-QBowjCIqQzJ8sn9Y7HG0
cache-control: no-cache
Postman-Token: 8c14c293-f769-4391-90a3-c070cba1393a
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="foto"; filename="C:\Users\ander\Downloads\bilder tilhenger\DSC_0178.JPG
Content-Disposition: form-data; name="unikID"
asdf2398
------WebKitFormBoundary7MA4YWxkTrZu0gW--
As you can see the filename is added to the request, but not the actual file itself (it should be, shouldn't it?)
Is this a bug, or am I doing something wrong?
Nothing wrong with the Postman request. It was the PHP extension php-fileinfo who wasn't installed on our new server.

Postman shows "Could not get any response" even though response is OK

I have a WCF service which I make API requests to.
This API call returns a JSON response object and also is able to return it in GZIP compression as well when "gzip" value is used in "Accept-Encoding" header.
The problem is when I try to get the response in GZIP, Postman shows "Could not get any response" although I see response and response's content are OK (200 status code) in Fiddler and can easily decompress the response content in my C# client.
I took a look in Postman Console but all I see is "Error: incorrect header check".
I hardly tried to find any documentation regarding this header check but couldn't find any.
These are the request headers:
POST /correction/v1/document?lang=US HTTP/1.1
Content-Type: text/plain
Accept-Encoding: gzip
User-Agent: PostmanRuntime/7.6.0
Accept: */*
content-length: 630
Connection: close
These are the response headers:
HTTP/1.1 200 OK
Content-Length: 512
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Server: Microsoft-HTTPAPI/2.0
Date: Sun, 24 Feb 2019 14:05:50 GMT
Connection: close
The only thing I suspect is wrong is this message from Fiddler:
I integrated this code into mine in order to use GZIP in WCF.
https://github.com/carlosfigueira/WCFSamples/tree/master/MessageEncoder/GZipEncoderAndAutoFormatSelection
Basically, it captures the response before returning to client and use GZipStream for compression.
I got the same issue, I added the following header to fix this issue.
Accept-Encoding : *
I was able to solve a similar issue by using the header Accept-Encoding: */* or if you want to be specific do Accept-Encoding: */* that way the HTTP client will be able to process the response based on the type of encoding received, in the case of a gzip, it will decode the response and show it as normal text.
For me, I removed 'Accept-Encoding' in the request header.
I got this issue when the REST service was returning a zip content (aka. WinZip format). I solved the error by compressing the data using 7zip to produce true gzip format.

Amazon S3 Create Object Error: POST requires exactly one file upload per request

I am trying to create an object via postman rest client with the following request. It gives the below-mentioned error. What could be the reason for this? Can anyone help me to fix this?
Request:
POST HTTP/1.1
Host: 1465549420742testconbkt2.s3-us-west-2.amazonaws.com
x-amz-date: Fri, 10 Jun 2016 09:03:47 GMT
Authorization: xxxxxx
Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryE19zNvXGzXaLvS5C
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="file"; filename="testFile.txt"
Content-Type: text/plain
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="acl"
public-read-write
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="key"
testFile.txt
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="success_action_status"
200
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="AWSAccessKeyId"
AKIAJQJTU6FXS7TC2DTA
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Response:
<Error>
<Code>InvalidArgument</Code>
<Message>POST requires exactly one file upload per request.</Message>
<ArgumentName>file</ArgumentName>
<ArgumentValue>0</ArgumentValue>
<RequestId>B1EE3A8D9EA832AE</RequestId>
<HostId>dqOG4gKXDXYKomDig1VD559Wc3XCLvPPB+uUiM6xKNiOVeMH+dvqDrAv47zy15qDIz/WvO+T3rQ=</HostId>
</Error>
Thanks in advance
You have an error in your boundary:
It need "--"(2 dash) more than the header so:
Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryE19zNvXGzXaLvS5C
Should be:
Content-Type: multipart/form-data;boundary=------WebKitFormBoundaryE19zNvXGzXaLvS5C
Apparently for Post request
From:
HTTP POST with HttpWebRequest
The file or content must be the last field in the form. Any fields below it are ignored.
http://docs.aws.amazon.com/AmazonS3/latest/dev/HTTPPOSTForms.html
Yours is not last. It's followed by other form fields, and presumably this is confusing S3 into thinking you have more than one file. Granted, the "ignored" in the docs is not entirely consistent with my explanation, but that could be a side effect of uploading a small file, if that's what you're doing... fields that begin within about the first 20K of the upload may not always be ignored if they come after the file.
I believe your boundary values need to be prefixed with -- for each entry and the last boundary value needs to be suffixed with -- as follows (also as mentioned before, file needs to go last):
POST HTTP/1.1
Host: 1465549420742testconbkt2.s3-us-west-2.amazonaws.com
x-amz-date: Fri, 10 Jun 2016 09:03:47 GMT
Authorization: xxxxxx
Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryE19zNvXGzXaLvS5C
Cache-Control: no-cache
------WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="acl"
public-read-write
------WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="key"
testFile.txt
------WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="success_action_status"
200
------WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="AWSAccessKeyId"
AKIAJQJTU6FXS7TC2DTA
------WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="file"; filename="testFile.txt"
Content-Type: text/plain
------WebKitFormBoundaryE19zNvXGzXaLvS5C--
I was having the same error, the problem for me was that indeed the file was "empty".
I had the request saved for a long time, and maybe I missplaced the file in my computer, and the reference Postman had was broken (I haven't seen message in the console of Postman though)
Adding again the file solved it. No more "POST requires exactly one file upload per request." error message.
I am not sure how that would translate to the HTTP code request being used by all the answers here, and I don't think that copying the HTTP code here will help, since I believe POSTMAN strips the actual contents of the file, but to give more info, I have it like this:
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="sample-mp4-file-small.mp4"
Content-Type: <Content-Type header here>
(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW