Titanium multipart file upload with different content types? - rest

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...

Related

Unable to open "File" or "Edit" menu in Notepad using WinAppDriver

I'm trying to learn how to use WinAppDriver to test my desktop app developed in VS2019.
I'm able to run a NUnit test using the basic Notepad.exe and example of typing text. However, I'm unable to click on menu elements in Notepad for example. How do you achieve this?
Inspect.exe says its name is "Edit".
I'm using the Appium.WebDriver 4.1.1 nuget package.
Here is a good example of what I'm trying to do, but the code is outdated: https://github.com/microsoft/WinAppDriver/blob/master/Samples/C%23/NotepadTest/ScenarioMenuItem.cs
Test Code in VS2019
using NUnit.Framework;
using OpenQA.Selenium.Appium.Windows;
using System;
namespace Notepad_Tests
{
public class Tests
{
protected static WindowsDriver<WindowsElement> NotepadSession;
[SetUp]
public void Setup()
{
var appiumOptions = new OpenQA.Selenium.Appium.AppiumOptions();
appiumOptions.AddAdditionalCapability("platformName", #"Windows");
appiumOptions.AddAdditionalCapability("deviceName", #"WindowsPC");
appiumOptions.AddAdditionalCapability("app", #"C:\Windows\notepad.exe");
appiumOptions.AddAdditionalCapability("app", #"C:\Windows\notepad.exe");
appiumOptions.AddAdditionalCapability("appArguments", #"MyTestFile.txt");
appiumOptions.AddAdditionalCapability("appWorkingDir", #"D:\MyTestFolder\");
NotepadSession = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), appiumOptions);
}
[Test]
public void Test1()
{
NotepadSession.FindElementByClassName("Edit").SendKeys("This is some text");
NotepadSession.FindElementByName("Edit").Click();
}
[TearDown]
public void TestCleanup()
{
// NotepadSession.Quit();
}
}
}
Error in WinAppDriver.exe window
==========================================
POST /session HTTP/1.1
Accept: application/json, image/png
Connection: Keep-Alive
Content-Length: 236
Content-Type: application/json; charset=utf-8
Host: 127.0.0.1:4723
User-Agent: selenium/3.141.0 (.net windows)
{"desiredCapabilities":{"platformName":"Windows","deviceName":"WindowsPC","app":"C:\\Windows\\notepad.exe","appArguments":"MyTestFile.txt","appWorkingDir":"D:\\MyTestFolder\\"},"capabilities":{"firstMatch":[{"platformName":"Windows"}]}}
HTTP/1.1 200 OK
Content-Length: 200
Content-Type: application/json
{"sessionId":"431F0707-71BD-4645-B085-5BD750FC2067","status":0,"value":{"app":"C:\\Windows\\notepad.exe","appArguments":"MyTestFile.txt","appWorkingDir":"D:\\MyTestFolder\\","platformName":"Windows"}}
==========================================
POST /session/431F0707-71BD-4645-B085-5BD750FC2067/element HTTP/1.1
Accept: application/json, image/png
Connection: Keep-Alive
Content-Length: 37
Content-Type: application/json; charset=utf-8
Host: 127.0.0.1:4723
User-Agent: selenium/3.141.0 (.net windows)
{"using":"class name","value":"Edit"}
HTTP/1.1 200 OK
Content-Length: 96
Content-Type: application/json
{"sessionId":"431F0707-71BD-4645-B085-5BD750FC2067","status":0,"value":{"ELEMENT":"42.2099874"}}
==========================================
POST /session/431F0707-71BD-4645-B085-5BD750FC2067/element/42.2099874/value HTTP/1.1
Accept: application/json, image/png
Connection: Keep-Alive
Content-Length: 31
Content-Type: application/json; charset=utf-8
Host: 127.0.0.1:4723
User-Agent: selenium/3.141.0 (.net windows)
{"value":["This is some text"]}
HTTP/1.1 200 OK
Content-Length: 63
Content-Type: application/json
{"sessionId":"431F0707-71BD-4645-B085-5BD750FC2067","status":0}
==========================================
POST /session/431F0707-71BD-4645-B085-5BD750FC2067/element HTTP/1.1
Accept: application/json, image/png
Connection: Keep-Alive
Content-Length: 31
Content-Type: application/json; charset=utf-8
Host: 127.0.0.1:4723
User-Agent: selenium/3.141.0 (.net windows)
{"using":"name","value":"Edit"}
HTTP/1.1 200 OK
Content-Length: 128
Content-Type: application/json
{"sessionId":"431F0707-71BD-4645-B085-5BD750FC2067","status":0,"value":{"ELEMENT":"42.3148312.3.-2147483646.27904.691604525.2"}}
==========================================
POST /session/431F0707-71BD-4645-B085-5BD750FC2067/element/42.3148312.3.-2147483646.27904.691604525.2/click HTTP/1.1
Accept: application/json, image/png
Connection: Keep-Alive
Content-Length: 2
Content-Type: application/json; charset=utf-8
Host: 127.0.0.1:4723
User-Agent: selenium/3.141.0 (.net windows)
{}
HTTP/1.1 400 Bad Request
Content-Length: 175
Content-Type: application/json
{"status":105,"value":{"error":"element not interactable","message":"An element command could not be completed because the element is not pointer- or keyboard interactable."}}
I got it to work by using the Microsoft.WinAppDriver.Appium.WebDriver Prerlease nugget package instead of the Appium.WebDriver 4.1.1 nuget package.
Then, the example here works perfectly:
https://github.com/microsoft/WinAppDriver/blob/master/Samples/C%23/NotepadTest/ScenarioMenuItem.cs

Axios REST Preflight OPTIONS 400 status on IE/Edge

I have a problem with my requests using Edge/IE. I'm getting a code 400 code on
preflight OPTIONS.
I'm adding a 2 additional headers to all my requests in application with axios:
Authorization:
if ( token ) {
axios.defaults.headers.common[ 'Authorization' ] = 'Bearer ' + token;
} else {
delete axios.defaults.headers.common[ 'Authorization' ];
}
Accept-Language:
if ( lang ) {
axios.defaults.headers.common[ 'Accept-Language' ] = lang;
} else {
delete axios.defaults.headers.common[ 'Accept-Language' ];
}
Here's how my request headers works in Chrome:
Accept-Language: pl-PL
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJOZXcgUGFzdG9yYWwgQXBwIiwiYXVkIjoiTmV3IHBhc3RvcmFsIHVzZXIiLCJpYXQiOjE1MTM1OTEzODUsImV4cCI6MTUxMzU5ODU4NSwidWlkIjoxMSwidHlwZSI6NCwibGFuZ3VhZ2UiOjEsImRpc3BsYXlOYW1lIjoiVGVzdG8gUHJvYm9zemN6eiJ9.qyFHZuCHC9-NpNqjY7keY7j4LE5zu5JKxK9VyAFwH60
Request headers in Edge:
Accept: */*
Accept-Encoding: gzip, deflate
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 0
Host: 52.169.186.226
Origin: http://localhost:8080
Referer: http://localhost:8080/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299
Response headers:
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Origin, Authorization
Access-Control-Allow-Methods: OPTIONS,POST
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Mon, 18 Dec 2017 11:29:49 GMT
Server: Apache/2.4.25 (Ubuntu)
When I remove Accept-Language header the application start working in Edge, but problem still exists in IE.
The only messages from browser is code http error 400 and the console log of error is:
description: "Network Error"
message: "Network Error"
stack: "Error: Network Error at createError (http://localhost:8080/index_bundle.js:68811:3) at handleError (http://localhost:8080/index_bundle.js:68656:7)"
Rest of the headers is standard for axios. On the backend we're using Slimp PHP framework.
Any idea how to debug the problem, or similar problems using standard REST requestes with React + Axios? Or what should I check in first order?

SOAP attachments in WireMock

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!

Getting 500 error (missing ;) from blobstore upload

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.

Jasper webservice: Invalid resource descriptor

I try to upload a simple image via REST webservice to the jasper server.
This is the HTTP request/response, I'm getting "400 Bad Request: Invalid resource descriptor".
I tried to copy a valid resource descriptor from the repository and re-upload it but it gives the same error!
(The dots represent \r\n and \t chars.)
T 10.84.6.166:36057 -> 10.84.6.166:8080 [AP].
PUT /jasperserver/rest/resource/reports/Customers/3221/image01.gif HTTP/1.1.
User-Agent: useragent.
Host: 10.84.6.166:8080.
Accept: */*.
Cookie: JSESSIONID=5D8D24835E61ED65ABD982964243C06B.
Content-Type: multipart/form-data; boundary="72e01e9922f8bb1669638258c2a2a155".
Content-Length: 23796.
Expect: 100-continue.
.
T 10.84.6.166:8080 -> 10.84.6.166:36057 [AP]
HTTP/1.1 100 Continue.
.
T 10.84.6.166:36057 -> 10.84.6.166:8080 [AP]
--72e01e9922f8bb1669638258c2a2a155.
Content-Disposition: form-data; name="ResourceDescriptor".
Content-Length: 811.
Content-Type: text/plain; charset=UTF-8.
Content-Transfer-Encoding: 8bit.
.
<resourceDescriptor name="s2" wsType="img" uriString="/reports/Customers/3221/s2.png" isNew="true">.
.<label><![CDATA[serverattacks_13-06-01.png]]></label>.
.<creationDate>1373470272965</creationDate>.
.<resourceProperty name="PROP_RESOURCE_TYPE">.
..<value><![CDATA[com.jaspersoft.jasperserver.api.metadata.common.domain.FileResource]]></value>.
.</resourceProperty>.
.<resourceProperty name="PROP_PARENT_FOLDER">.
..<value><![CDATA[/reports/Customers/3221]]></value>.
.</resourceProperty>.
.<resourceProperty name="PROP_VERSION">.
..<value><![CDATA[0]]></value>.
.</resourceProperty>.
.<resourceProperty name="PROP_HAS_DATA">.
..<value><![CDATA[true]]></value>.
.</resourceProperty>.
.<resourceProperty name="PROP_IS_REFERENCE">.
..<value><![CDATA[false]]></value>.
.</resourceProperty>.
</resourceDescriptor>.
--72e01e9922f8bb1669638258c2a2a155.
Content-Disposition: form-data; name="/reports/Customers/3221/s2.png".
Content-Length: 22544.
Content-Type: application/octet-stream.
Content-Transfer-Encoding: binary.
.
<long binary png contents>
--72e01e9922f8bb1669638258c2a2a155--.
T 10.84.6.166:8080 -> 10.84.6.166:36057 [AP]
HTTP/1.1 400 Bad Request.
Server: Apache-Coyote/1.1.
Pragma: No-cache.
Cache-Control: no-cache.
Expires: Thu, 01 Jan 1970 01:00:00 CET.
P3P: CP="ALL".
Content-Type: text/xml;charset=UTF-8.
Content-Length: 27.
Date: Thu, 11 Jul 2013 08:42:09 GMT.
Connection: close.
.
Invalid resource descriptor
Update:
I still don't know what's wrong but I finally got it working and released a Jasper PHP Library on github: http://blog.flowl.info/2013/jasper-php-library-on-github/
I tried to update jrxml on jasperServer. I found and buld java tests. I found working example of updating image on JasperServer.Mаy it is help уou.(With help of this example i wrote request for updating jrxml on jasperServer. And it is works!)
POST http://repsuite.cheby.ru:8080/jasperserver/rest/resource/SAMPLE_REST_FOLDER/JUNIT_IMAGE_FILE HTTP/1.1
Content-Length: 5560
Content-Type: multipart/form-data; boundary=dzFSpJmyJB0pL6bHxKgtqI4VmaKgL9pTWCrLeJv
Host: repsuite.cheby.ru:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Cookie: JSESSIONID=E485652B97C69549403D8CEEA0DC0855
Cookie2: $Version=1
--dzFSpJmyJB0pL6bHxKgtqI4VmaKgL9pTWCrLeJv
Content-Disposition: form-data; name="ResourceDescriptor"
<resourceDescriptor name="JUNIT_IMAGE_FILE" wsType="img" uriString="/SAMPLE_REST_FOLDER/JUNIT_IMAGE_FILE" isNew="true">
<label>jaspersoft logo</label>
<description>jaspersoft logo</description>
<creationDate>1308696383000</creationDate>
<resourceProperty name="PROP_RESOURCE_TYPE">
<value>com.jaspersoft.jasperserver.api.metadata.common.domain.FileResource</value>
</resourceProperty>
<resourceProperty name="PROP_PARENT_FOLDER">
<value>/SAMPLE_REST_FOLDER</value>
</resourceProperty>
<resourceProperty name="PROP_VERSION">
<value>0</value>
</resourceProperty>
<resourceProperty name="PROP_IS_REFERENCE">
<value>false</value>
</resourceProperty>
<resourceProperty name="PROP_HAS_DATA">
<value>true</value>
</resourceProperty>
</resourceDescriptor>
--dzFSpJmyJB0pL6bHxKgtqI4VmaKgL9pTWCrLeJv
Content-Disposition: form-data; name="/SAMPLE_REST_FOLDER/JUNIT_IMAGE_FILE"; filename="jasperSoftLogo_2.jpg"
Content-Type: application/octet-stream
----Binary content of image----