How to rewrite a URL while keeping POST data? - apache

I'm using Apache and its proxy settings to serve a web page over HTTPS (more detail here: click).
In the previous question, I was struggling with why the POST data was disappearing between my browser and my server. Now I know that it was caused by using Apache's RewriteRule. So I tried working around that with proxies, but this resulted in the web page sending out all other requests on the main domain, instead of the sub domain it's at. For example: My main web page is at myUrl.com/sprinklers. This goes through a proxy, which goes to localhost:8091. The main HTML page loads, but ALL other calls it makes, it makes at myUrl.com/any/path/it/needs, while it should be at myUrl.com/sprinklers/any/path/it/needs.
Sadly, I'm stuck in the middle:
Using RewriteRule means that everything works, but I lose the POST data, which I need.
Using proxies means that the POST data works, but also that I get a ton of 404's, because the web page somehow now expects things to be at the root of the domain, instead of the subdomain it's at.
The trailing slash needs to be there, since without it, the same happens as when I use proxies, I get a ton of 404's for all bits and pieces of the web page.
I tried using ProxyHTMLURLMap in all shapes and forms (all found online), but none worked.
TL;DR:
I need to enable two-way traffic between myUrl.com/sprinklers/.* and localhost:port/.*, while also retaining POST data. How do I do that?

As always, ask and you shall find the answer yourself...
It turned out to be a lot simpler than I imagined. Simply telling RewriteRule to use HTTP code 307 did the trick. Apparently, this is the same as the other redirection codes, but 307 also keeps the POST data.
For those wondering how to do this in Apache:
RewriteRule ^/sprinklers$ /sprinklers/ [R=307]
That's it, fixed.

Related

While Redirecting the url through apache server Data get lost

My Question is this
I redirect the form in
Redirect /formviewer/faces/pages/view/viewform.xhtml
///formviewer/faces/pages/view/viewform.xhtml
in Apache Http Server but the form is not redirecting while doing post request from client Side.
So what is it doing?
I rather suspect that its normalising the thing you want to redirect to ///... and considering it the same.
When looking at redirects, there are three things in my list of 'go-to' tools:
curl -I http://..... and look at the response and the Location header. I use this when installing new redirects (it avoids following chained redirects and gives me a better view of what is happening at each step.
Something like Fiddler or a browsers developer tool. Frankly I'd only use this if curl wasn't doing it for me.
Enable the RewriteLog in Apache... I almost never use this, but for your case it may shed some light.
But let's take a step back: why are you wanting to redirect to a path with and extra // prepended (which as I've previously speculated, likely won't work)?

Apache 301 Redirect and preserving post data

I have implemented SEO URLs using Apache 301 redirects to a 'redirect.cfm' in the root of the website which handles all URL building and content delivering.
Post data is lost during a 301 redirect.
Unable to find a solution so far, have tried excluding post method from rewrites - worst case scenario we could use the old type URLs for post methods.
Is there something that can be done?
Thanks
Using a 307 should be exactly what you want
307 Temporary Redirect (since HTTP/1.1)
In this case, the request should be repeated with another URI; however, future requests
should still use the original URI.[2] In contrast to how 302 was historically implemented,
the request method is not allowed to be changed when reissuing the original request. For
instance, a POST request should be repeated using another POST request
- Wikipedia
Update circa 2021
The original answer here was written before 307 status code redirect worked consistently across browsers. As per Hashbrown's answer below, the 307 status code should be used.
Old Answer
POST data is discarded on redirect as a client will perform a GET request to the URL specified by the 301. Period.
The only option is to convert the POST parameters to GET parameters and tack them onto the end of the URL you're redirecting to. This cannot be done in a .htaccess file rewrite.
One option is to catch POST requests to the url to be redirected and pass it off to a page to handle the redirect. You'd need to do the transposition of the parameters in code then issue the redirect header with the parameter appended new url that way.
Update: As pointed out in the comments to this answer, if you do redirect to another URL specifying POST parameters and that URL is also accessed without paramters (or the params are variable), you should specify a link to the canonical URL for the page.
Say the POST form redirects transposed to the following GET resource:
http://www.example.com/finalpage.php?form_data_1=123&form_data_2=666
You would add this link record to the head section of the page:
<link rel="canonical" href="http://www.example.com/finalpage.php" />
This would ensure all SEO value would be given to http://www.example.com/finalpage.php and avoid possible issues with duplicate content.
Using 301 redirects for general URL rewriting is not the way to go.
This is a performance issue (especially for mobile, but also in general), since it doubles the number of requests for your page.
Think about using a URL rewriting tool like Tuckey's URLrewriteFilter or apache mod_rewrite.
What Ray said is all true, this is just an additional comment on your general approach.

