Temporary Servlet response from siteminder : "This page is used to hold your data " - http

Iam making an POST call using fetch from javascript to a servlet which returns a json response .
fetch('upload', {
method: 'post',
//body: data
body: formData
}).then(function (response) {
// console.log("response.text()--> ",response.text());
//return response.text();
if(response != '' && response != undefined){
return response.json();
}else{
return response;
}
}).then(function (result) {
if(result != '' && result != undefined){
failure=result.failure;
}
It works fine in IE but the same request when made from Chrome or Firefox browsers i get below response from Server.As this is considered as 200 response by fetch , it's using this response for further processing in the promise which is causing issues.
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY onLoad="document.AUTOSUBMIT.submit();">
This page is used to hold your data while you are being authorized for
your request.
<BR>
<BR>You will be forwarded to continue the authorization process.If this does not happen automatically, please click the Continue button
below.
Below are the request headers from chrome.
Request URL:https://devhost.com/dev/upload
Request Method:POST
Status Code:200 OK
Remote Address:XXX.XXX.XXX.XXX:443
Referrer Policy:no-referrer-when-downgrade
Cache-Control:no-store, max-age=0
Connection:close
Content-Length:2541
Content-Type:text/html; charset=iso-8859-1
Date:Wed, 16 Aug 2017 22:26:32 GMT
Expires:Wed, 16 Aug 2017 22:26:32 GMT
It seems this is a problem with the Siteminder setting , which is taking more time to validate a use This message is being sent back when server needs more time to validate and send response to the user(client), it sends a temporary reply to the client display the following message to the user.
Is there anyway to handle this from Siteminder or from Client side.

It looks like you are seeing the post preservation page, which is probably because SiteMinder wants to update your session or you aren't authorized. What is the action of the form element?

Related

File upload : who is responsible for setting HTTP headers

I'm trying to understand how HTTP file uploads work.
For instance, my VueJS app is calling a REST API (with Axios). When calling axios.request, no headers are set. There is just a FormData object containing the file to upload.
When the request arrives to the backend, I see that a Content-Type: multipart/form-data; ... header has been added to the request.
At which moment is this header created? Who is responsible for creating the header?
If it is a file upload Ajax request, in Axios, it's the browser that set the Content-Type: multipart/form-data;... header.
In Axios source code lib/adapters/xhr.js (the one that take charge of XMLHttpRequest), the HTTP request data will be checked. If it is an instance of FormData, then Content-Type header would be deleted and let browser do the job.
In lib/adapters/xhr.js (look at the comment in the source code):
if (utils.isFormData(requestData)) {
delete requestHeaders['Content-Type']; // Let the browser set it
}
For utils.isFormData(), the logic is:
// code in lib/utils.js
function isFormData(val) {
return (typeof FormData !== 'undefined') && (val instanceof FormData);
}

Axios network error on Cors Post request with status code 200

I use axios to communicate with my own API (not written in NodeJS).
When I post a non simple request axios always goes directly to the catch block displaying a network error in the console, even with 2 successful Http Requests.
Error: Network Error
Stack trace:
createError#http://localhost:3000/static/js/bundle.js:1634:15
handleError#http://localhost:3000/static/js/bundle.js:1170:14
There is also a CORS warning about a missing header
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8080. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
However it is included in the Options Request!
When I add 'Access-Control-Allow-Origin': '*' in the Axios request headers, the warning is gone, but the browser doesn't fire a Post request after the successful Options request.
For the sake of being complete here are the post request headers.
The code:
postForm = () => {
axios.post("http://127.0.0.1:8080/",
myComplexObj, {
headers: {
//'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
},
timeout: 15000
}
).then(res => {
console.log(res);
alert('success');
})
.catch(function(error) {
//code always end up here
console.log(error);
/*Error: Network Error
Stack trace:
createError#http://localhost:3000/static/js/bundle.js:1634:15
handleError#http://localhost:3000/static/js/bundle.js:1170:14
*/
console.log(error.response); //undefined
console.log(error.response.data); //undefined
}
})
Any help is gladly appreciated.
What I have tried:
Remove the timeout //no change
Remove the Catch block //still no success
Return status code 204 on Options and/or Post requests //no difference
You are confusing because status 200, however, the browser will not allow you to access the response of a CORS request if the Access-Control-Allow-Origin header is missing.
Here are some great articles that explain how CORS works:
https://www.html5rocks.com/en/tutorials/cors/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Anyway, I think that you are using Django. So, you need add to settings.py:
CORS_ORIGIN_WHITELIST = (
'localhost:8080',
'localhost'
)
Or wherever you have the axios code.

Chrome fails to download response body if HTTP status is an error code

I have a Node.js Express web server that returns an HTTP response JSON payload along with an error status (4xx or 5xx) when something goes wrong.
res.status(500).json({ error: 'message' });
From the Chrome browser developer console's Timing section, I can see a lot of time (up to 5 minutes) spent in the "Content Download" segment and ultimately I am getting "Failed to load response data" in the Response section after download fails.
Chrome developer console timing output
Other browsers like Firefox and Opera are able to successfully download the JSON payload successfully and display them in their respective developer consoles.
If I send back the HTTP status as 200, Chrome has no trouble downloading the payload.
Also, if I do not set the Cache-Control HTTP headers to "no-store, no cache...", Chrome is able to successfully download the payload with 4xx/5xx status. However, I would like to set this header as a good practice against cache misuse.
HTTP Response Headers in the success and failure case
Is there something specific I need to do for Chrome?
Thank you!
I just had a similar problem. For the request I used the fetch API and in case of an error I did not read the stream of the response body.
Neither the content of the response body was displayed in the devtools nor was the request included in the HAR export.
After debugging this in the console I noticed that the content is displayed in the response or preview tab as soon as I was reading the stream. (e.g.: await response.text())
Strangely enough the behavior changes as you described when the corresponding cache headers are not set.
In my case, it happened when nothing was awaiting the response body.
Before (no body is rendered in the preview tab):
async request(context: RequestOpts): Promise<Response> {
// ...
const response = await this.fetchApi(url, init);
if (response.status >= 200 && response.status < 300) {
return response;
}
throw new Error();
}
After:
async request(context: RequestOpts): Promise<Response> {
// ...
const response = await this.fetchApi(url, init);
if (response.status >= 200 && response.status < 300) {
return response;
}
throw await response.json();
}

Angular2 : detect error from HTTP post

I cannot interecept error from http post
a part of my mservice (http post method)
addApplicationLink(applicationLink: ApplicationLink){
let body = JSON.stringify(applicationLink);
let requestHeaders = new Headers();
var headers = new Headers();
headers.set('Content-Type', ['application/json; charset=utf-8']);
let reqoptions = new RequestOptions({
headers: headers
});
return this._http.post(this._applicationLinksUrl + this._linkServicePath,body,{headers: headers});
in my component :
addApplicationLink() {
//todo
this.addNewLink = false;
/* check if must be done after call real rest service */
//this.applicationLinks.push(this.applicationLinkAdd);
this._applicationLinkService.addApplicationLink(this.applicationLinkAdd)
.subscribe(data => {
this.applicationLinks.push(this.applicationLinkAdd)
},
error => {
// handle error
console.error('this an erreor ' + error.status)
}
)
When user tries to add two same applicationlinks , the backend returns an error 409
But when I execute , error.status displays 200 in browser console
I see also in browser console
XMLHttpRequest cannot load http://localhost:7001...... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 409.
rem : Http post is made with json , thus there is a prefligth call
Have you an idea to intercept error 409 ?
In fact, your server doesn't send back the CORS header (Access-Control-Allow-Origin' header is missing). This prevent the browser from providing the actual 409 error to the Angular2 application within the browser.
You need to fix first the problem on the server and you will be able to see this 409 error.
For more details about how CORS works, you could have a look at this article:
http://restlet.com/blog/2015/12/15/understanding-and-using-cors/

Web API as a Proxy and Chunked Transfer Encoding

I have been playing around with using Web API (Web Host) as a proxy server and have run into an issue with how my Web API proxy handles responses with the "Transfer-Encoding: chunked" header.
When bypassing the proxy, the remote resource sends the following response headers:
Cache-Control:no-cache
Content-Encoding:gzip
Content-Type:text/html
Date:Fri, 24 May 2013 12:42:27 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
When going through my Web API based proxy, my request hangs unless I explicitly reset the TransferEncodingChunked property on the response header to false:
response.Headers.TransferEncodingChunked = false;
I admit, I don't fully understand what impact setting the TransferEncodingChunked property has, but it seems strange to me that in order to make the proxy work as expected, I need to set this property to false when clearly the incoming response has a "Transfer-Encoding: chunked" header. I am also concerned about side effects to explicitly setting this property. Can anyone help me understand what is going on and why setting this property is required?
UPDATE: So I did a little more digging into the difference in the response when going through the proxy vs. not. Whether I explicitly set the TransferEncodingChunked property to false, the response headers when coming through the proxy are exactly the same as when not going through the proxy. However, the response content is different. Here are a few samples (I turned off gzip encoding):
// With TransferEncodingChunked = false
2d\r\n
This was sent with transfer-encoding: chunked\r\n
0\r\n
// Without explicitly setting TransferEncodingChunked
This was sent with transfer-encoding: chunked
Clearly, the content sent with TransferEncodingChunked set to false is in fact transfer encoded. This is actually the correct response as it is what was received from the requested resource behind the proxy. What continues to be strange is the second scenario in which I don't explicitly set TransferEncodingChunked on the response (but it is in the response header received from the proxied service). Clearly, in this case, the response is NOT in fact transfer encoded by IIS, in spite of the fact that the actual response is. Strange...this is starting to feel like designed behavior (in which case, I'd love to know how / why) or a bug in IIS, ASP.Net, or Web API.
Here is a simplified version of the code I am running:
Proxy Web API application:
// WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "Proxy",
routeTemplate: "{*path}",
handler: HttpClientFactory.CreatePipeline(
innerHandler: new HttpClientHandler(), // Routes the request to an external resource
handlers: new DelegatingHandler[] { new ProxyHandler() }
),
defaults: new { path = RouteParameter.Optional },
constraints: null
);
// ProxyHandler.cs
public class ProxyHandler : DelegatingHandler
{
protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
// Route the request to my web application
var uri = new Uri("http://localhost:49591" + request.RequestUri.PathAndQuery);
request.RequestUri = uri;
// For GET requests, somewhere upstream, Web API creates an empty stream for the request.Content property
// HttpClientHandler doesn't like this for GET requests, so set it back to null before sending along the request
if (request.Method == HttpMethod.Get)
{
request.Content = null;
}
var response = await base.SendAsync(request, cancellationToken);
// If I comment this out, any response that already has the Transfer-Encoding: chunked header will hang in the browser
response.Headers.TransferEncodingChunked = false;
return response;
}
}
And my web application controller which creates a "chunked" response (also Web API):
public class ChunkedController : ApiController
{
public HttpResponseMessage Get()
{
var response = Request.CreateResponse(HttpStatusCode.OK);
var content = "This was sent with transfer-encoding: chunked";
var bytes = System.Text.Encoding.ASCII.GetBytes(content);
var stream = new MemoryStream(bytes);
response.Content = new ChunkedStreamContent(stream);
return response;
}
}
public class ChunkedStreamContent : StreamContent
{
public ChunkedStreamContent(Stream stream)
: base(stream) { }
protected override bool TryComputeLength(out long length)
{
length = 0L;
return false;
}
}
From an HttpClient standpoint, content chunking is essentially a detail of the transport. The content provided by response.Content is always de-chunked for you by HttpClient.
It looks like there's a bug in Web API that it doesn't correctly (re-)chunk content when requested by the response.Headers.TransferEncodingChunked property when running on IIS. So the problem is that the proxy is telling the client, via the headers, that the content is chunked when in fact it is not. I've filed the bug here:
https://aspnetwebstack.codeplex.com/workitem/1124
I think your workaround is the best option at the moment.
Also notice that you have multiple layers here that likely weren't designed/tested for proxying scenarios (and may not support it). On the HttpClient side, note that it will automatically decompress and follow redirects unless you turn that behavior off. At a minimum, you'll want to set these two properties:
http://msdn.microsoft.com/en-us/library/system.net.http.httpclienthandler.allowautoredirect.aspx
http://msdn.microsoft.com/en-us/library/system.net.http.httpclienthandler.automaticdecompression.aspx
On the WebApi/IIS side, you've found at least one bug, and it wouldn't be suprising to find others as well. Just be forewarned there may be bugs like this currently writing a proxy using these technologies outside their main design use cases.

Resources