How do I set http headers in Adobe Illustrator ExtendScript when using the BridgeTalk HttpConnection object? - adobe-illustrator

I am trying to make http post requests from within Illustrator ExtendScript (via BridgeTalk) and for the most part it is working. However, the documentation on using HttpConnection is non-existent and I am trying to figure out how to set http-headers. The HttpConnection object has both a requestheaders and responseheaders property so I suspect it is possible.
By default, the post requests are being sent with the Content-Type header "text/html", and I would like to override it so that I can use either "application/x-www-form-urlencoded" or "multipart/form-data".
Here is what I have so far:
var http = function (callback) {
var bt = new BridgeTalk();
bt.target = 'bridge' ;
var s = '';
s += "if ( !ExternalObject.webaccesslib ) {\n";
s += " ExternalObject.webaccesslib = new ExternalObject('lib:webaccesslib');\n";
s += "}\n";
s += "var html = '';\n";
s += "var http = new HttpConnection('http://requestb.in/1mo0r1z1');\n";
s += "http.method = 'POST';\n";
s += "http.requestheaders = 'Content-Type, application/x-www-form-urlencoded'\n";
s += "http.request = 'abc=123&def=456';\n";
s += "var c=0,t='';for(var i in http){t+=(i+':'+http[i]+'***');c++;}t='BEFORE('+c+'):'+t;alert(t);\n"; // Debug: to see what properties and values exist on the http object
s += "http.response = html;\n";
s += "http.execute() ;\n";
s += "http.response;\n";
s += "var t='AFTER:';for(var i in http){t+=(i+':'+http[i]+'***');}alert(t);\n"; // Debug: to see what properties and values have been set after executing
bt.body = s;
bt.onResult = function (evt) {
callback(evt);
};
bt.onError = function (evt) {
callback(evt);
};
bt.send();
};
Things to note:
If I try setting the requestheaders properties like in my code above, the request fails. If I comment it out, the request succeeds. The default value for requestheaders is undefined.
Examining the http object after a successful request, shows the reponseheaders properties to be set to: "Connection, keep-alive,Content-Length, 2,Content-Type, text/html; charset=utf-8,Date, Wed, 24 Jun 2015 09:45:40 GMT,Server, gunicorn/18.0,Sponsored-By, https://www.runscope.com,Via, 1.1 vegur". Before the request executes, the responseheaders is set to undefined.
If anyone could help me set the request headers (in particular the Content-Type header), I would be eternally grateful!

Solved it!
The key for setting the content-type header is to set the http.mime property as follows:
s += "http.mime = 'application/x-www-form-urlencoded';\n";
Also for completeness, you can add your own custom headers as follows:
s += "http.requestheaders = ['My-Sample-Header', 'some-value'];\n";
(It turns out the headers is an array which takes the format [key1, value1, key2, value2, .......])

Related

How to get request body in angular from ActivatedRoute

As i can get the query params by using ActivatedRoute which is get request. but how can i get request body by using ActivatedRoute from post request. If ActivatedRoute is not right option to get then how should i get request body
This is my jsp code:-
var res = "url which i am creating";
var url =res[0];
var mapForm = document.createElement("form");
mapForm.target = "Test";
mapForm.method = "post";
mapForm.action = url;
//Splitting parameters from url to add into body
var res1 =res[1].split("=");
var name = res1[0];
var value = res1[1];
mapInput3 = document.createElement("input");
mapInput3.type = "hidden";
mapInput3.name =name;
mapInput3.value = value;
mapForm.appendChild(mapInput3);
document.body.appendChild(mapForm);
map = window.open("", "Test", "menubar,
toolbar, location, directories, status, scrollbars,
resizable, dependent, width=1200, height=600,
left=0,top=0");
if (map) {
mapForm.submit();
}
this is my angular code:-
this.activeRoute.queryParams.subscribe(params => {
this.authKey = params['auth_key'];
});
Now if I sent parameter through get method from jsp, I am able to get it from above angular code.
but if i sent params through post method then i get message as " Cannot post"
If I got you right you want to get the body of the query.
You can use snapshot.get and when declare a it with a value something like this ->
const t = this.route.snapshot.mapedQuery.get()
The value of- t is your query body.
Answered from my phone so I can’t format the code

Pentaho - upload file using API

I need to upload a file using an API.
I tried REST CLIENT and didn't find any options.
Tried with HTTP POST and that responded with 415.
Please suggest how to accomplish this
Error 415 is “Unsupported media type”.
You may need to change the media type of the request or check whether that type of file us accepted by the remote server.
https://en.m.wikipedia.org/wiki/List_of_HTTP_status_codes
This solution uses only standard classes of jre 7. Add a step Modified Java Script Value in your transformation. You will have to add two columns in the flow: URL_FORM_POST_MULTIPART_COLUMN and FILE_URL_COLUMN, you can add as many files as you want, you will just have to call outputStreamToRequestBody.write more times.
try
{
//in this step you will need to add two columns from the previous flow -> URL_FORM_POST_MULTIPART_COLUMN, FILE_URL_COLUMN
var serverUrl = new java.net.URL(URL_FORM_POST_MULTIPART_COLUMN);
var boundaryString = "999aaa000zzz09za";
var openBoundary = java.lang.String.format("\n\n--%s\nContent-Disposition: form-data\nContent-Type: text/xml\n\n" , boundaryString);
var closeBoundary = java.lang.String.format("\n\n--%s--\n", boundaryString);
// var netIPSocketAddress = java.net.InetSocketAddress("127.0.0.1", 8888);
// var proxy = java.net.Proxy(java.net.Proxy.Type.HTTP , netIPSocketAddress);
// var urlConnection = serverUrl.openConnection(proxy);
var urlConnection = serverUrl.openConnection();
urlConnection.setDoOutput(true); // Indicate that we want to write to the HTTP request body
urlConnection.setRequestMethod("POST");
//urlConnection.addRequestProperty("Authorization", "Basic " + Authorization);
urlConnection.addRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
var outputStreamToRequestBody = urlConnection.getOutputStream();
outputStreamToRequestBody.write(openBoundary.getBytes(java.nio.charset.StandardCharsets.UTF_8));
outputStreamToRequestBody.write(java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(FILE_URL_COLUMN)));
outputStreamToRequestBody.write(closeBoundary.getBytes(java.nio.charset.StandardCharsets.UTF_8));
outputStreamToRequestBody.flush();
var httpResponseReader = new java.io.BufferedReader(new java.io.InputStreamReader(urlConnection.getInputStream()));
var lineRead = "";
var finalText = "";
while((lineRead = httpResponseReader.readLine()) != null) {
finalText += lineRead;
}
var status = urlConnection.getResponseCode();
var result = finalText;
var time = new Date();
}
catch(e)
{
Alert(e);
}
I solved this by using the solution from http://www.dietz-solutions.com/2017/06/pentaho-data-integration-multi-part.html
Thanks Ben.
He's written a Java class for Multi-part Form submission. I extendd by adding a header for Authorization...

