POST with JSON has intermitent WebAPI resolution issue - angularjs

This error has perplexed me. I have been working on this application for a year now and one of the most original parts of it just started failing for no apparent reason. I haven't made any configuration changes or changes in and around the area which is failing, so it is baffling me.
Requirement
In my SPA, click on a button and the JSON model associated to that button is sent to the server to be saved.
Implementation
return $resource('/api/audits/:auditId/auditAnswers', { auditId: auditId, auditAnswer: auditAnswer }).save(auditAnswer);
This in turn is handled by WebAPI 2.0
[Route("api/audits/{auditId}/auditAnswers")]
[HttpPost]
public ServiceResult SaveAuditAnswerByAudit(HttpRequestMessage request, Guid auditId, [FromBody]AuditAnswerModel auditAnswer)
{ ... }
Issue
This worked for a good year without issue. Now when I test in Firefox 46.0.1 hosted in IIS Express, only about 1 in 5 attempts actually reaches the WebAPI method. No other post seems to reach WebAPI at all.
The error occurs as soon as I attempt the post, so it does not seem like it's timing out, either.
Firefox reports
Accept application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length 348
Content-Type application/json;charset=utf-8
Host localhost:61032
Referer http://localhost:61032/QAT/Audits/f3fa490d-6324-4227-b8fa-a6be4d33dd82
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Also, no HTTP status code is reported.
The error Callback for $resource is called and the response object contains:
data null
status 0
statusText ""
I have come across this once already and fixed it by not posting the entire JSON to WebAPI, but there are times I need to do this and consider it the correct way to do so.
Thinking it may be browser related I have restarted the browser, computer, cleared cached, and none of these methods resolved the issue. However, using a different browser such as Chrome does not encounter this issue (yet).
The fact that it works "eventually" (after about 5 attempt) is most concerning to me.
Question
Is this a known issue? Is it my fault? Is there something I can do to fix it?

Related

POST http request for WIX database gives error

I built a wix website and wanted to have a database to accept data from a Form. I wrote the codes in wix corvid to accept data after some research. Please refer to attached image links for the code.
In order to test the same, I used http://www.apirequest.io. And it gives me the following error:
Error Submitting Request
Error: Request has been terminated Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.
If you site enforces CORS (i.e. Access-Control-Allowed-Origin is set to something other than *), then you may need to allow http://www.apirequest.io.
Regarding the permissions, I have made sure from the settings that 'Anyone can submit data to this collection'.
I am an absolute beginner for web development and http requests. Please support where I went wrong. I would be happy to do further reading on these subjects, please help.
enter image description here
enter image description here
The above question is solved and now it seems that it shouldn't have been here! I was making an error in generating the Http Request.
In case any anyone else is working with wix, the above code is correct in the attached images is correct.
The following http request triggers it:
POST /_functions/firstfunc HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 45
{"Title": "Mr.",
"Name": "John",
"Age": "58"}

gzip compression results in empty response on bad request, works fine otherwise

I am doing a HTTP POST request from a web client using angular with the following header:
Accept-Encoding: gzip, deflate, br
The server response content-type is application/json. When the response status is 200, everything works fine, my response has a body that I can see from the client. However, when the response status is 400, the response body is empty according to the client, but I am certain I am populating it on the server. Also, if I remove "gzip" from the request header above (no change server-side whatsoever), then everything works fine even with a 400 response status, in other words I can see the response body from the client. I'm running Tomcat with Spring on the server side.
It really seems like gzip is the cause of my problem here, but I don't understand why or how to fix it, any help would be appreciated.
Thanks in advance.
We figured it out, we were using an old version of the ehcache-web library and thus its GZipFilter, which didn't return the response body for any status other than 200. Upgrading to version 2.0.4 of that library fixed the issue.

angular HTTP auth: not getting browser login prompt

