Passing an array inside the "parameters" of adapter in Worklight - adapter

The code part:
function PushRequests(strUser, eClientType, iSectorId, strDeviceId, arrRequests) {
var input = {
method : 'post',
returnedContentType : 'xml',
path : 'SomeAddress/PushRequests',
parameters : {
'strUser' : strUser.toString(),
'eClientType' : eClientType.toString(),
'iSectorId' : iSectorId.toString(),
'strDeviceId' : strDeviceId.toString(),
'arrRequests' : arrRequests // <- the array
}
};
return WL.Server.invokeHttp(input);
}
The response:
Procedure invocation error. Content is not allowed in prolog.,Failed to parse the payload from backend (procedure: HttpRequest)
I have tried to strignify the array by the navite way and via JSON. This is not the solution.
I know the problem is with the array passed. Does anybody know a workaround, or a way to correctly pass an array to the adapter?

I know the problem is with the array passed.
How do you know this?
Content is not allowed in prolog.
This is almost always a symptom of passing data to an XML parser that is invalid XML, or has some characters before the prolog, which is:
<?xml version="1.0" encoding="utf-8"?>
In your adapter, you've told it to expect XML from the backend HTTP service you're calling. I was able to reproduce the same message you see by returning invalid XML from my backend HTTP service. In fact, I can put anything in the response that is invalid XML, and I'll get the "Content is not allowed in prolog." message. I can return a page that is a 404 page, or with a Content-Type header of "text/plain". The adapter was told to expect XML, but given something else.
Please be sure to check that you are not getting a 404 page, or 500, or something else from the backend HTTP service your adapter is calling.
Here's how I reproduced the "Content is not allowed in prolog" message from my adapter:
First, create an adapter with xmltester.xml:
<wl:adapter name="xmltester"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wl="http://www.worklight.com/integration"
xmlns:http="http://www.worklight.com/integration/http">
<displayName>xmltester</displayName>
<description>xmltester</description>
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>http</protocol>
<domain>localhost</domain>
<port>3000</port>
</connectionPolicy>
<loadConstraints maxConcurrentConnectionsPerNode="2" />
</connectivity>
<procedure name="getStuff"/>
</wl:adapter>
and xmltester-impl.js:
function getStuff() {
var input = {
method : 'get',
returnedContentType : 'xml',
path : 'index.xml',
parameters : {
'arrRequests' : JSON.stringify(['one', 'two'])
}
};
return WL.Server.invokeHttp(input);
}
I created a node server (server.js) to be my backend:
var express = require('express');
var app = express();
var port = 3000;
app.get('/index.xml', function(req, res){
var body = '<?xml version="1.0" encoding="utf-8"?><boo/>';
res.setHeader('Content-Type', 'application/xml');
res.setHeader('Content-Length', body.length);
res.end(body);
});
app.listen(port);
console.log('Listening on port %s', port);
Started the server:
npm install express
node server.js
Then created a Worklight app with a button:
<button id="doit">Do it!</button>
And linked up a click listener to see what I get back from Worklight when the adapter is invoked:
$ = WLJQ;
$("#doit").click(function() {
var invocationData = {
adapter : 'xmltester',
procedure : 'getStuff',
parameters : []
};
WL.Client.invokeProcedure(invocationData,{
onSuccess : function(data) {alert("SUCCESS" + JSON.stringify(data));},
onFailure : function(data) {alert("FAILURE" + JSON.stringify(data));}
});
return false;
});
I could recreate the problem exactly when my backend server returned a payload with extra characters in front of the prolog (which you can try yourself by editing the server.js code above), like:
somethinghere<?xml version="1.0" encoding="utf-8"?>
Or any non-XML payload, for that matter.

returnedContentType : 'xml'
Failed to parse the payload from backend
Is the returned content in xml format? If not, can you cange the returnedContentType field to 'plain' or 'html' or whichever format you are expecting it in?

Related

IBM DataPower - How to handle HTML Response from openurl?

