First request fails with HTTP 400 (Bad Request) after reading HttpRequest.InputStream - asp.net

I develop an asmx web service (i.e. ASP.NET 2.0).
There's a piece of code that may read the contents of the HTTP request (via HttpContext.Current.Request.InputStream) while processing it. I realise that InputStream may only be read once for a request, and I make sure I never try to read it more than once.
The problem seems to be that if InputStream happens to be read during the early stages of the application's lifecycle (e.g. after pskill w3wp, during Application_Start), the HTTP request fails with a HTTP 400 - Bad Request error, with no explanation given, no exception thrown and no entry in the httperr log. If it is read later (e.g. within the web method itself), requests run fine whether InputStream is read or not. Application_Start runs fine if InputStream isn't read.
Is this some sort of ASP.NET bug? IIS bug? Or am I doing something wrong by daring to read InputStream? And if so, is there another way to get a look at the "raw" contents of the request without disturbing the inner workings of IIS/ASP.NET?
In short, adding this code within Application_Start is enough to reproduce this error:
using (StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream))
reader.ReadToEnd();

Couldn't find a way to read request contents during Application_Start without disturbing inner workings of ASP.NET/IIS. Instead, ended up making sure this doesn't happen until Application_Start is over (and also doesn't happen from the moment Application_End starts, which also turned out to be problematic and created access violations).

You have to no use the using bloc because this has as effect to close the reader and by consequence to close the inputstream of httprequest

I would suggest not attempting to read the Request.InputStream during Application_Start - it's used for initialising the application. Accessing the Request object from within Application_Start results in an exception "Request is not available in this context."
The fact that you are wanting to read the input stream suggests you should be using Application_BeginRequest instead - this has access to request and response.
In Summary:
Application_Start
Fires once when the application starts. While usually triggered by the first request, it occurs before the first request is set up. Don't do request specific code in here as it doesn't have access to Request and Response.
Application_BeginRequest
Fires for every request before any page handlers are invoked - you can read the input, write to response, end the request, etc...
See these SO articles for more info:
Request is not available in this context
Replacement for HttpContext.Current.Request.ServerVariables["SERVER_NAME"] in Integrated Mode
When does HttpRequest get created?

Related

Unexpected GET method calls to ASP.NET ScriptService

Our error logger is picking up the following error periodically:
System.InvalidOperationException: Request format is unrecognized for
URL unexpectedly ending in '/TheMethodName'
The reason this error is being thrown is because the request to the script service is using the GET method, and the default security settings only allow POST requests.
The strange part is that the only place in our code where we are calling this particular service method is through an $.ajax call, and it is specifically using type: 'POST'. There is no other place in the app where a GET request is made for this service.
The ui is making the POST call every 20 seconds to retrieve some data, and it does not seem that the GET's are interfering with that -- they are just extraneous. I've looked at the IIS logs, and I can see the proper POST requests, and then sometimes a GET request.
As an added wrinkle, it's not just this web service that is getting the extra GET calls -- we are logging these to several other service endpoints as well.
My guess is that the browser or a proxy server or something is making these calls on its own (like as part of prefetching or some sort of caching), but I have no evidence of that. In looking at the user agent for the bad requests, they are coming in from a variety of browsers.
Has anybody else seen this before, or have an idea of what might be causing it?

Custom HttpModule is not called when used Server.Transfer

I have code in my project which changes the URL containing the text as querystring to number to get the data from the database. I am checking the querystring in page load and if it contains the name rather than the number I am mapping it to the numeric key. Now I have to execute the page life cycle again. I had two choice either use the
Response.Redirect
but I do not want the URL in the client browser to change so I went with the
Server.Transfer
The problem I started facing is that I have a custom httpmodule which is used to log the URLs in the database. I realized that
BeginRequest
in the http module is not firing after the
Server.Transfer
My application is working fine in the case of
Response.Redirect.
I am not sure how and why Server.Transfer is skipping my HttpModule and if it is how it works ?
Server.Transfer is a completely server side mechanism - it instantiates the new Page class based on the path to .aspx file and transfers the execution there (including all state information for the built-in objects). There is no new request and nothing goes again through the pipeline (so among other things HttpModules are not re-executed), as the hosting part is interested this is still the same request - the response has just been created from different page than it was originally planed.
Response.Redirect falls to standard HTTP mechanism. On server side it throws an exception to break the current execution pipeline and return an 3xx status code. The browser then issues new request for the resource under the new URL. Both requests go through full pipeline on the server side.
So the answer to your question boils down to the fact that HttpModules are being executed for every upcoming request but in case of Server.Transfer there is no new upcoming request.

XML Load TimeOut

I am using below code to load a xml:
XmlDocument xdoc = new XmlDocument();
xdoc.Load("http://mydomain.com/video/list");
in normal situation it works fine, but some times i face a issue of response time out.
sometimes the url from which i wants to load my xml not response me and till that time my application also went timeout.
please tell me what should i do in such situation, so that either i can run my other code if it not responding me within 5 second or any other such solution in which i can do my code in case that url is not responding me xml file.
Thanks
You could try using a HttpWebRequest where you have the possibility to set the TimeOut for the request. In the case the remote resource doesn't response before this timeout value is reached an exception will be thrown which you could intercept and inform the user.

HTTP request/response handling untill page life cycle commences

What happens from the point an HTTP request is received on a TCP/IP port up until the Page fires the On_Load event?
The below link should give you detailed explanation about the asp.net application life cycle process.
http://msdn.microsoft.com/en-us/library/ms178473.aspx
Brifely to say.
Request is received by the server, the server determines the ISAPI extension to handle the request based on filename extension.
In case this is first request, it will create an app domain for maintaining isolation with this and other applications running.
then it creates hosting environment which will also create the objects like HttpContext, HttpRequest and HttpResponse.
After this the HTTPApplication object is created .
Afterwards the events in the global.asax which is the class inherited from the HTTPApplication object fires in the order defined in the link above.
The browser recieves the http response
The browser parses http headers and starts reading the HTTP content.
Parsing first the <head> section and parsing this, putting external resources on the get queue (first, css then javascript, ideally)
Parsing the <body> content and drawing elements on the viewport.
When the DOM is drawed to screen and is completely rendered. the page fires the on_load event.
When the HTTP request reaches the server, the server will then prepare the necessary file that is requested by the client and send it to the client. The client will then receive the entire content of the HTML page. Note that this is just the HTML and the browser still needs to make additional requests to the server for images and other types of files like applets if necessary.
Finally, to answer your question, it'll have to depend on where you put the onload event. If it's for the then this will be invoked when the body has completed loading. If it's in other node items, as we call it in JavaScript, then it'll be on the complete loading of that particular item.
Hope it helps :)
Cheers!

Detect that asp.net http headers already sent

I am adding headers to a page as follows:
Page.Response.AddHeader("foo", "bar");
Depending upon previous processing, sometimes this fails with "Server cannot append header after HTTP headers have been sent." I am dealing with this by enclosing Page.Response.AddHeader("foo", "bar"); within a try-catch construct. However, to keep things cleaner and avoid generating an exception is there any way to detect that the headers have already been sent? (btw if I try evaluating Page.Response.Headers then I get the following error: "This operation requires IIS integrated pipeline mode")
Thanks
As of .NET 4.5.2, you can do this using the now-public HeadersWritten property of HttpResponse (see the msdn docs):
if (HttpContext.Current.Response.HeadersWritten) { ... }
You can use an HttpModule to register for the PreSendRequestHeaders event. When it gets called, write a value to HttpContext.Current.Items indicating that the headers are being sent – and then everywhere else in your code you check the value in HttpContext.Current.Items to see if its been sent yet.
UPDATE: the HeadersWritten property is now available on the HttpResponse object.
Unfortunately, whilst the HttpResponse object has a property called HeadersWritten, and a backing field called _headersWritten, neither of these are accessible from outside of the System.Web assembly - unless you use Reflection. I'm not clear what you think you'll be able to obtain from the Headers collection, it may or may not exist, independently of whether the headers have been sent yet.
If you want to use Reflection, it may have it's own performance penalties, and it will require your application to run in full trust.
All of the publicly accessible methods on HttpResponse that involve the _headersWritten field seem to use it to throw an exception.
Trying setting buffer to false:
http://msdn.microsoft.com/en-us/library/950xf363.aspx
This will alleviate your first problem but your perfromance and user experience can suffer.
Also "This operation requires IIS integrated pipeline mode" is related to non-IIS 7 server processing that line of code. You can find more info on it here:
http://forums.asp.net/p/1253457/2323117.aspx

Resources