Response.StatusCode and Internet Explorer - Display custom message? - asp.net

I am implementing a HttpRequestValidationException in my Application_Error Handler, and if possible, I want to display a custom message.
Now, I'm thinking about the StatusCode. In my current example, it sends a 200, which I think should not be done. I would like to send the (IMHO) more appropriate 400 Bad Request instead. However, at the same time, I would like to use Response.Write to enter a custom message. Firefox displays it properly, but IE7 gives me the Default unhelpful Internet Explorer Error Page.
On one side, I guess that Internet Explorer just assumes that everything <> 200 is simply not having any "good" content, and the RFC is not really clear here.
So I just wonder, is sending a HTTP 200 for an Error Page caused by a HttpRequestValidationException good practice or not? Are there good alternatives?

An HTTP 200 Response Code does not indicate an error. It indicates that everything was OK. You should not use a 200 response code for an error.
Internet Explorer shows its "Friendly Errors" page if the response is less than 512 bytes. Here's more on this issue: http://weblogs.asp.net/scottgu/archive/2006/04/09/442332.aspx,

No, it's certainly not a good practice. 2XX status codes mean (among other things) that the request is valid. Which is just the contrary to raising a HttpRequestValidationException.
I don't know how to make IE behave correctly, sadly. A slightly better way than to send a 200 would be to redirect it to an error page, but still far from perfect.

Internet Explorer shows what they call a "friendly HTTP error message" when the response is 4xx or 5xx. This option can be turned off by the user in IE's Tools.Options.Advanced[Browsing] dialog.
Sending a 200 for an error page is generally bad practice. One alternative would be to have a valid "Error" page that's supposed to show error messages (so a 200 would be okay) and then use a 3xx redirect to that page.

Related

IIS responding to single request with two responses

We have a user making a POST to our webserver (windows server 2003, IIS 6). They get the full response from our webapp, but then IIS also responds with a "400 Bad Request". No other information is provided (yes I have friendly errors turned off).
At first, I thought maybe it was some middleware injecting a response in there. However, I was able to find the following in the HTTPSys error logs which confirms that it is coming from our server:
2013-08-09 23:36:40 11901 80 HTTP/0.0 Unparsed - 400 - BadRequest -
There are a whole slew of these errors piling up, and I have no idea why. Unparsed doesn't really tell me anything, so I don't have much to go on. I was able to get them to produce a wireshark trace, which shows that we are indeed responding with the full correct response and then appending a 400 bad request response. I copied their request EXACTLY from wireshark and tried it from my machine and of course, I can't reproduce it (I get the one valid response back).
So I am completely unable to reproduce the "Unparsed" error, I WAS however able to get two responses back from one request. I intentionally broke the line endings between the request headers and body and I got back a full correct response followed by "Bad Request (Invalid Verb)".
Two questions
1) Does anyone have any ideas as to how to produce an "Unparsed" error in HTTPsys logs? Any thoughts on how I might go about reproducing this?
2) WHY is IIS responding to a single request with two responses? Is that normal behavior, or indicative of a configuration error?
Thanks for anyone willing to offer help on this terrible headache!
Going to answer my own question here because I wouldn't wish this pain upon anyone else.
It turned out their POST had a slight error in content-length, I am thinking it wasn't including the final "\r\n" but whatever it is the count ended up being short by 2.
The reason this never showed up when I copied the exact request and sent it from my machine was that I wasn't properly closing the connection. For some reason, closing the connection with a FIN actually makes the difference and causes the 400 Bad Request.
Not sure why this happens, maybe the extra chars sent in the initial request are somehow read when the FIN comes? I don't know, but there you have it. Fix the content-length and the pain goes away.

Wireshark not displaying GET or POST data

I'm a student and I'm taking my first networking class. I'm working on an assignment designed to get me used to using Wireshark and understanding packet transfers. Part of the assignment is to collect some data about a certain GET request, but my Wireshark isn't showing anything related to GET or POST requests.
I've discussed this with my instructor and he can't figure it out, either. I've tried uninstalling/reinstalling Wireshark, but haven't gotten anything different.
Here's what I'm getting when I should be getting GET data:
26030 1157.859131000 128.119.245.12 10.0.0.7 HTTP 564 HTTP/1.1 404 Not Found (text/html)
This is the first packet I get after connecting to the server (this comes from right-click "copy"). From what I've gathered from the assignment instructions and the instructor, this should get a GET request. Anyone have any ideas?
You can use a browser plugin like firebug to examine actual request and response headers being exchanged. Sometimes due to page caching actual document may not be refetched after only headers like if modified since since being exchanged or the browsers cached version has not expired.

What's the difference between a "GET" request and a "page refresh"?

Is there any difference between doing a "GET" request (type URL and Enter) compared to simply refreshing (CtrlR) the page?
No, it is not simply a get request, because on a page that you've POSTed to (from a separate form), the browser will confirm with you that you want to refresh the page because it is a POST request.
As for your question, you'll need to provide specifics for debugging purposes.
It is simply telling the browser to repeat the page load, which implies repeating the GET or POST request. Some browsers will inform the server that 304 (not-modified) is an acceptable response, and the server can reply with a 304 HTTP response to inform the browser that it's cached contents are valid
Most browsers ignore the Expires header if we do a "page refresh", yet respect it if we do a "url visit".
However, different browsers have their own way of differentiating "refresh" and "url visit", the only way to be sure is to manually test each one of them.

