While using RedirectResult Redirect(string url) with "about:blank" it returns error that side cannot be reached and it loops infinitely inside my controller method
Can you please advice how could I handle about:blank case?
The redirect is basically done by using two declares on Headers - the url and the status.
So the very basic of redirect is this two lines of code (for the "about:blank") where for security reasons is forbitten and response with ERR_UNSAFE_REDIRECT
Response.StatusCode = 301;
Response.RedirectLocation = "about:blank";
So this can not be done using redirect and header declarations.
There is a way around - use JavaScript and run this line
<script>window.location.href = 'about:blank';</script>
Alternative consider to create an empty page and redirect to this empty existing page - and avoid the about:blank
Related
I am working with the shift4shop web api. These guys used to be known as threeDCart if that helps anyone. Its an eCommerce platform.
we are trying to apply a promotion code to an open cart.
support has verified there is no api-way to do that.
there is an url that will apply the promotion. This is often emailed to customers so they can apply the promo if they choose to.
we can paste the correct url in chrome, brave, edge, or firefox and it correctly applies the promotion.
We used private tabs for the different browser tests and the browsers were 'cold'. we launched the browser and immediately entered the URL.
We are thinking this eliminates the possibility that there are cookies that are necessary.
https://www.mywebsite.com/continue_order.asp?orderkey=CDC886A7O4Srgyn278668&ApplyPromo=40pro
However, when I try to do this in C#, i get a response that is redirected a page that says 'The cart is empty'.
The promotion is not applied
I am stumped as to how the website would respond differently to the same URL when it comes from a browser as opposed to the c# system.net library.
here is the c# code I am using
using System.Net;
//i really create this using my data, but this is the resulting url
string url = "https://www.mywebsite.com/continue_order.asp?orderkey=CDC886A7O4Srgyn278668&ApplyPromo=40pro"
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
string result = "";
using (StreamReader rdr = new StreamReader(response.GetResponseStream()))
{
result = rdr.ReadToEnd();
}
You can also call ".view_cart.asp" w the same parameters and the browsers will cause the promo to be applied.
I have tried setting the method to [ , GET, get ]
There has to be something about the request settings that are preventing this from working.
I do not know what else to try.
Any thoughts are appreciated.
As per shift4shop support, the continue_order.asp has a 302.
the browsers land on continue_order.asp and process that page.
They then continue on to view_order.asp.
The 2 pages together perform functionality that you can not get by just calling continue_order.asp
Thanks to savoy w/ shift4Shop for helping on that.
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;
I'm using an .aspx page to serve an image file from the file system according to the given parameters.
Server.Transfer(imageFilePath);
When this code runs, the image is served, but no Last-Modified HTTP Header is created.
as opposed to that same file, being called directly from the URL on the same Server.
Therefor the browser doesn't issue an If-Modified-Since and doesn't cache the response.
Is there a way to make the server create the HTTP Headers like normally does with a direct request of a file (image in that case) or do I have to manually create the headers?
When you make a transfer to the file, the server will return the same headers as it does for an .aspx file, because it's basically executed by the .NET engine.
You basically have two options:
Make a redirect to the file instead, so that the browser makes the request for it.
Set the headers you want, and use Request.BinaryWrite (or smiiliar) to send the file data back in the response.
I'll expand on #Guffa's answer and share my chosen solution.
When calling the Server.Transfer method, the .NET engine treats it like an .aspx page, so It doesn't add the appropriate HTTP Headers needed (e.g. for caching) when serving a static file.
There are three options
Using Response.Redirect, so the browser makes the appropriate request
Setting the headers needed and using Request.BinaryWrite to serve the content
Setting the headers needed and calling Server.Transfer
I choose the third option, here is my code:
try
{
DateTime fileLastModified = File.GetLastWriteTimeUtc(MapPath(fileVirtualPath));
fileLastModified = new DateTime(fileLastModified.Year, fileLastModified.Month, fileLastModified.Day, fileLastModified.Hour, fileLastModified.Minute, fileLastModified.Second);
if (Request.Headers["If-Modified-Since"] != null)
{
DateTime modifiedSince = DateTime.Parse(Request.Headers["If-Modified-Since"]);
if (modifiedSince.ToUniversalTime() >= fileLastModified)
{
Response.StatusCode = 304;
Response.StatusDescription = "Not Modified";
return;
}
}
Response.AddHeader("Last-Modified", fileLastModified.ToString("R"));
}
catch
{
Response.StatusCode = 404;
Response.StatusDescription = "Not found";
return;
}
Server.Transfer(fileVirtualPath);
I have an application that contains a button, on click of this button, it will open a browser window using a URL with querystring parameters (the url of a page that i am coding).
Is there a way to ensure that the URL is coming from my application and only from my application - and not just anyone typing the URL manually in a webbrowser?
If not, what is the best way to ensure that a specific URL is coming from a specific application - and not just manually entered in the address bar or a web browser-
Im using asp.net.
You can check if the request was made from one of the pages of your application using:
Request.UrlReferrer.Contains("mywebsite.com")
That's the simple way.
The secure way is to put a cookie on the client containing a value encrypted using a secure key or hashed using a secure salt. If the cookie is set to expire when the page is closed it should be impossible for someone to forge.
Here's an example:
On the pages that would redirect to the page you are trying to protect:
HttpCookie cookie = new HttpCookie("SecureCheck");
//don't set the cookie's expiration so it's deleted when the browser is closed
cookie.Value = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Session.SessionID, "SHA1");
Response.Cookies.Add(cookie);
On the page you are trying to protect:
//check to see if the cookie is there and it has the correct value
if (string.IsNullOrEmpty(Request.Cookies["SecureCheck"]) || System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(Session.SessionID, "SHA1") != Request.Cookies["SecureCheck"])
throw Exception("Invalid request. Please access this page only from the application.");
//if we got this far the exception was not thrown and we are safe to continue
//insert whatever code here
There's no reliable way to do this for a GET request, nor is their any reason to try for a legitimate user. What you should do instead is ensure that regardless of where the request comes from the user has the proper permissions and access rights and that the session is protected appropriately (HTTP only cookies, SSL, etc.) If the request is changing data, then it should be a POST, not a GET, and it should be accompanied by some suitable cross-site request forgery prevention techniques (such as a cookie containing a nonce that is verified against a matching nonce on the form itself).
There is no way, other than rejecting the request if it doesn't contain a previously generated random one-time token in the parameters (that would be stored in the session, for example).
While there is no 100% secure way to do this, what I am suggesting might at least take care of your basic needs.
This is what you can do .
Client: Add a HTTP header with an encoded string that is like hash (sha256) of some word.
Then make your client always do a POST request instead of GET.
Server: Check the HTTP Header for encoded string. Also make sure it is a POST request.
This is not 100% as ofcourse someone smart enough could figure out and still generate a request, but depending on your need you might find this enough or not
You can check the referer, the user agent, add an additional header to the request, always do post requests to that url. However, considering HTTP is transmitted in plain text, somebody is always able to let wireshark or fiddler run, capture the HTTP packets and recreate the requests with your measures in place.
Pass parameters from your application so that you can verify on the server side.
I suggest you use an encryption algorithm and generate random text using a password(key). Then, decrypt the param on the server side and check if it matches your expectation.
I am not very clear though. sorry about that, If had to do something like this, then, I would do something similar to mentioned above.
You can use to check the header on MVC controller like Request.Headers["Accept"]; if it is coming from your code in angularjs or jquery:
sample angularjs like this:
var url = ServiceServerPath + urlSearchService + '/SearchCustomer?input=' + $scope.strInput;
$http({
method: 'GET',
url: url,
headers: {
'Content-Type': 'application/json'
},.....
And on the MVC [HttpGet] Action method
[HttpGet]
[PreventDirectAccess]//It is my custom filters
// ---> /Index/SearchCustomer?input={input}/
public string SearchCustomer(string input)
{
try
{
var isJsonRequestOnMVC = Request.Headers["Accept"];//TODO: This will check if the request comes from MVC else comes from Browser
if (!isJsonRequestOnMVC.Contains("application/json")) return "Error Request on server!";
var serialize = new JavaScriptSerializer();
ISearch customer = new SearchCustomer();
IEnumerable<ContactInfoResult> returnSearch = customer.GetCustomerDynamic(input);
return serialize.Serialize(returnSearch);
}
catch (Exception err)
{
throw;
}
}
The goal of my program is to grab a webpage and then generate a list of Absolute links with the pages it links to.
The problem I am having is when a page redirects to another page without the program knowing, it makes all the relative links wrong.
For example:
I give my program this link: moodle.pgmb.si/moodle/course/view.php?id=1
On this page, if it finds the link href="signup.php" meaning signup.php in the current directory, it errors because there is no directory above the root.
However this error is invalid because the page's real location is:
moodle.pgmb.si/moodle/login/index.php
Meaning that "signup.php" is linking to moodle.pgmb.si/signup.php which is a valid page, not moodle.pgmb.si/moodle/course/signup.php like my program thinks.
So my question is how is my program supposed to know that the page it received is at another location?
I am doing this in C Sharp using the follownig code to get the HTML
WebRequest wrq = WebRequest.Create(address);
WebResponse wrs = wrq.GetResponse();
StreamReader strdr = new StreamReader(wrs.GetResponseStream());
string html = strdr.ReadToEnd();
strdr.Close();
wrs.Close();
You should be able to use ResponseUri method of WebResponse class. This will contain the URI of the internet resource that actually provided the response data, as opposed to the resource that was requested. You can then use this URI to build correct links.
http://msdn.microsoft.com/en-us/library/system.net.webresponse.responseuri.aspx
What I would do is first check if each link is absolute or relative by searching for an "http://" within it. If it's absolute, you're done. If it's relative, then you need to append the path to the page you're scanning in front of it.
There are a number of ways you could get the current path: you could Split() it on the slashes ("/"), then recombine all but the last one. Or you could search for the last occurrence of a slash and then take a substring of up to and including that position.
Edit: Re-reading the question, I'm not sure I am understanding. href="signup.php" is a relative link, which should go to the /signup.php. So the current behavior you mentioned is correct "moodle.pgmb.si/moodle/course/signup.php."
The problem is that, if the URL isn't a relative or absolute URL, then you have no way of knowing where it goes unless you request it. Even then, it might not actually be being served from where you think it is located. This is because it might actually be implemented as a HTTP Redirect or similar server side.
So if you want to be exhaustive, what you can do is:
Use your current technique to grab a list of all links on the page.
Attempt to request each of those pages. Then if you:
Get a 200 responce code then all is good - it's there.
Get a 404 response code you know the page does not exist
Get a 3XX response code then you know where the web server
expects that content to actually orginate form.
Your (Http)WebResponse object should have a ResponseCode property. Note that you should also handle any possible WebException errors - these too will have a WebResponse with a ResponseCode in (usually 5xx).
You can also look at the HttpWebResponse Headers property - the Location header.