Redirect all .jpg but allow image embed - .htaccess

I have this code in my .htacess file, and does the redirection of http://www.example.com/wp-content/wp-content/uploads/2016/10/063.jpg to www.example.com/wp-content/show-image.php?path=http://www.example.com/wp-content/wp-content/uploads/2016/10/063.jpg
Somehow it works, and it won't redirect www.example.com/wp-content/show-image.php?path=http://www.example.com/wp-content/wp-content/uploads/2016/10/063.jpg as well.
RewriteEngine On
RewriteRule ^([^\.]+)\.(jpe?g|png) http://www.example.com/wp-content/show-image.php?path=http://www.example.com/wp-content/$1.jpg [R=301,NC,L]
the problem is that it will redirect images in <img src=""/> as well. I want <img src="http://www.example.com/wp-content/wp-content/uploads/2016/10/063.jpg" /> to be able to load, not to be redirected.
any idea on how to do this?

The only way to really do this, without modifying the URL in some way, is to check the HTTP Referer. The Referer is not set for a direct request, but is set (to your domain) when a request comes from the embedded src attribute.
However, this is prone to error and is not recommended in a professional environment. The browser might be configured to not send the Referer in the request anyway or it could even be faked.
Anyway, you can implement this by inserting a conditional check. ie. Only redirect when the Referer is not set to the expected host:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://www\.example\.com
RewriteRule ^([^\.]+)\.(jpe?g|png) http://www.example.com/wp-content/show-image.php?path=http://www.example.com/wp-content/$1.jpg [R=301,NC,L]
The ! prefix negates the CondPattern.
However, that will also prevent Googlebot etc. seeing your image URLs, unless you include further exceptions. UPDATE: And it is usually recommended to allow empty Referer headers, but this will allow direct requests (but this is probably required for Google image search and the Googlebot, which does not send a Referer header when crawling) For example, you can try:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !google
RewriteCond %{HTTP_REFERER} !^http://www\.example\.com
RewriteRule ^([^.]+)\.(jpe?g|png)$ http://www.example.com/wp-content/show-image.php?path=http://www.example.com/wp-content/$1.jpg [R=301,NC,L]
(Incidentally, you don't need to escape the dot in a character class in order to match a literal dot.)
This will block other sites from linking to your images directly (ie. hotlinking).
Modify the URL:
Otherwise, you can change the URL of your embedded image in some way. eg. Append ?noredirect=1 to the end of the URL and check for this instead in your .htaccess condition:
RewriteCond %{QUERY_STRING} !^noredirect=1$

Related

Clicking on my web in google results redirects me back to google

Im helping a friend out on a website which is created using an online platform powered by plesk and theres an issue when trying to access this web through google.
Writing the domain directly in the browser works fine but when accessing it through a google search it redirects the user back to google.
What could be the issue?
this is my .htaccess file
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
#HTTP-HTTPS
RewriteCond %{HTTPS} off
RewriteRule (.*) https://srad.wtf/es_ES/$1 [R=301,L,QSA]
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by Apache
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite all other queries to the front controller.
RewriteRule ^ %{ENV:BASE}/index.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
# When mod_rewrite is not available, we instruct a temporary redirect of
# the start page to the front controller explicitly so that the website
# and the generated links can still be used.
RedirectMatch 307 ^/$ /index.php/
# RedirectTemp cannot be used instead
</IfModule>
</IfModule>
Ive removed the majority of the comments from the file to keep it clean
As stated in comments, there doesn't appear to be anything in your .htaccess file that would cause this redirect.
the redirect response ... appears to be coming from an Nginx server (possibly a front-end proxy), not Apache.
#MrWhite does that mean its something that I cant solve myself?
The Nginx server, from which the response is ultimately being served from/through (a front-end/caching proxy I suspect) is part of your server config - so you would expect to have some control over this - although "using an online platform" then maybe not?
However, the redirect(s) you are seeing may be coming from your application server/PHP (not Nginx or Apache). The problem isn't just with "Google Chrome" (as you have tagged) or even with Google SERPs. Any inbound link to the homepage is being 302 redirected back to itself (the HTTP Referer).
Not wanting to sound alarming, but this sort of redirect is quite typical of a site being hacked - as it is potentially damaging for SEO. Although since this only affects the homepage and is a 302 (temporary) redirect and you appear to have other language specific redirects in the application logic then this may just be a missconfiguration - although redirecting back to the "HTTP Referer" is quite a deliberate action!
For example, the following link to your homepage currently 302 redirects back to "this page"!
https://srad.wtf/
Workaround
Your site appears to be in two languages, as denoted by the first path segment, /en/ or /es_ES/ (default). The application logic appears to unconditionally redirect(302) to /es_ES/ if omitted (it is not deduced from the user's browser preferences or remembered for returning visitors).
You may be able to redirect to /es_ES/ early in .htaccess before the application kicks in. (By the same logic that requesting the HTTP homepage also works OK, since it is redirected to HTTPS early in .htaccess.)
Try the following, after the RewriteEngine directive:
RewriteRule ^$ https://example.com/es_ES/ [R=302,L]
Note that this is a "workaround", it doesn't fix the underlying problem.
Additionally...
#HTTP-HTTPS
RewriteCond %{HTTPS} off
RewriteRule (.*) https://srad.wtf/es_ES/$1 [R=301,L,QSA]
This HTTP to HTTPS redirect is not strictly correct, as it unconditionally prefixes the request with /es_ES/ even when a valid language code might already be present. eg. Request http://example.com/es_ES/about (HTTP) and you are redirected to https://example.com/es_ES/es_ES/about (404). etc.
The HTTP to HTTPS redirect should simply redirect to the same URL-path (resolve any other language/path issues elsewhere*1). For example, this should be written:
RewriteCond %{HTTPS} off
RewriteRule (.*) https://example.com/$1 [R=301,L]
The QSA (Query String Append) flag is not required since the query string (if any) is passed through by default, unless you create a new query string on the substitution string (the QSA flag would then be required to append the query string from the original request).
(*1 To some extent, the preceding "workaround" resolves the missing language code.)
Strictly speaking, the language should be defaulted conditionally based on the value of the Accept-Language HTTP request header - but this is best done in PHP, not .htaccess.

Redirect certain subfolders by removing the parameter question mark

I am using .htaccess to redirect certain subfolders of my domain, to remove the question mark to improve my URLs.
Currently my URLs are like this:
www.example.com/post/?sometitle
I am trying to remove the question mark, so it is the following URL:
www.example.com/post/sometitle
Currently I have the following code in my .htaccess file:
RewriteCond %{THE_REQUEST} /post/?([^\s&]+) [NC]
RewriteRule ^ /post/%1 [R=302,L,NE]
i am using php GET parameters, i am attempting for when the browser visits example.com/post/sometitle that the page that is currently example.com/post/?sometitle is displayed
In that case you need to the opposite of what you are asking in your question: you need to internally rewrite (not externally "redirect") the request from example.com/post/sometitle to example.com/post/?sometitle.
However, you must have already changed all the URLs in your application to use the new URL format (without the query string). You shouldn't be using .htaccess alone for this.
I also assume that /post is a physical directory and that you are really serving index.php in that directory (mod_dir is issuing an internal subrequest to this file). So, instead of /post/?sometitle, it's really /post/index.php?sometitle?
For example:
RewriteEngine On
# Rewrite /post/sometitle to filesystem path
RewriteRule ^post/([\w-]+)$ /post/index.php?$1 [L]
So, now when you request /post/sometitle the request is internally rewritten and handled by /post/index.php?sometitle instead.
I have assumed that "sometitle" can consist of 1 or more of the characters a-z, A-Z, 0-9, _ and -. Hence the regex [\w-]+.
If this is a new site then you can stop there. However, if you are changing an existing URL structure that has already been indexed by search engines and linked to by external third parties then you'll need to redirect the old URLs to the new. (Just to reiterate, you must have already changed the URL in your application, otherwise users will experience repeated redirects as they navigate your site.)
To implement the redirect, you can add something like the following before the above rewrite:
# Redirect any "stray" requests to the old URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ([\w-]+)
RewriteRule ^post/$ /post/%1 [R=302,NE,QSD,L]
The check against the REDIRECT_STATUS environment variable is to ensure we only redirect "direct requests" and thus avoiding a redirect loop.
(Change to 301 only when tested as OK, to avoid caching issues.)
In Summary:
RewriteEngine On
# Redirect any "stray" requests to the old URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ([\w-]+)
RewriteRule ^post/$ /post/%1 [R=302,NE,QSD,L]
# Rewrite /post/sometitle to filesystem path
RewriteRule ^post/([\w-]+)$ /post/index.php?$1 [L]
UPDATE: If you have multiple URLs ("folders") that all follow the same pattern, such as /post/<title>, /home/<title> and /build/<title> then you can modify the above to cater for all three, for example:
# Redirect any "stray" requests to the old URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ([\w-]+)
RewriteRule ^(post|home|build)/$ /$1/%1 [R=302,NE,QSD,L]
# Rewrite /post/sometitle to filesystem path
RewriteRule ^(post|home|build)/([\w-]+)$ /$1/index.php?$2 [L]
Aside: (With my Webmasters hat on...) This is not really much of an "improvement" to the URL structure. If this is an established website with many backlinks and good SE ranking then you should think twice about making this change as you could see a dip in rankings at least initially.
If only changing from query is your requirement then try with below, we are using QSD flag to discard our query string after our rule matched.
RewriteCond %{QUERY_STRING} ([^\s&]+) [NC]
RewriteRule ^ /post/%1 [R=302,L,NE,QSD]

Using mod_rewrite to mask a directory/file name in a URL

I've taken my site down for some prolonged maintenance and am using mod_rewrite to send all requests to a single page: www.mysite.com/temp/503.php
This is my .htaccess file which works fine.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/temp/503.php [NC]
RewriteRule .* /temp/503.php [R,L]
However, what I'd also like to be able to do is to hide /temp/503.php in the resulting URL from the visitor.
I know this is perhaps trivial and I'm sure fairly simple to achieve, but with my limited mod_rewrite skills I can't seem to get it to work.
Any help would be much appreciated.
Thanks.
Just get rid of the R flag in the rewrite rule, which tells the rule to redirect the request, thus changing the URL in the browser's location bar. So the rule would look like:
RewriteRule .* /temp/503.php [L]
which internally rewrites the requested URI instead of externally telling the browser that it's been moved to a new URL.

htaccess only accept traffic from specific http_referer

I'm trying to set up a htaccess file that would accomplish the following:
Only allow my website to be viewed if the viewing user is coming from a specific domain (link)
So, for instance. I have a domain called. protect.mydomain.com . I only want people coming from a link on unprotected.mydomain.com to be able to access protect.mydomain.com.
The big outstanding issue I have is that if you get to protect.mydomain.com from unprotected.mydomain.com and click on a link in the protect.mydomain.com that goes to another page under protect.mydomain.com then I get sent back to my redirect because the http_referer is protect.mydomain.com . So to combat that I put in a check to allow the referrer to be protect.mydomain.com as well. It's not working and access is allowed from everywhere. Here is my htaccess file. (All this is under https)
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} ^https://(.+\.)*mydomain\.com
RewriteCond %1 !^(protect|unprotected)\.$
RewriteRule ^.*$ https://unprotected.mydomain.com/ [R=301,L]
You are matching your referer against ^https://(.+\.)*mydomain\.com. Which means if some completely other site, say http://stealing_your_images.com/ links to something on protect.mydomain.com, the first condition will fail, thus the request is never redirected to https://unprotected.mydomain.com/. You want to approach it from the other direction, only allow certain referers to pass through, then redirect everything else:
RewriteEngine On
RewriteBase /
# allow these referers to passthrough
RewriteCond %{HTTP_REFERER} ^https://(protect|unprotected)\.mydomain\.com
RewriteRule ^ - [L]
# redirect everything else
RewriteRule ^ https://unprotected.mydomain.com/ [R,L]

How do I rewrite a URL so that the rewrite can be typed into the URL bar?

I have the following page: www.domain.com/index.php?route=information/contact and I'd like to rewrite it so that it shows up as: www.domain.com/contact, but there's more...
What's important, is that when someone types in www.domain.com/contact, it redirects them to www.domain.com/index.php?route=information/contact, which in turn, is rewritten as www.domain.com/contact.
I appreciate any help! Thanks.
Edit: To clarify
I want users to be able to enter www.domain.com/contact and be redirected to www.domain.com/index.php?route=information/contact.
However once redirected, I'd like a purely aesthetic rewrite so that www.domain.com/index.php?route=information/contact shows up as www.domain.com/contact (the same as what they typed in.)
Is this possible?
Edit: My .htaccess file currently...
Options +FollowSymlinks
# Prevent Directoy listing
Options -Indexes
# Prevent Direct Access to files
<FilesMatch "\.(tpl|ini)">
Order deny,allow
Deny from all
</FilesMatch>
# SEO URL Settings
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php?_route_=$1 [L,QSA]
RewriteCond %{QUERY_STRING} ^route=common/home$
RewriteCond %{REQUEST_METHOD} !^POST$
RewriteRule ^index\.php$ http://www.domain.com/? [R=301,L]
### Additional Settings that may need to be enabled for some servers
### Uncomment the commands by removing the # sign in front of it.
### If you get an "Internal Server Error 500" after enabling, then restore the # as this means your host
doesn't allow that.
# 1. If your cart only allows you to add one item at a time, it is possible register_globals is on. This
may work to disable it:
# php_flag register_globals off
Try these rules in your .htaccess file:
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteCond %{THE_REQUEST} ^GET\s/+index\.php [NC]
RewriteCond %{QUERY_STRING} ^route=information [NC]
RewriteRule . /warranty? [L,NC,R=301]
RewriteRule ^warranty$ /index.php?route=information/contact [L,NC]
L will make sure that user's URL in browser doesn't change and redirection happens internally.
Your question is extremely unclear, and I suspect that inexperience is to blame.
With the following rule:
RewriteRule /?(.*) index.php?route=information/$1
the location bar will read "/contact" but index.php will be invoked via an internal rewrite.
With a small modification:
RewriteRule /?(.*) index.php?route=information/$1 [R]
the location bar will read "/index.php?route=information/contact" and index.php will be invoked, after the redirect.
As always, the rule should follow the appropriate RewriteCond so as to avoid rewriting if an actual file is requested.
AFAIK, you can't make the address bar show a different address than the one that the page was loaded from. If you want the user to see www.domain.com/contact in the address bar when viewing the page, you need to make the server actually return the page content (not a redirect) when that URL is requested.
I think you might be misunderstanding URL rewriting: it's not for changing what the user sees in the address bar, it's for changing what the server sees when a request arrives from the user. If you create a rewrite rule that changes /foo to /bar, then when the user types /foo in their browser, the server will treat it as a request for /bar.
What you want, I think, is that when the user types www.domain.com/contact in their browser, the server should treat it as a request for www.domain.com/index.php?route=information/contact, but the browser should still show the pretty URL that the user typed. The way to do that is to simply rewrite /contact to /index.php?route=information/contact on the server. No redirect is needed; the user simply requests the pretty URL, and the server handles the request based on the equivalent ugly one and sends back the resulting page.

Resources