Return request HttpModules as quickly as possible - iis-7

In a web site I capture the http POST request with a HttpModule as in this answer.
After reading the body of the POST in the context's BeginRequest event I would like to return as quickly as possible an "OK" response to the client.
What would be the best way to prevent further processing in IIS (7.5 integrated mode)?

I believe this one is the fastest:
Response.Clear();
Response.ClearHeaders();
Response.StatusCode = 200;
Response.StatusDescription = "OK";
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();

Call HttpResponse.End(). It will flush any pending content (your OK response) and then end the request.

Related

Kill a http post request

I am trying to handle the duplicated form posting by using the anti forgery token as answered here the problem arises when a duplicate identical form post request arrives it is successfully identified but i am unable to handle it properly. I am doing
if (ctx.Session["userform"] != null)
{
if (_antiForgToken.Equals(ctx.Session["userform"].ToString()))
{
//kill the request
response.Clear();
response.ClearContent();
response.Close();
}
}
else
ctx.Session["userform"] = _antiForgToken;
}
the question is how can i just drop the duplicated HTTP request as if it never happened...
You still need to respond to the request made by the client right and just killing the response will not help. Probably send a reponse with a status code 400.
400 Bad Request
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

403 forbidden caused by response object?

In my server side code I'm creating the following response object:
var response = HttpContext.Current.Response;
response.Clear();
response.AddHeader("Content-Type", content.Type);
response.AddHeader("Content-Length", content.Length.ToString());
response.AddHeader("Content-Disposition",
string.Format("attachment; filename={0}; size={1}", Server.UrlEncode(content.FileName), content.Length.ToString()));
response.Flush();
response.BinaryWrite(content.Image);
response.Flush();
Is it possible something in this response object is causing the 403 and if so what? If I just run a blank aspx page I don't get a 403 it is only when it goes through the above code that a 403 occurs.
The issue is unlikely to be a mime type issue (so probably not related to the content type being text/plain), though that's an issue in itself.
Chances are that permissions are not setup correctly, or that .NET is not registered on the server properly. Try running aspnet_regiis on the server again.

Delay HttpWebrequest with Threading

I use a proxy and visit some webpages with HttpWebReuqest. Sometimes a welcome message comes from the proxy and says I will be redirected to the desired page after 10 seconds.
This happens when I have already received the response. So the content inside:
HttpWebResponse urlResponse =(HttpWebResponse ) urlRequest.GetResponse();
Stream contentStream = urlResponse.GetResponseStream();
StreamReader sr = new StreamReader(contentStream, Encoding.GetEncoding("iso-8859-9"));
content = sr.ReadToEnd();
is not what I am looking for.
I tried setting allow autoredirect to true, but it didn't help, because the page is loaded without any redirect, but still waits 10 seconds.
Is there a way to fix this problem? How can I implement threading with:
HttpWebResponse urlResponse =(HttpWebResponse )urlRequest.GetResponse();
Thanks.
Either disable the 10 sec wait in your proxy server or parse the HTML output to get the redirect URL, this URL could be in HTTP meta refresh or in some JavaScript

Async Web Service calls to IIS7 with Dynamic Compression don't work