In my angular app, i am trying to do basic HTTP auth.
I send the http get request from angular without any credentials initially, as i assume that when the backend sends a 401 status, the browser would ask me for credentials and would then resubmit the request on its own.
But the browser login prompt is never displayed.
This is the error that i get:
angular.js:11756 GET http://localhost:8080/appName/rest/keys/Keys?batch=0&userName=Test 401 (Unauthorized)
These are the headers i get for response:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:origin, content-type, accept, authorization
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin:http://localhost:3001/
Content-Length:0
Date:Tue, 09 Aug 2016 14:53:26 GMT
Server:Apache-Coyote/1.1
WWW-Authenticate:Basic
I was hoping that the browser prompt would appear automatically when it encounters status 401, but it doesn't seem to be the case here. Am i missing something?
EDIT:
It does not work in Chrome and Firefox, but works in IE, IE displays a login prompt when i try to access the url, and works correctly with username and password, while Chrome directly gives a 401 error.
If i try to access the server url directly from address bar, then Chrome displays the login prompt and asks me for the credentials.
Not sure, but can it be a CORS issue?
Ok, i was able to resolve the issue.
The problem was indeed related to CORS, not in a direct way.
Also, it was working on IE since IE does not respect CORS and will anyways let you access cross origin.
Two things were missing:
Initially i was sending (along with other headers) Access-Control-Allow-Origin : * from the server, for enabling CORS.
Then i got to know this:
Firefox and Chrome require exact domain specification in
Access-Control-Allow-Origin header. For servers with authentication,
these browsers do not allow "*" in this header. The
Access-Control-Allow-Origin header must contain the value of the
Origin header passed by the client.
https://www.webdavsystem.com/ajax/programming/cross_origin_requests/
And then there was an issue related to cross origin browser auth:
By default, in cross-site XMLHttpRequest invocations, browsers will
not send credentials. A specific flag has to be set on the
XMLHttpRequest object when it is invoked.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
This specific flag is withCredentials : true, which needs to be set with the xhr request. I managed to set it with my http request from the angular app, and voila it worked!

How to detect if request came from mobile device

On server side is there any way to detect that particular request to API came from mobile device (from mobile app)?
I know about user agent sniffing but I dont like this aproach from few enough reasons not to implement it.
I also know I could add some flag to request when it comes from my mobile app, but this seems bit dirty as well.
Are there actually any 'proper' ways to do it?
I guess it doesn't change much but my backend is in node.js.
Greetings, thanks!
Tom
The general answer is no. You get a header / message from a device. All you know about the device is in the header and the device can write what it wants in it. If you are talking about http requests (which is indicated by agent lookup) you can look at a header here:
All you can do "reliable" is to look for the user agent. In my case it is Mozilla Firefox on Linux. But I could fake it if I want.
Host: somesite.org
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://somesite.org/index.php?page=2
Cookie: rteStatus=rte;
Cache-Control: max-age=0
Maybe you can get some informations from the referer if it is some chromium-mobile site or you can have a look at Accept and Accept-Enconding, maybe some mobile browsers accept different stuff. But there is no reliable way to determine the device but by its user Agent via header.
An other approach is to look if the request comes from an IP known as 3G or 4G pool. But this would just work if the requests is not coming via WLAN / WIFI. And I am not sure if a list of 3G / 4G IP address pools exists.
You can use UserAgent string for detecting. Below code in C#.
public bool IsMobileDevice(HttpRequest r){
String userAgetnt = r.UserAgent;
String deviceName = "Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini";
return Regex.IsMatch (r.UserAgent, deviceName);
}
To detect if request came from mobile app, you must pass Accept:application/json in each request, then in your controller detect if request expects or wants json, if request expects json then return json response otherwise do what you want.

Silverlight WebClient Accept header being overwritten in Firefox 3

I've got a Silverlight app that talks to a REST web service using the WebClient class. It runs fine in IE 8 and Chrome 5, but the web service call fails in Firefox 3.
I've narrowed down the problem: Firefox 3 is changing the Accept header of my HTTP request. here's my simplified code:
// Use the ClientHttp stack.
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
// Call the web service.
var webClient = new WebClient();
webClient.Headers["Accept"] = "application/json";
webClient.DownloadStringAsync(someUrl);
Using Fiddler to investigate the data on the pipes, the request has its header replaced:
GET /1/36497f32-1acd-4f4e-a946-622b3f20dfa5/Content/GetAllTextContentsForUser/0 HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Host: localhost:88
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Notice the 2nd line, "Accept" -- it's been replaced with text/html, xml, and other formats. Not what I'm looking for -- I absolutely need JSON coming back.
Is there a way to prevent Firefox from modifying my Accept header?
Turns out the Accept header is being overwritten in all browsers. IE and Chrome overwrite the Accept header with the value of "*/*" (star slash star). Firefox overwrites it with some strange value that specifies XML, among other things.
The answer to this problem is you cannot expect to have your Accept header preserved. The browser will overwrite the Accept header, even if you use ClientHttp.

Resources