should redirect to www cause a one second delay?

I am using Magento 1.6.2.0 on a shared host running Litespeed web server, and I have begun investigating ways to speed up page loads. Currently I am using Pingdom to look at requests and it appears that I am losing an entire second from the get-go when I type my URL without the www. The browser redirects to the www page, it's just that it takes so long. Is this something I can fix? I presume that I can change Magento's base-url to not include the www, but then I presume I'll have the same delay when going to the www url instead.
I took a look at the link you gave, and I indeed see an about 1 second delay before I receive a 302 redirect to the URL with www. prepended. Not entirely coincidentally, the actual page HTML also takes quite long (about 1.7 seconds) to load.
This is a fairly common issue with large web applications: to return even a simple response like a redirect, the entire application must load and run its startup code. Couple this with a not so fast shared webserver that isn't optimized for that one application, and you can get quite slow page load times. It's nothing unique to Magento; I've seen the same effect with MediaWiki myself, and I expect that it happens with other applications too.
The obvious solution is just to avoid redirects: as long as you make sure all your URLs have the right hostname, the extra delay due to wrong hostnames will not appear. Magento itself will presumably take care of this for its own URLs, but if you have any other code (or static pages) that link to your Magento URLs, make sure they use the right hostname.
You can also sign up for Google Webmaster Tools (and similar tools for other search engines) and configure your preferred domain there (it's under Site configuration → Settings) so that Google will automatically prepend www. to any links to your site it indexes.
You can (and should) also try to reduce Magento's startup time in general. This will speed up not only redirects, but all other page loads as well. I'm not familiar enough with Magento to be able to give much detailed advice on this, but the obvious first step for any massive PHP application is to make sure you're using a PHP accelerator such as APC.
Finally, the fastest way to redirect visitors to the correct hostname is to make your webserver send the redirect directly without ever invoking Magento at all. The details on how to do this depend on the server software you're using, but apparently LiteSpeed supports the same RewriteRule syntax as Apache's mod_rewrite, so you should be able to do this just by adding the following lines to your main .htaccess file:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.mmmspeciosa\.com$ [NC]
RewriteRule ^(.*)$ http://www.mmmspeciosa.com/$1 [R=301,L]
(By the way, I'm using HTTP 301 permanent redirects here instead of the HTTP 302 temporary redirects Magento seems to be using. This is not only more appropriate according to the HTTP standard, but also works better with search engines, which treat a 301 redirect as an indication to index the target URL instead of the source of the redirect. If this redirect type is not configurable in Magento, I would consider it a bug. If it is configurable, you should set it to 301.)

Umbraco - use HTTPS for some pages

I'm building a site with Umbraco, and there are a couple of pages that need to be visited over HTTPS instead of HTTP (e.g. a login page).
I've seen a couple of macros that get put on the page that needs to use HTTPS, and essentially just check the protocol used and do a Response.Redirect with the correct protocol if necessary. This seems like a terrible way of achieving what seems to be a fairly basic requirement - ideally I'd want Umbraco to render any links to these pages as <a href="https://...", not do a redirect when the user goes to a page.
With these redirecting macros, there's also the possibility of a browser displaying a warning if the user's on an HTTPS page and navigates to a HTTP one. If the links are relative, the user will be redirected from HTTPS to HTTP, and the browser may warn about this.
Is there a way to achieve this without modifying any Umbraco framework code?
There's currently no built-in way to make a few pages in Umbraco return a https url.
The only way I can think of doing this at the moment is just by making sure that you set up your links correctly.
But there's no way of stopping people from entering the insecure link. That is where the redirects come in handy though, it will make sure you don't get to a secure page insecurely.
I would recommend running the whole site in https mode. In the past, performance would have been an objection to running your full site in https mode. However with modern servers, this really shouldn't be a problem any more.

Url rewrite without redirect in ASP.NET

We have a CMS system that creates long URLs with many parameters. We would like to change the way they are presented, to make them more friendly.
Since we have many sites already built on this CMS, it's a little difficult to rewrite the CMS to create friendly urls (although it's a method we're considering, if no alternative is found), we we're looking for a method that when a user clicks on a long url, the url will change into a friendly one - in the browser - without using Response.Redirect().
In Wordpress such a method exists (I'm not sure whether it's done in code or in Apache), and I'm wondering if it could be done in ASP.NET 2.0 too.
Another thing to take into consideration is that the change between the urls has to be done by accessing the DB.
UPDATE: We're using IIS6
If you're using ii7 the easiest way to do this is to use the URL Rewrite Module According to that link you can
Define powerful rules to transform
complex URLs into simple and
consistent Web addresses
URL Rewrite allows Web administrators
to easily build powerful rules using
rewrite providers written in .NET,
regular expression pattern matching,
and wildcard mapping to examine
information in both URLs and other
HTTP headers and IIS server variables.
Rules can be written to generate URLs
that can be easier for users to
remember, simple for search engines to
index, and allow URLs to follow a
consistent and canonical host name
format. URL Rewrite further simplifies
the rule creation process with support
for content rewriting, rule templates,
rewrite maps, rule validation, and
import of existing mod_rewrite rules.
Otherwise you will have to use the techniques described by Andrew M or use Response.Redirect. In any case I'm fairly certain all of these methods result in a http 301 response. I mention this because its not clear why you don't want to do Response.Redirect. Is this a coding constraint?
Update
Since you're using IIS 6 you'll need to use another method for URL rewriting.
This Article from Scott Mitchell describes in detail how to do it.
Implementing URL Rewriting
URL rewriting can be implemented
either with ISAPI filters at the IIS
Web server level, or with either HTTP
modules or HTTP handlers at the
ASP.NET level. This article focuses on
implementing URL rewriting with
ASP.NET, so we won't be delving into
the specifics of implementing URL
rewriting with ISAPI filters. There
are, however, numerous third-party
ISAPI filters available for URL
rewriting, such as:
ISAPI Rewrite
IIS Rewrite
PageXChanger
And many others!
The article goes on to describe how to implement HTTP Modules or Handlers.
Peformance
A redirect response HTTP 301 usually only contains a small amount of data < 1K. So I would be surprised if it was noticeable.
For example the difference in the page load of these urls isn't noticible
"https://stackoverflow.com/q/4144940/119477"
"https://stackoverflow.com/questions/4144940/url-rewrite-without-redirect-in-asp-net"
(I have confirmed using ieHTTPHeaders that http 301 is what is used for the change in URL)
Page Rank
This is what google's webmaster central site has to say about 301.
If you need to change the URL of a
page as it is shown in search engine
results, we recommended that you use a
server-side 301 redirect. This is the
best way to ensure that users and
search engines are directed to the
correct page.
In response to extra comments, I think what you need to do is bite the bullet and modify the CMS to write the new links out into the pages. You've already said that you have normal URL rewriting which can translate the new URLs to old when they're incoming. If you were to also write out the new URLs in your markup then everything should simply work.
From an SEO point of view, if the pages your CMS produces have the old links, then that's what the search engines will see and index. There's nothing much you can do about that, javascript, redirect or otherwise. (although a permanent redirect would get you a little way there).
I also think that what you must have been seeing in Wordpres was probably a redirect. Without finding an example I can't be sure though. The thing to do would be to use Fiddler or another http debugger to see what happens when you follow one of these links.
For perfect SEO, once you've got the new URLs working outbound and inbound, what you'd want to do is decide that your new URLs are the definitive URLs. Make the old URLs do a redirect to the new URLs, and or use a canonical link tag back to the new URL from the old one.
I'm not certain what you're saying here, but basically a page the user is already reading contains an old, long, URL, and you'd like it to change to the new, short URL, dynamically on the client side, before the browser requests the page from the server?
The only way I think this coule be done would be to use Javascript to change the URL in response to onclick or document.ready, but it would be pointless. You'd need to know the new short url for the javascript to re-write to, and if you knew that, why not simply render that url into the link in the first place?
It sounds more like you want URL routing, as included in ASP.Net 4 and 3.5?
Standard URL rewriting modifies the incoming request object on the server, so the client browser submits the new URL, and the downstream page handlers see the old URL. I believe the routing things extend this concept to the outgoing response too, rewriting old urls in the response page into new URLs before they're sent to the client.
Scott Gu covers the subject here:
http://weblogs.asp.net/scottgu/archive/2009/10/13/url-routing-with-asp-net-4-web-forms-vs-2010-and-net-4-0-series.aspx
Scott Gu also has an older post on normal URL rewriting outlining several different ways to do it. Perhaps you could extend this concept by hooking into Application_PreSendRequestContent and manually modifying all the href values in the response stream, but I wouldn't fancy it myself.
http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx