I would like to skip the part where an upload URL is sent to the client, and upload directly to the blobstore from the backend. I use this to send the multipart request, although I get:
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing/_ah/upload/ahB0NTIzNjU4OTY1ODk1Njg5ciILEhVfX0Jsb2JVcGxvYWRTZXNzaW9uX18YgICAgICAiAs M. Reason:
<pre> Missing ';'</pre></p><h3>Caused by:</h3> <pre>javax.mail.internet.ParseException: Missing ';'
at javax.mail.internet.ParameterList.<init>(ParameterList.java:135)
at javax.mail.internet.ContentType.<init>(ContentType.java:72)
at javax.mail.internet.MimeMultipart.<init>(MimeMultipart.java:98)
at com.google.apphosting.utils.servlet.MultipartMimeUtils.parseMultipartRequest(MultipartMimeUtils.java:41)
at com.google.appengine.api.blobstore.dev.UploadBlobServlet.handleUpload(UploadBlobServlet.java:173)
at com.google.appengine.api.blobstore.dev.UploadBlobServlet.access$000(UploadBlobServlet.java:71)
at com.google.appengine.api.blobstore.dev.UploadBlobServlet$1.run(UploadBlobServlet.java:117)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.appengine.api.blobstore.dev.UploadBlobServlet.doPost(UploadBlobServlet.java:114)
this is the data sent:
--__END_OF_PART__
Content-Type: image/bmp
content-transfer-encoding: binary
content-disposition: form-data; name="file"
[binary string here]
--__END_OF_PART__--
these are the headers:
accept-encoding: gzip,
content-type: multipart/form-data; boundary=__END_OF_PART__
and this is the code:
BlobstoreService service = BlobstoreServiceFactory.getBlobstoreService();
String url = service.createUploadUrl("/upload");
HttpRequestFactory factory = UrlFetchTransport.getDefaultInstance().createRequestFactory();
MultipartFormContent content = new MultipartFormContent();
content.addPart(new MultipartFormContent.Part(
"file",
new InputStreamContent("image/bmp",
new ByteArrayInputStream(Base64.decodeBase64(data)))));
content.writeTo(System.out);
HttpRequest request = factory.buildPostRequest(new GenericUrl(new URL(url)), content);
request.getHeaders().setContentType(content.getMediaType().build());
request.execute();
As noted in the docs, the multipart body has to be multipart/form-data with input type "file", which produces the Content-Disposition header with "filename" section:
Content-Disposition: form-data; name="myFile"; filename="imagename.bmp"
With HttpClient it should be something like this.
Related
I am using 2 multiparts ( 1 is a file the other is a form-data )
For the file I am using the default content type but (multipart/form-data) but for the other I need to use application/json
I don't know how to set content type for that specific multipart/fpr, data ===
This is what I have done -
Response resp = RestAssured.given().baseUri(UPLOAD)
.header("Content-Type", "multipart/form-data; boundary=--abcd")
.multiPart("files",new File(System.getProperty("user.dir") +picPath))
.multiPart("JSON_DATA",JSON_DATA )
.post().then().extract().response();
But this is the request that has been generated --
Content-Disposition: form-data; boundary=--abcd; name = files; filename =Photo.png
Content-Type: application/octet-stream
/../../../Photo.png
------------
Content-Disposition: form-data; boundary=--abcd; name = JSON_Data; filename = file
**Content-Type: text/plain**
{.......}
HOW DO I SET THE 2ND ONE TO application/json instead of text/plainm
You can define content-type for each part like this, no need put form-data in header
given().log().all()
.multiPart("file", file)
.multiPart("JSON_DATA", JSON_DATA, "application/json")
.post();
I am trying to create a transient document in adobe sign using rest api.Foloowing is my code snippet:
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://api.in1.echosign.com/api/rest/v6/transientDocuments');
req.setMethod(postMethod);
req.setHeader('Content-Type', 'application/json');
blob testFileContent = blob.toPDF('test string it is');
// req.setBody('{"filename":"testsign","file":'+testFileContent+'}');
req.setBody('{"fileName":"testsign","file":"'+testFileContent+'"}');
String authorizationHeader = 'Bearer ' +acceessToken;
req.setHeader('Authorization', authorizationHeader);
//req.setHeader('Authorization', acceessToken);
try{
HttpResponse res = h.send(req);
However I am getting the bad request error in response.Issue maybe due to the tag mismatch with adobe sign requirement, however after a lot of research and trial and error I am not able to find the accurate tags to put in JSON for this API request. Any suggestion and help ?
Form data
Content-Disposition: form-data; name="File"; filename="<filename>.pdf"
Content-Type: application/pdf
Request params
Content-Type: multipart/form-data;
Accept: application/json, text/javascript, */*;
More details available in the documentation.
I'm using WireMock to mock a SOAP service.
It works great, but one of the services contains an attachment.
Is there any way to mock it with WireMock?
Thanks
Yes it's possible.
First, you can use SOAP ui to mock the response you are expecting with the attachment. [On the soap resource, right click: generate SOAP mock service]
On the mock created, in the response you should see a dummy body corresponding to the wsld. There you can click on attachment and add a file:
You run this mock and try to hit it manually with a soap request that should then appear on the request part.
It will produce for you the response with the attachment.
You can see the raw part looking like this:
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart#soapui.org>"; start-info="text/xml"; boundary="----=_Part_19_678369072.1513344309074",
MIME-Version: 1.0
------=_Part_19_678369072.1513344309074
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart#soapui.org>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getFileResponse xmlns:ns3="urn:eu:europa:ec:etrustex:integration:service:notification:v2.0" xmlns:ns2="urn:eu:europa:ec:etrustex:integration:service:filerepository:v2.0" xmlns="urn:eu:europa:ec:etrustex:integration:model:common:v2.0">
<ns2:fileWrapper>
<Content><inc:Include href="cid:test.txt" xmlns:inc="http://www.w3.org/2004/08/xop/include"/></Content>
</ns2:fileWrapper>
</ns2:getFileResponse>
</S:Body>
</S:Envelope>
------=_Part_19_678369072.1513344309074
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-ID: <test.txt>
Content-Disposition: attachment; name="test.txt"
TEST
------=_Part_19_678369072.1513344309074--
Now, you can set up wiremock with something like this:
{
"request": {
"method": "POST",
"urlPattern": "/mockFileRepository"
},
"response": {
"status": 200,
"bodyFileName": "responseTest.raw",
"headers": {
"Content-Type": "multipart/related; type=\"application/xop+xml\"; start=\"<rootpart#soapui.org>\"; start-info=\"text/xml\"; boundary=\"----=_Part_19_678369072.1513344309074\"",
"MIME-Version": "1.0"
}
}
}
Pay attention the headers content-type should be the same as on the raw parts you got from soap ui.
the responseTest.raw looks something like this:
------=_Part_19_678369072.1513344309074
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <rootpart#soapui.org>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getFileResponse xmlns:ns3="urn:eu:europa:ec:etrustex:integration:service:notification:v2.0" xmlns:ns2="urn:eu:europa:ec:etrustex:integration:service:filerepository:v2.0" xmlns="urn:eu:europa:ec:etrustex:integration:model:common:v2.0">
<ns2:fileWrapper>
<Content><inc:Include href="cid:test.txt" xmlns:inc="http://www.w3.org/2004/08/xop/include"/></Content>
</ns2:fileWrapper>
</ns2:getFileResponse>
</S:Body>
</S:Envelope>
------=_Part_19_678369072.1513344309074
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-ID: <test.txt>
Content-Disposition: attachment; name="test.txt"
TEST
------=_Part_19_678369072.1513344309074--
And voila!
I would like to upload a log file from our iOS app directly to a folder on Box.com. Reading the api for Box this functionality is provided with REST webservices. The examples in the api are cURL which work out of the box (sorry, no pun intended) from the terminal.
Our app is Swift based, and I am using NSURLSession to make the request. After too many attempts to count, and close examination of the limited blogs on this subject (iOS / Box) I still have not managed to upload a test file.
One frustrating thing is that the api appears to be wrong, as seen here, but following the format suggested in this answer did not help.
Here is the NSURLSession request code from my latest attempt:
let path = NSBundle.mainBundle().pathForResource("testFile", ofType: "txt")
let data: NSData? = NSData(contentsOfFile: path!)
let url = NSURL(string: "https://upload.box.com/api/2.0/files/content")!
let request = NSMutableURLRequest(URL: url)
let boundary = generateBoundaryString()
request.HTTPMethod = "POST"
request.addValue("Bearer q1ckXDSTC0EcsCJiLtW638o5x5roWabb", forHTTPHeaderField: "Authorization")
let body = NSMutableData()
body.appendData("Content-Type: multipart/form-data; boundary=\(boundary)\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"parent_id\"\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: text/plain\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("0\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"filename\"; filename=\"testFile.txt\"\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: text/plain\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(data!)
body.appendData("\n--\(boundary)--".dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
let task = NSURLSession.sharedSession().uploadTaskWithRequest(request, fromData: data!, completionHandler: {(data,response,error) in
if(error != nil) {
NSLog("Error message = \(error.debugDescription)")
}
if(response != nil) {
NSLog("Response = \(response)")
}
if(data != nil) {
NSLog("Data = \(data!)")
}
});
task.resume()
The server responds with a 405 error.
Response = Optional(<NSHTTPURLResponse: 0x157de26d0> { URL: https://upload.box.com/api/2.0/files/content } { status code: 405, headers {
Age = 0;
Allow = "GET, OPTIONS, HEAD";
Connection = "keep-alive";
"Content-Length" = 0;
"Content-Type" = "text/html; charset=UTF-8";
Date = "Thu, 13 Oct 2016 14:49:49 GMT";
Server = ATS;
} })
From the example above the request header is:
Request headers - Optional(["Authorization": "Bearer q1ckXDSTC0EcsCJiLtW638o5x5roWabb"])!
And the request body is:
body - Content-Type: multipart/form-data; boundary=0B1D5883-9EA6-4D6B-9FEC-C51D817D5975
--0B1D5883-9EA6-4D6B-9FEC-C51D817D5975
Content-Disposition: form-data; name="parent_id"
Content-Type: text/plain
0
--0B1D5883-9EA6-4D6B-9FEC-C51D817D5975
Content-Disposition: form-data; name="filename"; filename="testFile.txt"
Content-Type: text/plain
Hello
--0B1D5883-9EA6-4D6B-9FEC-C51D817D5975--
We have tried to disseminate the cURL request with Wireshark but as it is an SSL request this didn't help much.
The verbose version of the cURL request looks like this:
0000: POST /api/2.0/files/content HTTP/1.1
0026: Host: upload.box.com
003c: User-Agent: curl/7.47.0
0055: Accept: */*
0062: Authorization: Bearer o6ojjxpfECdKrBzIUhiRyRKHTTXg8Sll
009a: Content-Length: 368
00af: Expect: 100-continue
00c5: Content-Type: multipart/form-data; boundary=--------------------
0105: ----ed667cff7b6570a1
011b:
== Info: Done waiting for 100-continue
=> Send data, 285 bytes (0x11d)
0000: --------------------------ed667cff7b6570a1
002c: Content-Disposition: form-data; name="attributes"
005f:
0061: {"name":"testFile.txt", "parent":{"id":"0"}}
008f: --------------------------ed667cff7b6570a1
00bb: Content-Disposition: form-data; name="file"; filename="testFile.
00fb: txt"
0101: Content-Type: text/plain
011b:
=> Send data, 35 bytes (0x23)
0000: This is a test file.
=> Send data, 48 bytes (0x30)
0000:
0002: --------------------------ed667cff7b6570a1--
Which we have also tried to replicate exactly, but the problem remains.
If anyone has achieved this successfully I would really appreciate some direction or suggestions
We contacted Box support team but they have yet to respond.
So I am trying to post to a Salesforce.com REST api that is expecting the following sample request -
POST /services/data/v33.0/chatter/feed-elements HTTP/1.1
Authorization: OAuth 00DRR0000000N0g!...
User-Agent: Jakarta Commons-HttpClient/3.0.1
Host: instance_name
Content-Length: 845
Content-Type: multipart/form-data; boundary=a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq
Accept: application/json
--a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq
Content-Disposition: form-data; name="json"
Content-Type: application/json; charset=UTF-8
{
"body":{
"messageSegments":[
{
"type":"Text",
"text":"Please accept this receipt."
}
]
},
"capabilities":{
"content":{
"description":"Receipt for expenses",
"title":"receipt.pdf"
}
},
"feedElementType":"FeedItem",
"subjectId":"005RR000000DmOb"
}
--a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq
Content-Disposition: form-data; name="feedElementFileUpload"; filename="receipt.pdf"
Content-Type: application/octet-stream; charset=ISO-8859-1
...contents of receipt.pdf...
--a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq--
As you can see, the two parts of the request is expecting different content types.
In Titanium, I have the following code -
xhr.open("POST", postUri);
xhr.setRequestHeader("Authorization", authHeader);
xhr.setRequestHeader('enctype', 'multipart/form-data');
var data2send = {
json: jsonObj,
feedElementFileUpload: imageBlob
};
xhr.send(data2send);
According to the Appcelerator documentation and a couple of online threads, the httpclient should be able to set each part automatically, however, Salesforce API still gives an error message of:
[{"errorCode":"MISSING_ARGUMENT","message":"Missing required 'subjectId' parameter."}]
I can confirm that subjectId is in the jsonObj and its content is correct. It seems that the json part is not recognised as JSON by Salesforce correctly. How can I set the content-type correctly? Many thanks.
Updates - I used the Wireshark to capture the request text. Apparently the httpclient did not set up the content-type for the json part that Salsforce API is expecting. Any idea how to set it?
POST /services/data/v33.0/chatter/feed-elements HTTP/1.1
Host: mydomain.com
Accept-Language: en-us
User-Agent: Appcelerator Titanium/3.5.1 (iPhone Simulator/8.2; iPhone OS; en_US;)
enctype: multipart/form-data
X-Requested-With: XMLHttpRequest
Accept: */*
Content-Type: multipart/form-data; charset=utf-8; boundary=0xTibOuNdArY_1430987526
Connection: keep-alive
Authorization: Bearer $My_AUTH_CODE
X-Titanium-Id: 8329dd1d-3379-4d7c-955e-120ad1586a2b
Content-Length: 93333
Accept-Encoding: gzip, deflate
--0xTibOuNdArY_1430987526
Content-Disposition: form-data; name="json"
{"feedElementType":"FeedItem","subjectId":"xxxxxxxxxx","body":{"messageSegments":[{"type":"text","text":"test"}]},"capabilities":{"content":{"description":"sdfaadfs","title":"adsfafsd.png"}}}
--0xTibOuNdArY_1430987526
Content-Disposition: form-data; name="feedElementFileUpload"; filename="01430987526.png"
Content-Type: image/png
my file data...