I tried looking for the solution in the forum but I was unable to find something similar to what I'm trying to achieve. I have a gateway script in an MPG which kinda looks like this:
session.INPUT.readAsJSON(function (error, json) {
if (error){
throw error;
} else {
var SAMLResponse = json['SAMLResponse'];
var RelayState = json['RelayState'];
var urlopen = require('urlopen');
var options = {
target: 'https://************.com/e32d32der2tj90g8h4',
method: 'POST',
headers: { 'HEADER_NAME' : 'VALUE'},
contentType: 'application/json',
timeout: 60,
sslClientProfile: 'ClientProfile',
data: {"SAMLResponse": SAMLResponse, "RelayState": RelayState}
};
urlopen.open(options, function(error, response) {
if (error) {
session.output.write("urlopen error: "+JSON.stringify(error));
} else {
var responseStatusCode = response.statusCode;
var responseReasonPhrase = response.reasonPhrase;
response.readAsBuffer(function(error, responseData){
if (error){
throw error;
} else {
session.output.write(responseData);
console.log(responseData);
}
});
}
});
}
});
I'm doing a POST request and the response I get from the urlopen function is an HTML page, how to I display the contents of that page in my browser? I need that to initiate a process flow. am I going in the wrong direction here? what's the best way to POST to a URI and display it's response in DataPower?
with regards to my experience with DataPower, I just started learning, So I might not be familiar with many of the concepts.
Thanks in Advance!
session.INPUT.readAsJSON() would indicate that you are receiving JSON data as the input (from the POST).
Since you are building this in a Multi-Protocol Gateway (MPGW) you need to set the Response type to non-xml if the response is HTML and if there is no backend call being made (other than the url-open()) you also must set the skip-backside=1 variable.
Is the scenario as:
JSON HTTP Request -> [MPGW] -> url-open() -> Backend server --|
HTTP Response <-----------------------------------------|
Or:
JSON HTTP Request -> [MPGW] -> url-open() --| (skip-backside)
HTTP Response <------------------------|
If there is no backend call I would recommend building this in a XML Firewall (XMLFW) service instead and set it to "loopback" and non-xml.
If there is a backend and that is where you are sending your HTML from the url-open() then only MPGW Response type needs to be set to non-xml.
If it is the second option the you can just set the payload and headers in GWS and just call the target (https://************.com/e32d32der2tj90g8h4) as teh MPGW backside connection, no need for the url-open().

In dart httpRequest getstring always error

I established a RESTful server, and I can get a simple string with my Chrome or IE using this URL: "http://localhost:8080/WebService/RESTful/getString"
But when using Dart, it always returns a error message:
"[object XMLHttpRequestProgressEvent]"
From the onError() callback method,
I'm sure that server returns a string with "text/plain" MIME type in Java.
Here is the code:
import 'dart:html';
void main() {
HtmlElement btn = document.body.querySelector("#btn");
btn.onClick.listen(onClick);
}
void onClick(Event v) {
var url = "http://localhost:8080/WebService/RESTful/getString";
HttpRequest.getString(url).then((str) {
window.alert(str.toString());
}, onError: (e) {
window.alert(e);
});
}
Who can help me ?
If you try to fetch resources from another server than the one your page was loaded from, this server needs to return CORS headers otherwise your browser refuses to fetch form this other server.
It depends on your server how this can be configured or added.
See for example
- How do you add CORS headers in Redstone interceptor?
- CORS with Dart, how do I get it to work?

Meteor - Parse Data from Incoming HTTP Request

For outgoing HTTP requests (using meteor.http.call) I can define params and/or data. The results are then available (via results.content).
How do I access and parse the body/contents/data of incoming HTTP requests?
Using iron-router, I have got as far as this:
Router.map(function () {
this.route('httpTest', {
path: '/httpTest',
action: function () {
var request = this.request;
var response = this.response;
console.log('request_body: '+ request.body);
// request.body does not work. what should it be????
N.B. I understand that I CAN access query parameters, but I want to access form data and/or json data from the body of an incoming http request.
The request is an incoming http message, which is a Readable Stream, so you can get the data of the request by reading from that stream.
The following should work (but I haven't tested it):
var readable = this.request;
var alldata = "";
readable.on('data', function(chunk) {
alldata += chunk;
})
readable.on('end', function() {
console.log('do something with alldata');
});
It may not be working because of the missing where: 'server'. Here is a working example:
Router.map(function() {
this.route('test', {
where: 'server',
action: function() {
console.log(this.request.body.make);
console.log(this.request.body.model);
this.response.writeHead(200, {'Content-Type': 'text/html'});
this.response.end('hello!\n');
}
});
});
From the command line I can hit this route with:
curl -X POST -H "Content-Type: application/json" -d '{"make":"honda","model":"civic"}' http://localhost:3000/test
Which prints the expected honda and civic in the server's terminal. It looks like this.request.body is already parsed so you can access any variables directly which is nice if your input is json.
To read the raw body, without having Node.js JSON-ify it, in a synchronous way, I used this:
Router.route("my/api", function() {
var rawBody = "";
var chunk;
while ((chunk = this.request.read()) !== null) {
rawBody += chunk;
}
}, { where: "server" });
(the asynch way proposed in another answer here didn't worked for me, although it should as per Node.js documentation).

how to parse a request in a node.js server built on net module

We are building a server with net module, and having hard time extracting the URL (and resource path) from the request. The following code crashes, saying:
Parameter 'url' must be a string not undefined.
File netServer.js:
var net = require('net');
var url = require('url');
var server = net.createServer(function(socket) { //'connection' listener
socket.on('connect', function(request) {
});
socket.on('data', function(request) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
});
socket.on('end', function() {
});
});
server.listen(8080, function() { //'listening' listener
console.log('server bound');
});
Any suggestions?
Are you trying to build an HTTP server? net is a TCP package, so all you get is the remoteAddress and remotePort, the rest will be sent on the data handler (which is just passed a Buffer, or a string, depending on the encoding).
Use the HTTP module for this, because it does all of the parsing for you.

Working with XML in a Firefox Add-on(ex Jetpack)

I'm currently developing a Firefox add-on(using https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/ ) that consumes an API where the return data is in xml.
My problem is that I need to parse the returned data, and would like to do that using a xml object.
Since the request module only supports JSON and Text ( https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/packages/addon-kit/docs/request.html#Response ) I need to convert the response.text to XML.
The code looks like this:
var Request = require('request').Request
.......
var req = Request({
url: https://to-the-api.com,
content: {
op: 'get-the-data-op',
password: "super-sec",
user: "username"
},
onComplete: function (response) {
dataAsText = response.text;
console.log("output: " + dataAsText);
}
});
req.post();
I have tried to user (new DOMParser).parseFromString(response.text, 'text/xml') but unfortunately it just fails with a error like ReferenceError: DOMParser is not defined
The question is if anyone of you guys have been able to create a Xml object inside a Firefox add-on, and if so, how?
Looks like the capability to parse response as xml was present, but has been removed. check out this bugzilla reference
Can't you use a normal XMLHttpRequest if you want to process the response as XML?
If DOMParser is unavailable you can try E4X:
var xml = new XML(response.text);
alert(xml.children().length());
You want to use the XMLHttpRequest object to handle your xhr request. Then when you get a response back access the responseXML object of the request variable. In the responseXML you'll have the documentElement and can use the querySelectorAll or querySelector to find elements you want. In each element you want just grab the textContent you need.
Here's an example to get you going (this looks for the 'xmls' element in the response):
var request = new require("xhr").XMLHttpRequest();
request.open('GET', 'https://to-the-api.com', true);
request.onreadystatechange = function (aEvt) {
if (request.readyState == 4) {
if(request.status == 200) {
var xmls = request.responseXML.documentElement.querySelectorAll("xmls");
for (var i = 0; i < xmls.length; i++) {
console.log("xml", i, xmls[i], xmls[i].textContent);
}
}
else {
console.log('Error', request.responseText);
}
}
};
request.send(null);

Resources