Kill a http post request - asp.net

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.

Related

If return response HTTP 204, What a correct header connection value?

If application will return response HTTP 204 .
What a correct header connection value (close or keep-alive)?
204 means there is no body to send back. You would still typically keep the connection open for subsequent requests so don’t have to close it this point.
Think of this scenario:
A web page has a “contact us” form which makes an XHR call rather than a POST. In that case you might send back a 204 to say the XHR call was successfully logged but you can keep the connection open so user can still browse the rest of the site without having to reestablish the connection.
If however your endpoint is for API calls only and no further requests will me made sending connection: close may make sense to save server resources.
The 204 (No Content) status code indicates that the server has
successfully fulfilled the request and that there is no additional
content to send in the response payload body.
So according to my understanding, as the server doesn't have anything else to send in the response, the header should be 'close'

while hitting an API Request throws 302 status code how to solve this

I'm hitting an API using http dart library while doing this I'm getting 302 status code. I know that 302 status code is for redirects, can you please say how can i enable redirects in http post method. I have used the following code:
Future<LoginModel> login(String username, String password) async {
var client = new http.Client();
final response =
await client.post(LOGIN_URL +"username=Student&password=2018" ,
headers: {'Content-type': 'application/json',
'Accept': 'application/json'});
if (response.statusCode == 200) {
return LoginModel.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
302 is a status code returned by the server to indicate that the client should retry the request using a different URL. It's a way to redirect the client to a different endpoint.
The problem is that only GET (or HEAD) requests can be retried automatically. You are using a POST.
If the 302 status code is received in response to a request other than
GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
A well-behaved API should probably not issue 30X in response to a POST, but it is. The way to get around this is to make a new http request with the redirected URL. (You might want to put it in a while loop to keep following the redirects until you get to 200, or some error, or reach a timeout/limit.)
add header with
"Accept":"application/json" . henceforth it will only return json data otherwise it will prompt to redirect with html url, default dio configuration does not have response type so you have to mention it in header.
This is because of some issue with the URL that you use. status code 302, says that the URL you are using has been moved or redirected.
May be the loginurl that you are using has certificates now and using https:// instead of http://

HTTP statuscode to retry same request

Is there an HTTP status code to instruct a client to perform the same request again?
I am facing a situation where the server has to "wait" for a lock to disappear when processing a request. But by the time the lock disappears, the requests might be close to its timeout limit. So instead, once the lock clears, I would like to instruct the client to just perform the same request again.
The best I an come up with is a HTTP 307 to the same location, but I'm worried that some browsers might not buy into this (redirect loop detection).
The correct response, when a server is unable to handle a request, is 503 Service Unavailable. When the condition is temporary, as it is in your case, you can set the Retry-After header to let the client know how long it should wait before trying again.
However, this will not force the browser to perform the request again - this is something you would need to handle yourself in javascript. For example, here is how you might perform a retrying ajax POST request in jquery:
function postData() {
$.ajax({
type: 'POST',
url: '503.php',
success: function() {
/*
Do whatever you need to do here when successful.
*/
},
statusCode: {
503: function(jqXHR) {
var retryAfter = jqXHR.getResponseHeader('Retry-After');
retryAfter = parseInt(retryAfter, 10);
if (!retryAfter) retryAfter = 5;
setTimeout(postData, retryAfter * 1000);
}
}
});
}
Note that the above code only supports a Retry-After header where the retry delay is specified in seconds. If you want to support dates that would require a little more work. In production code I would also recommend a counter of some sort to make sure you don't keep retrying forever.
As for using a 307 status code to repeat the request automatically, I don't think that is a good idea. Even if you add a retry parameter to get around the browser loop detection (which feels like a horrible hack), it's still not going to work on a POST request. From RFC2616:
If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user.
While some browsers are known to ignore this requirement, it's definitely not correct, and isn't something you would want to rely on.
And if you're not using a POST request, you almost certainly should be. Remember that a GET request should not have any side effects, and by default the response will be cached. From the description of your problem, it sounds very much like your request is likely to be doing something that has side-effects.
Use the 307 redirect, but add a retry counter:
http://path/to/server?retry=3
This will make the URL different on each retry, preventing loop detection. And the server could check for retry hitting a limit, and abort with an error when that happens, so the user doesn't wait forever.

REST http status code for content that needs authentication?

I have a web application that uses RESTful url patterns. Currently if a users tries to access a page where they need to be authenticated it just returns nothing. Is it good practice to return the HTTP status code in this case? Would I use 403 or a different one?
You should send a response with the HTTP status code.
I wouldn't send a 403 Forbidden back though as the spec specifies for this status code :
The server understood the request, but
is refusing to fulfill it.
Authorization will not help and the
request SHOULD NOT be repeated
Return a 401 Unauthorized status code instead. See this for more info on the status codes:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
The way I do this with Jersey is to send a response with the status and then include a String entity which contains a human readable message, e.g.
Response response = Response.status(Status.PRECONDITION_FAILED).entity(
new String("Incorrect " + id + " [" + id + "]")).build();
This will be displayed to the client. I throw a Jersey WebApplicationException which wraps this response.
If they don't have permissions return 401 to give them the chance to respond to the authentication challenge or 403 if you don't want them to.
Restlet 1.1 onwards return 403, while earlier versions return 401. 403 seems to be regarded as more correct, if not necessarily more helpful.
It depends. You really ought to return something, of course, just to have a decent client experience. If you'd like to give them opportunity to authenticate at that moment, you can return a 401 and the client will know to pass credentials using standard authentication. If, however, you'd prefer that they authenticate through some other mechanism (some login URL and then set a cookie or somesuch), then returning a 403 is probably the way to go.
lol... in the REST API implementation I just built I returned a 401 status code with a response body that read "goodbye". Was the first thing complained about by guy interacting with API. I still think "goodbye" said it all ; )

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