IBM DataPower - How to handle HTML Response from openurl? - post

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

Related

$http error handling in AngularJS

$http in my AngularJS project not able to recognize 40X(401,403,405...) errors on iOS.
I am using 1.2.10 AngularJS version and Cordova version 3.4.0.
Below is the code I am using:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials,successCallback,errorCallback){
$http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
successCallback(response.data);
console.log("Success------"+JSON.stringify(response))
},function(data, status, headers, config){
errorCallback(data);
console.log("Error------"+JSON.stringify(data)+" "+status)
})
}
}
});
hello.loginUser($rootScope.encodedUserCredencials,function(persons) {
// success handler
}, function(data) {
// error handler
console.log(data.status+"===="+status)
});
data.status is returning 0 and status returns undefined.
Please help me to resolve this issue.
Tried to include the domain in whitelist on IOS.But no solution :( It still gives the same response.
But the same code works absolutely fine in Android.
Please help me to resolve this issue.
Thanks in advance :)
So you r using the $http from angular. Do you use the error callback or the second function in the then callback ?
Example
$http.get("someUrl")
.success(function(response){}) // if http code == 200
.error(function(response){}) // else
Or with then, that can take 2 functions. The first is the onSuccess, the second the onError function.
$http.get("someUrl")
.then(function(response){
// if http code == 200
},
function(response){
// else
});
The response parameter does also contain the error codes.
Consider using a $httpInterceptor to handle all errorcodes at the same place, instead handling them in every http callback.
UPDATE:
It seems, that the angular doc is incomplete/wrong for the success callback.
It doesnt pass 4 parameter there. It does pass a response object that contains all the information about request+response and the passed data.
Update to the edit:
Dont write callbacks by yourself. Use angular promises:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials){
return $http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
return response.data;
},function(response){
return response;
});
}
}
});
hello.loginUser($rootScope.encodedUserCredencials)
.then(function(persons) { // success handler
}, function(data) { // error handler
console.log(data);
});
Try this and tell me if the console.log logs something.
I had exactly the same problem. Cordova app, angular js, IPhone and 401 requests are not received in angular js http interceptor. They work fine on android devices.
My finding was that IPhone browser is handling those at a higher lever and trying to use WWW-Authenticate information to do authentication. This is why the response does not get to angular.
The only solution I found, was to change my service to return 400 instead of 401 in case of an api request. In this case I return 400 with an error message that I handle on client side.
I hope this helps.
My issue with the 403 status code was that my backend returned a response with status 403 but the body of a response did not contain a JSON string. It contained just a string - Authentication Failed.
The rejection variable was an object Error.
I encoded the body and the rejection variable contains a valid response error object.
To handle HTTP errors I use interceptors.
$httpProvider.interceptors.push(function($q, $location, redirect, HTTP_CODES) {
return {
'responseError': function(rejection) {
if (rejection.status === HTTP_CODES.FORBIDDEN) {
redirect('/login', $location.url());
}
return $q.reject(rejection);
}
};
});

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

Delete entry from database with WinJS and OData

I'm trying to delete an entry from the database by odata. I get the error message
{"error":{"code":"","message":{"lang":"en-US","value":"Bad Request - Error in query syntax."}}}
my code:
function deleteMonthEntry() {
var item = actMonthEntries.getItem(listIndex);
var queryString = "Stundens(" + item.data.datensatz_id + ")?$format=json";
var requestUrl = serviceUrl + queryString;
WinJS.xhr({
type: "delete",
url: requestUrl,
headers: {
"Content-type": "application/json"
}
}).done(
function complete(response) {
},
function (error) {
console.log(error);
}
);
}
My request URL looks like this:
requestUrl = "http://localhost:51893/TimeSheetWebservice.svc/Stundens(305233)?$format=json"
Thanks
Marlowe
At least I found the solution:
I've entered an filter request to my service like this:
TimeSheetWebservice.svc/Stundens?$filter=datensatz_id eq 305221
this returned the correct entry with this link:
TimeSheetWebservice.svc/Stundens(305221M)
So if I enter a M after the ID, everything works fin. But I have no idea where this M comes from.
Can anyone tell me the reason for this M? It does not belong to the ID. The ID is this
305221
Marlowe
Are you sure the server you're talking to supports the $format query option? Many don't. I would try removing that part of the request URI, and instead modify your headers value to specify an Accept header:
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
For servers where $format is allowed, giving it a json value is equivalent to providing an Accept header with the application/json MIME type.
In general, for a DELETE operation, the Accept header or $format value only matters for error cases. With a successful DELETE, the response payload body will be empty, so there's no need for the server to know about your format preference.

Backbone.js: POST request with empty value

I am trying to make a POST request.
Here my code:
var myModel = new MydModel({
content: "ciao"
});
console.log(myModel.get("content")); // "ciao"
myModel.save();
If I look to the network activity it looks like this:
The response part {id:0, content:"", ……}
In the header part: Request Payload {"content":"ciao"}
Here my model:
define([], function () {
var MyModel = Backbone.Model.extend({
url: function url ()
{
return "http://localhost/users";
}
});
return MyModel;
});
Is it my problem or is it in the server part?
send/receive vs request/response
a server receives requests and sends responses
a client sends requests and receives responses
in short
if {id:0, content:"", ……} (the response) is wrong, it's your server
if {"content":"asdasdsa"} (the request) is wrong, it's your client
There is little problem with receiving JSON-payload that "Backbone-client" sends to your Apache-server.
All you need to do is to manually parse JSON-payload from input on the server side ("php://input", for PHP), like this:
if($_SERVER['REQUEST_METHOD'] == 'PUT' || $_SERVER['REQUEST_METHOD'] == 'POST') {
$postStr = file_get_contents("php://input");
//json_decode throws error or returns null if input is invalid json
try {
$json = json_decode($postStr, true);
if(empty($json)) {
throw new Exception("Not valid json");
}
//must not be json, try query str instead
} catch(Errfor $e) {
$postVars = parse_str($postStr);
foreach($postVars as $key=>$data) {
$_POST[$key] = $data;
}
}
}
Full explanation you can find here:
http://colinbookman.com/2014/04/08/php-puts-posts-and-backbone-js/

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