What's the most appropriate HTTP status code for an "item not found" error page

I'm curious what's the most appropriate HTTP status code for an "item does not exist" page.
If the page itself doesn't exist, I'll obviously use 404. However, one of my pages has a userid argument (it's an "edit user" page) and in case no user with the given user ID exists I'm displaying an error page, but I'd also like to send a 4xx status header (since "200 OK" doesn't really fit).
I guess 404 would be ok since it's "not found" and not "file not found", but I wonder if there's a better code for this case.
Getting overly clever with obscure-er HTTP error codes is a bad idea. Browsers sometimes react in unhelpful ways that obfuscate the situation. Stick with 404.
A 404 return code actually means 'resource not found', and applies to any entity for which a request was made but not satisfied. So it works equally-well for pages, subsections of pages, and any item that exists on the page which has a specific request to be rendered.
So 404 is the right code to use in this scenario. Note that it doesn't apply to 'server not found', which is a different situation in which a request was issued but not answered at all, as opposed to answered but without the resource requested.
204:
No Content.” This code means that the server has successfully
processed the request, but is not going to return any content
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204
404 is just fine. HTTP/1.1 Status Code Definitions from RFC2616
That's depending if userid is a resource identifier or additional parameter. If it is then it's ok to return 404 if not you might return other code like
400 (bad request) ‐ indicates a bad request
or
412 (Precondition Failed) e.g. conflict by performing conditional update
More info in free InfoQ Explores: REST book.
If the page itself doesn't exist, I'll obviously use 404.
What you said there is a bit confusing but I will have to assume that you're developing an API backend.
The problem is that whoever is consuming the API endpoint may be confused in two ways:
They may think the 404 returned is because the endpoint(resource) wasn't reached, Or
They might think that the item or user being requested wasn't found.
So the trick is, how are they going to know which is the right assumption?
Well, the answer is simple. Always try to attach a body to any errors that you returned from code. Errors that are returned by the server automatically do not have a body. So try to attach a body which you can document so that they can be able to use the content of the body to differentiate between code returned errors and server errors.
But in a nutshell, 404 is the right status to return, but try to attach a body to it indicating why 404 was returned.
An example could be:
// For illustration I'm just gonna use C#
Return NotFound(new { errorMessage: "Item requested was not found" });
Here, NotFound returns a 404 statuscode and the parameter is an object like
{ errorMessage: "some reason for the error"}. This way, you can always check if your error returned a body, and the you know it's returned from your code. Otherwise, the resource(link) wasn't found.
/**
* {#code 422 Unprocessable Entity}.
* #see WebDAV
*/
UNPROCESSABLE_ENTITY(422, "Unprocessable Entity")
Since it's a user-facing page always use 404. It's the only code people know usually.
For the api request, use 400 with the error message "No such user exists" or something along those lines.
204 is appropriate solution when the item not found:
404 Status Code:
404 status code automatically appears when the requested API is
unavailable. Links that lead to a 404 page are often called broken
or dead links and can be subject to link rot.
204 Status Code:
204 status code should when item not found which means your request
processed successfully and the content not found.

REST: Correct HTTP Response Code For a POST Which Is Ignored

We have a REST API which clients routinely POST and PUT data to. When they do this, sometimes they POST data which results in no change on our system. The POSTs and PUTs are well-formed, but they data they're sending is identical to the data in our database. When this happens, I've just found out that we're returning a 400 HTTP status. Unfortunatly, this means "bad request" as in "request could not be understood by the server due to malformed syntax".
Clearly this is not the case, but I'm told that we're going to use this since there's no other appropriate status code. Choices we've considered:
304 Not Modified. This, regrettably, is only for GET requests.
204 No Content. Seems close, but forbids an entity-body.
Other choices seem equally bad. We might go with 200 OK and have the relevant information in the XML document we return, but this doesn't seem very "RESTish". How does the REST world generally handle this?
(Fixed Not Modified response code. Thanks Mkoeller)
I think it's perfectly fine to return a 200 OK in that case, the data was correctly processed and the server did what it had to. Because the server processed correctly the data, it should return an OK status code. The fact that it ignored it internally is or should be irrelevant.
What the server did to the data should not be told to the clients, they should be told what happened to the request (processed ok, error occurred, and the like).
And if, for some weird reason (I can't think a valid one, btw), it is of interest to the clients, you have the response to tell them so.
If the clients are able to know the entity tag for the content on the server before they PUT, then using If-Match headers and the 412 Precondition Failed response exists for exactly the situation you describe.
From client view the server status is the same if the request content was the same on the server or not, right? Since the server afterwards holds excactly the content that was sent, why should the server respond with any kind of error status?
On the other hand why should the client bother if the request content was the same as already known to the server? It was successfully transfered to the server so the bulk of work is done. How is a client expected to react if there was a different response code for this situation?
Conclusion: Your situation of a request content equaling the existing content is no special case. You should respond with the same response status code. That might be 200, 302 or 303.

Resources