Issue with BTC-e API in App Script, method parameter

I am trying to incorporate the BTC-e.com API in to a google docs spreadsheet.
The API documentation is here: https://btc-e.com/api/documentation
The method name is sent via POST parameter method.
As the URLFetchApp requires me to set the type of request as POST by a parameter method and I then have another parameter called method to be set as getInfo.
How can I go about setting the fetch method as POST and have the API parameter method as getInfo.
Below is the function this relates too. Also I am sure there a more issues in my work I am yet to find.
function inventory() {
var nonce=Number(SpreadsheetApp.getActiveSheet().getRange('K2').getValue());
var token=SpreadsheetApp.getActiveSheet().getRange('K1').getValue();
var tokenEndpoint = "https://btc-e.com/tapi";
var sign= 'TEMP'
var head = {
'Content-Type': 'application/x-www-form-urlencoded',
'Key': token,
'Sign': sign
}
var params = {
method : "POST",
method : "getInfo",
headers: head,
contentType: 'application/x-www-form-urlencoded',
method : "getInfo",
nonce: nonce
}
var request = UrlFetchApp.getRequest(tokenEndpoint, params);
var response = UrlFetchApp.fetch(tokenEndpoint, params);
var response2=String(response);
SpreadsheetApp.getActiveSheet().getRange('K2').setValue(nonce+1);
SpreadsheetApp.getActiveSheet().getRange('I16').setValue(response2);
SpreadsheetApp.getActiveSheet().getRange('I17').setValue(nonce);
}
This just yields the error
Attribute provided with invalid value: method
Thanks,
Steve
PS: First time posting, I tried to get the format correct.
I made the following Google JavaScript function to do POST access to BTC-e. You can find this function in action in the example spreadsheet I made to demonstrate the BTC-e API functions.
function btceHttpPost(keyPair, method, params, nonce) {
if (keyPair === undefined) {
return "{'error':'missing key pair'}"
}
if (params === undefined) {
params = '';
}
// Cleanup keypair, remove all \s (any whitespace)
var keyPair = keyPair.replace(/[\s]/g, '');
// Keypair example: "AFE730YV-S9A4FXBJ-NQ12HXS9-CA3S3MPM-CKQLU0PG,96a00f086824ddfddd9085a5c32b8a7b225657ae2fe9c4483b4c109fab6bf1a7"
keyPair = keyPair.split(',');
var pubKey = keyPair[0];
var privKey = keyPair[1];
// As specified on the BTC-e api (https://btc-e.com/api/documentation) the
// nonce POST parameter must be an incrementing integer (>0). The easiest
// implementation is the use of a timestamp (TS), so there is no need
// for persistant storage. Preferable, the resolution of the TS should be
// small enough the handle the desired call-frequency (a sleep of the TS
// resolution can fix this but I don't like such a waste). Another
// consideration is the sizeof the nonce supported by BTC-e. Experiments
// revealed this is a 32 bit unsigned number. The native JavaScript TS,
// stored in a float, can be 53 bits and has a resolution of 1 ms.
if (nonce === undefined)
// This time stamp counts amount of 200ms ticks starting from Jan 1st, 2014 UTC
// On 22 Mar 2041 01:17:39 UTC, it will overflow the 32 bits and will fail
// the nonce key for BTC-e
var nonce = Math.floor((Date.now() - Date.UTC(2014,0)) / 200);
// Construct payload message
var msg = 'nonce=' + nonce + '&method=' + method + params;
var msgSign = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, msg, privKey);
// Convert encoded message from byte[] to hex string
for (var msgSignHex = [], i = 0; i < msgSign.length; i++) {
// Doing it nibble by nibble makes sure we keep leading zero's
msgSignHex.push(((msgSign[i] >>> 4) & 0xF).toString(16));
msgSignHex.push((msgSign[i] & 0xF).toString(16));
}
msgSignHex = msgSignHex.join('');
var httpHeaders = {'Key': pubKey, 'Sign': msgSignHex};
var fetchOptions = {'method': 'post', 'headers': httpHeaders, 'payload': msg};
var reponse = UrlFetchApp.fetch('https://btc-e.com/tapi', fetchOptions);
return reponse.getContentText();
};
The problem looks to be with your params object . You have method set thrice in the same object, which is a source of confusion.
Next, take a look at the documentation for UrlFetchApp.fetch() ( https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object) ) . The method can take a value of post, get, delete, put.
The getInfo should probably be appended to your URL to make it
var tokenEndpoint = "https://btc-e.com/tapi/getInfo"
Per the docs, you also have to put in more parameters to the request, nonce, api key etc. Use this as a starting point, revisit the documentation and get back to SO if you still have trouble