We have some ASP.NET Web Services that fail under this perfect storm of conditions:
IIS7
Dynamic Compression is turned on
Web Service call is Asynchronous
If it is IIS 6, or we turn Dynamic Compression off or call the web service synchronously, it works fine.
It fails in the call to SoapHttpClientProtocol.EndInvoke(IAsyncResult asyncResult) with an 'Unexpected end of file' error.
Using Fiddler, I see that the response from IIS 6 has a transfer-encoding of 'chunked' and no content-length. The response from IIS 7 is NOT chunked and has a content-length. The end of file error occurs 1 character past the content length.
If I intercept the message in Fiddler and change it to chunked, there is no error. The answer could be to change it to chunked in IIS 7 (which I've tried to do and failed), but I don't feel like I should have to do this: I think it should just work!
I had to open an MSDN support ticket with Microsoft for this one, but got my answer.
The answer here is a simple client-side solution. My previous WebRequest method looked like this:
protected override WebRequest GetWebRequest(Uri uri)
{
var request = base.GetWebRequest(uri);
request.Headers.Add("Accept-Encoding", "gzip");
return request;
}
The better way is this:
protected override WebRequest GetWebRequest(Uri uri)
{
var request = (HttpWebRequest) base.GetWebRequest(uri);
request.AutomaticDecompression = DecompressionMethods.GZip;
return request;
}
I'm not entirely sure why this works: The headers on the request and response are exactly the same, but the client seems to be able to manage the response it gets back.
This seems to work with both IIS6 and IIS7, even though the IIS6 response is chunked and the IIS7 one isn't. If anyone can help explain exactly why this works, it might be helpful to the community.

Why do I get "Cannot redirect after HTTP headers have been sent" when I call Response.Redirect()?

When I call Response.Redirect(someUrl) I get the following HttpException:
Cannot redirect after HTTP headers have been sent.
Why do I get this? And how can I fix this issue?
According to the MSDN documentation for Response.Redirect(string url), it will throw an HttpException when "a redirection is attempted after the HTTP headers have been sent". Since Response.Redirect(string url) uses the Http "Location" response header (http://en.wikipedia.org/wiki/HTTP_headers#Responses), calling it will cause the headers to be sent to the client. This means that if you call it a second time, or if you call it after you've caused the headers to be sent in some other way, you'll get the HttpException.
One way to guard against calling Response.Redirect() multiple times is to check the Response.IsRequestBeingRedirected property (bool) before calling it.
// Causes headers to be sent to the client (Http "Location" response header)
Response.Redirect("http://www.stackoverflow.com");
if (!Response.IsRequestBeingRedirected)
// Will not be called
Response.Redirect("http://www.google.com");
Once you send any content at all to the client, the HTTP headers have already been sent. A Response.Redirect() call works by sending special information in the headers that make the browser ask for a different URL.
Since the headers were already sent, asp.net can't do what you want (modify the headers)
You can get around this by a) either doing the Redirect before you do anything else, or b) try using Response.Buffer = true before you do anything else, to make sure that no output is sent to the client until the whole page is done executing.
A Redirect can only happen if the first line in an HTTP message is "HTTP/1.x 3xx Redirect Reason".
If you already called Response.Write() or set some headers, it'll be too late for a redirect. You can try calling Response.Headers.Clear() before the Redirect to see if that helps.
Just check if you have set the buffering option to false (by default its true). For response.redirect to work,
Buffering should be true,
you should not have sent more data using response.write which exceeds the default buffer size (in which case it will flush itself causing the headers to be sent) therefore disallowing you to redirect.
Using
return RedirectPermanent(myUrl) worked for me
You can also use below mentioned code
Response.Write("<script type='text/javascript'>"); Response.Write("window.location = '" + redirect url + "'</script>");Response.Flush();
There is one simple answer for this:
You have been output something else, like text, or anything related to output from your page before you send your header. This affect why you get that error.
Just check your code for posible output or you can put the header on top of your method so it will be send first.
If you are trying to redirect after the headers have been sent (if, for instance, you are doing an error redirect from a partially-generated page), you can send some client Javascript (location.replace or location.href, etc.) to redirect to whatever URL you want. Of course, that depends on what HTML has already been sent down.
My Issue got resolved by adding the Exception Handler to handle
"Cannot redirect after HTTP headers have been sent". this Error as shown below code
catch (System.Threading.ThreadAbortException)
{
// To Handle HTTP Exception "Cannot redirect after HTTP headers have been sent".
}
catch (Exception e)
{//Here you can put your context.response.redirect("page.aspx");}
I solved the problem using:
Response.RedirectToRoute("CultureEnabled", RouteData.Values);
instead of Response.Redirect.
Be sure that you don't use Responses' methods like Response.Flush(); before your redirecting part.
Error
Cannot redirect after HTTP headers have been sent.
System.Web.HttpException (0x80004005): Cannot redirect after HTTP headers have been sent.
Suggestion
If we use asp.net mvc and working on same controller and redirect to different Action then you do not need to write.. Response.Redirect("ActionName","ControllerName"); its better to use only return RedirectToAction("ActionName"); or return View("ViewName");
The redirect function probably works by using the 'refresh' http header (and maybe using a 30X code as well). Once the headers have been sent to the client, there is not way for the server to append that redirect command, its too late.
If you get Cannot redirect after HTTP headers have been sent then try this below code.
HttpContext.Current.Server.ClearError();
// Response.Headers.Clear();
HttpContext.Current.Response.Redirect("/Home/Login",false);
There are 2 ways to fix this:
Just add a return statement after your Response.Redirect(someUrl);
( if the method signature is not "void", you will have to return that "type", of course )
as so:
Response.Redirect("Login.aspx");
return;
Note the return allows the server to perform the redirect...without it, the server wants to continue executing the rest of your code...
Make your Response.Redirect(someUrl) the LAST executed statement in the method that is throwing the exception. Replace your Response.Redirect(someUrl) with a string VARIABLE named "someUrl", and set it to the redirect location... as follows:
//......some code
string someUrl = String.Empty
.....some logic
if (x=y)
{
// comment (original location of Response.Redirect("Login.aspx");)
someUrl = "Login.aspx";
}
......more code
// MOVE your Response.Redirect to HERE (the end of the method):
Response.Redirect(someUrl);
return;

Resources