I have a website using MODx Revolution (2.2.10-pl, advanced install), let's call it www.example.com, which I want to be accessible with both http and https.
to achieve this, I tweaked the site_url context setting to be [[++url_scheme]]www.example.com/. Links created using [[~id]] seem to be alright, however, sometimes, the generated links are really weird. My interpretation is that the code to create links programmatically doesn't work with my settings, but I don't know why, or how else I would go about enabling both http and https.
Question first, examples below: How should I set the site_url or any other site/context setting so that links on my site work with both http and https? Optionally, is the behavior I see a bug, or expected behavior given Revolution's tag evaluation semantics?
Misbehavior examples:
When I click on "View" in the manager for a resource with the alias example, the address that is opened is
https://www.example.com/xyz/[[++url_scheme]]www.example.com/example/
where xyz is my manager URL. The expected URL is of course
https://www.example.com/example/
Another case where this happens is for failed logins; my login call looks like this (minus irrelevant parts):
[[!Login? &redirectToOnFailedAuth=`[[++unauthorized_page]]`]]
The unauthorized_page's expected full URL is
https://www.example.com/special/401
but the URL which is opened for a failed login as username is
https://www.example.com/[[++url_scheme]]www.example.com/[[++url_scheme]]www.example.com/special/401?u=username
The second example is the same for http, except for the scheme, of course; I haven't logged into the manager with http.
EDIT
.htaccess at the webroot:
RewriteEngine On
RewriteBase /
# redirect all requests to /en/favicon.ico to /favicon.ico
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(en)/favicon.ico$ favicon.ico [L,QSA]
#RewriteRule ^(en|nl|de)/favicon.ico$ favicon.ico [L,QSA]
# redirect all requests to /en/assets* /assets*
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(en)/assets(.*)$ assets$2 [L,QSA]
#RewriteRule ^(en|nl|de)/assets(.*)$ assets$2 [L,QSA]
# redirect all other requests to /en/*
# to index.php and set the cultureKey parameter
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]
#RewriteRule ^(en|nl|de)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]
.htaccess in the manager's directory:
RewriteEngine On
RewriteBase /
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/xyz/$1
The problem is with $modx->makeUrl(). For example, for the
[[!Login? &redirectToOnFailedAuth=`[[++unauthorized_page]]`]]
call, in core/components/login/controllers/web/Login.php:
public function checkForRedirectOnFailedAuth(modProcessorResponse $response) {
$redirectToOnFailedAuth = $this->getProperty('redirectToOnFailedAuth',false,'isset');
if ($redirectToOnFailedAuth && $redirectToOnFailedAuth != $this->modx->resource->get('id')) {
$p = array(
'u' => $this->dictionary->get('username'),
);
$message = $response->getMessage();
if (!empty($message)) $params['m'] = $message;
$url = $this->modx->makeUrl($redirectToOnFailedAuth,'',$p,'full');
$this->modx->sendRedirect($url);
}
}
the last two lines do a redirect to a URL generated with makeUrl, which will be something like [[++url_scheme]]www.example.com/etc (note: I'm not 100% sure here, as I can't easily look at the raw URL. The conclusions still hold, though). If the URL is simply shown on the page, this is no problem, because MODx will parse the tag before inserting it into the html output. However, as the URL is used directly for the redirect, no such replacement takes place, and the browser interprets it as a relative URL, resulting in target URLs such as https://www.example.com/[[++url_scheme]]www.example.com/etc.
So much for the problem. To avoid this, site_url must be a literal value without any tags in it. As a workaround, I now use the following snippet as the first thing in my template:
$modx->config['site_url'] = $modx->config['url_scheme'] . substr($modx->config['site_url'], strlen('[[++url_scheme]]'));
return '';
together with a [[++site_url]] of
[[++url_scheme]]www.example.com/
Note that some parts of MODx don't seem to notice this update, which is why it's important to still use [[++url_scheme]] in your site_url. As far as I can tell right now, the parts that don't see the update, stuff like [[~id]], work properly with url_scheme.
EDIT this does of course only fix the "View" buttons in the manager if you tweak the manager templates accordingly.
WARNING this is of course very hacky, and not yet tested very well. The fact that some features do not see the overwritten value means that you're introducing an inconsistency into your website, which may lead to subtle errors! If a more clean solution comes up, go for it!
Related
I have tried for many days to solve my need. Try to find in google and read at the stackoverflow, but I stil unable to get my answer.
I need to get the subdomain value including the value behind it.
for example:
subdomain_name.domain.com -> will execute domain.com/user.php?subdomain_value=subdomain_name
subdomain_name.domain.com/product_1.html --> will open page domain.com/user.php?page=1&subdomain_value=subdomain_name
I have tried to use code below:
RewriteCond %{HTTP_HOST} ^((?!www\.)[^.]+)\.domain\.com$
RewriteCond %{REQUEST_URI} !^/user\.php$ [NC]
RewriteRule ^(.*)$ /user.php?subdomain_value=%1
RewriteRule ^product_([0-9]+).html$ /user.php?process=list_produk&page=$1&subdomain=%1
But it failed. When try to open subdomain_name.domain.com/product_1.html, it will keep opening the content of subdomain_name.domain.com
If I removed the code:
RewriteRule ^(.*)$ /user.php?subdomain_value=%1
Then, subdomain_name.domain.com/product_1.html will open the correct page, but the address subdomain_name.domain.com fail to open the correct page.
so, How can I make all of the .htaccess code work fine? I have think very hard and try all possibilities, including added [L], [NC,L], [L,QSA], but all of them failed.
Please help.
Thanks.
I'm going crazy here! I'm trying to learn Laravel and pretty URLs just don't work.
I have enabled mod_rewrite from my apache config file, I have set AllowOverride to All in my user config file and I have the following in my .htaccess file in public folder of Laravel installation:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [L]
I enter http://localhost/~user/lara/public/index.php/users it works, but with http://localhost/~user/lara/public/users I get 404 Not Found error
The requested URL /Users/user/Sites/lara/public/index.php/users was not found on this server.
You can see that the redirection works fine, as public/users have turned into public/index.php/users but it says not found, even though when I manually enter public/index.php/users it show me the output.
I have read all the related questions on SO, none of the worked for me!
This is most likely caused by the fact that you are changing the document root during a request. From the looks of your URL (with the ~user segment) you are using mod_userdir or something similar, and what these types of plugins do it allow you to map a given URL prefix to a document root that is not the normal one for the server.
As such, you sometimes run into issues like this where the right .htaccess file is found, but its rewritten URL is against the original document root rather than the modified one and so your index.php file cannot be found (maybe, to be honest I don't really know, this is all conjecture). This is also why going directly to index.php/users works - the problem isn't the setup per se, but the mixing of rewrite rules and the change of the document root.
As such, the fix is to use a RewriteBase line, ad the following to the .htccess file:
RewriteBase /~user/lara/public/
ok, so I've tried many things I've found on SO and elsewhere, but I just can't get it to work, always receiving a 404 error code.
I'd like to enter this url:
memorizeit.com/pics/220.0.8251.20120905002352.7982368227/Jameson+tested+the+MemorizeIt%21+Android+app%3A+With+Facebook+%26+Twitter.+Getting+grass+stains.
and have it invisibly convert to:
memorizeit.com/pics/index.php?pic=220.0.8251.20120905002352.7982368227&title=Jameson+tested+the+MemorizeIt%21+Android+app%3A+With+Facebook+%26+Twitter
The index.php page is looking for:
$pic = ($_GET["pic"]);
$title = ($_GET["title"]);
In my .htaccess file in the /pics directory I've got the following:
RewriteEngine on
Header set Cache-Control "max-age=2592000"
RewriteRule ^pics/([^\/]*)/([^\/]*)/([^\/]*)$ /pics/index.php?pic=$1&title=$2&extra=$3 [L,QSA]
RewriteRule ^pics/(.+)/(.+)$ /pics/index.php?pic=$1&title=$2 [L,QSA]
RewriteRule ^pics/([^\/]*)$ /pics/index.php?pic=$1 [L,QSA]
I've tried it without the QSA, I've tried it with either .+ (anything) and [^/]* (anything except /) I left both in so you can see how I've put them there (I think!). I do plan on making the $1 allowed to only include numbers and periods, but I'd just like to get it to work being wide open first.
I can't figure out why it isn't working. In my base url .htaccess file I have:
RewriteCond %{SERVER_PORT} ^80$
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
And it always redirects to https so I know the .htaccess files are being read. I don't know what else to try. Any thoughts would be greatly appreciated. Thanks!
Turns out that because pics/ is a real directory the rewrite was trying harder to get there than to just go ahead and rewrite it. So I changed the pics/ to p/ in the matching statement and moved the rules to the base .htaccess file and it works as expected.
Wow that took a long painful time... Hope it saves someone else some time.
I've come across a problem which i cant seem to figure out, i use the jQuery address plugin to store history and enable deep linking, and a typical url after a click would look like this:
http://mysite.com/#!/page
Problem here is i need rid of the last / so i need it to look like this:
http://mysite.com/#!page
I'm using plugin version 1.2 - the latest is 1.4. When i use 1.4 my hashbang #! disappears..
Anyone know why? even so, the updated version produces the same problem.
Reasons to fix this are i use 301 redirects to 'Pretty URL's' if an ?_escaped_fragment_= is requested. So this:
http://mysite.com/data/#!page1
would become:
http://mysite.com/data/page1
currently it does this: mysite.com/data//page1
here is the .htaccess rewrite:
<IfModule mod_rewrite.c>
RewriteEngine on
# Rewrite current-style URLs of the form 'index.php?url=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
</IfModule>
and here is some relevant PHP i use on page load:
if ($fragment = $_GET['_escaped_fragment_']) {
// OPTION 1: if Google is reqesting an '_escaped_fragment_=' page, then redirect to a clean URL
header("Location: $base/$fragment", 1, 301);
exit;
}
Any help on how to make this situation better is appreciated.. I don't want 'use the HTML5 History API' as ive explored this option already.
This line of code can help!
$.address.strict(false);
I want to redirect all requests to a certain path on my server (/app) to a subdirectory at /app/app_site. Following rewrite rules do the job for requests like 'http://localhost/app/somepage.htm':
RewriteCond %{REQUEST_URI} !^/app/app_site.*$
RewriteCond %{REQUEST_URI} !^/app_site.*$
RewriteRule ^/app(.*) /app/app_site$1 [L,PT]
This results in the correct page, while preserving the URL. Also, 'http://localhost/app/' will fetch the index page at /app/app_site/index.html, while preserving the URL 'http://localhost/app/'.
However, when I enter 'http://localhost/app', following things happen:
the correct page is fetched, at /app/app_site/index.html
yet, the URL is redirected to 'http://localhost/app/app_site/'
I'm nearly there, but would like to preserve the URL in all cases (also those without trailing slash). Anyone have a clue how to do this? Thanks!
This is the expected behaviour with DirectorySlash enabled, because you've rewritten to a directory that lacks a trailing slash, and mod_dir performs this cleanup after you've rewritten the URL with mod_rewrite.
The easiest solution is to rewrite the URL so that it always at least matches the slash-terminated directory path, like so:
RewriteCond %{REQUEST_URI} !^/app/app_site.*$
RewriteCond %{REQUEST_URI} !^/app_site.*$
RewriteRule ^/app/?(.*)$ /app/app_site/$1 [L,PT]
This prevents mod_dir from having to add the trailing slash, and therefore avoids the external redirection to /app/app_site/ you're experiencing now.