Why is the HTTP header 'content-length' not always set?

I am requesting files from an IBM HTTP server via a Websphere App Server (7FP19). For most files I get the content-length header but for some, not. I discovered that when I set the last-modified value in the request to '0' then I get the content-length for all files.
This seems a bit wierd to me. Does anyone know why this might be or is it just a coincidence?
Here is some code:
connection = (HttpURLConnection) url.openConnection();
for (String value : cookies.values()) {
connection.addRequestProperty("Cookie", value); //$NON-NLS-1$
}
connection.setDoOutput(true);
connection.setRequestProperty("User-Agent", USER_AGENT); //$NON-NLS-1$
//connection.setIfModifiedSince(localLastModified);
connection.setIfModifiedSince(0);
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(post);
wr.flush();
wr.close();
....
// set file attributes
long remoteDate = connection.getLastModified();
if(rc == 304)
data.lastModified = localLastModified;
else
data.lastModified = remoteDate;
data.retCode = connection.getResponseCode();
data.contentType = connection.getContentType();
data.contentEncoding = connection.getContentEncoding();
int expectedLength = connection.getContentLength();
if(expectedLength < 0) {
log.warn("Expected length: " + expectedLength);
}
UPDATE
this was running on Wesphere FP19. I returned to FP15 and the problem was gone. The length is always returned.
Are you just getting HTTP_NOT_MODIFIED/304 back which has no body and no C-L header? This seems to be working as expected.

FileUpload using HttpWebRequest returns (411) Length Required Error

I have written an ActiveX control which supports drag-drop of email attachments and disk files and uploads files to a web server.
I used the samples available at this link for Uploading files
Upload files with HTTPWebrequest (multipart/form-data)
I am sending data in chunks by setting the following properties
wr = (HttpWebRequest)WebRequest.Create(UploadUrl);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.ContentLength = contentLength;
wr.AllowWriteStreamBuffering = false;
wr.Timeout = 600000;
wr.KeepAlive = false;
wr.ReadWriteTimeout = 600000;
wr.ProtocolVersion = HttpVersion.Version10;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
wr.SendChunked = true;
wr.UserAgent = "Mozilla/3.0 (compatible; My Browser/1.0)";
rs = wr.GetRequestStream();
With the above settings I am getting an error (411) Length Required.
After reading the following article I realized, I dont need to set Content-Length property when I set SendChunked = true;
http://en.wikipedia.org/wiki/Chunked_transfer_encoding
But the Microsoft example code here doesn't do so
http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.sendchunked.aspx
After further digging I came to know that Chunked encoding is supported in HTTP version 1.1 only. So I changed the property as follows
wr.ProtocolVersion = HttpVersion.Version11;
Now I don't see that 411 error any more.
Now, can someone with better knowledge verify my understanding here and please let me know if I am doing right.
Thanks
Ravi.
They are both just mechanisms to let the receiver know when it has reached the end of the transfer. If you want to use Content-Length, it is pretty simple. Just take your encoded byte array of POST data, and use the Length property.
ASCIIEncoding encoding = new ASCIIEncoding ();
byte[] postDataByteArray = encoding.GetBytes (postData);
wr.ContentLength = postDataByteArray.Length;