NotionCommotion Posted November 29, 2014 Share Posted November 29, 2014 I would like to better understand relative and absolute paths when rewriting URLs. My virtual host configuration is shown below.I wish the server to see something like: https://example.com?page=page1&controller=controller1&data1=123&data2=321 Given the rewrites as shown in my virtual host, what would be the proper URL in the browser? One of these (note the ? and &), or something different? https://example.com/page1/controller1?data1=123&data2=321 https://example.com/page1/controller1&data1=123&data2=321 Next, if I enter one of the URLs, how do relative paths to images, etc work? Would the browser think it is in the root directory, or in /page1/controller1? I had problems with relative paths, and changed to absolute paths, and it fixed the problem, but I wish to better understand what is happening. On a side note, I would appreciate any critique of my virtual host configuration. My goal is for all requests to example.com to redirect to https://example.com, for only https://example.com (no subdomain) to redirect to https://www.example.com, and do the rewriting of page and controller. Thank you # Note that if a virtual ServerName is not found (i.e. IP 192.168.1.200), Apache defaults to first virtual host. # Note that if ServerName is set to one of the virtual host ServerName's in the Second Section, it doesn't work (why?) # Handle just example.com to http <VirtualHost *:80> ServerName example.com ServerAlias *.example.com Redirect / https://www.example.com/ </VirtualHost> # Handle just example.com without subdomains <VirtualHost *:443> ServerName example.com # ServerAlias example.com SSLEngine on SSLCipherSuite SSLv3:TLSv1:+HIGH:!SSLv2:!MD5:!MEDIUM:!LOW:!EXP:!ADH:!eNULL:!aNULL SSLCertificateKeyFile /etc/pki/tls/private/example_key.pem SSLCertificateFile /etc/pki/tls/certs/example_startssl.crt SSLCertificateChainFile /etc/pki/tls/certs/sub.class1.server.ca.pem Redirect / https://www.example.com/ </VirtualHost> <VirtualHost *:443> ServerName example.com ServerAlias *.example.com DocumentRoot /var/www/example/html SSLEngine on SSLCipherSuite SSLv3:TLSv1:+HIGH:!SSLv2:!MD5:!MEDIUM:!LOW:!EXP:!ADH:!eNULL:!aNULL SSLCertificateKeyFile /etc/pki/tls/private/example_key.pem SSLCertificateFile /etc/pki/tls/certs/example_startssl.crt SSLCertificateChainFile /etc/pki/tls/certs/sub.class1.server.ca.pem <Directory "/var/www/example/html"> allow from all Options +Indexes <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / # Are these lines necessary, or should I create a virtual host for http on port 80 instead? RewriteCond %{HTTPS} !=on RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [NE,R,L] ## If the request is for a valid directory, file, or link, don't do anything RewriteCond %{REQUEST_FILENAME} -d [OR] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -l RewriteRule ^ - [L] #remove the trailing slash RewriteRule (.+)/$ $1 # If you add this first rule to support views, be sure to remove the QSA flag from the second rule (maybe not required since the first rule has the L flag) #replace mypage/mycontroller with index.php?page=mypage&controller=mycontroller RewriteRule ^([^/]+)/([^/]+)/?$ index.php?page=$1&controller=$2 [L,QSA] #replace mypage with index.php?page=mypage RewriteRule ^([^/]+)/?$ index.php?page=$1 [L,QSA] </IfModule> </Directory> </VirtualHost> Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/ Share on other sites More sharing options...
QuickOldCar Posted November 30, 2014 Share Posted November 30, 2014 I'll ramble on about a few things. These may be useful to you http://httpd.apache.org/docs/trunk/urlmapping.html http://www.askapache.com/htaccess/mod_rewrite-variables-cheatsheet.html When you do your rewrite in htacces exclude for if is a file or directory You must do this before every rewrite rule you need it for not a file RewriteCond %{SCRIPT_FILENAME} !-f not a directory RewriteCond %{SCRIPT_FILENAME} !-d The order you write your rewrite rules will matter a lot. apache absolute versus relative URL-path A DocumentRoot-relative path to the resource to be served. Note that mod_rewrite tries to guess whether you have specified a file-system path or a URL-path by checking to see if the first segment of the path exists at the root of the file-system. For example, if you specify a Substitution string of /www/file.html, then this will be treated as a URL-path unless a directory named www exists at the root or your file-system (or, in the case of using rewrites in a .htaccess file, relative to your document root), in which case it will be treated as a file-system path. If you wish other URL-mapping directives (such as Alias) to be applied to the resulting URL-path, use the [PT] flag as described below. Absolute URL If an absolute URL is specified, mod_rewrite checks to see whether the hostname matches the current host. If it does, the scheme and hostname are stripped out and the resulting path is treated as a URL-path. Otherwise, an external redirect is performed for the given URL. To force an external redirect back to the current host, see the [R] flag below. lets talk relative, absolute and local urls A path is a slash separated list of directory names followed by either a directory name or a file name. A directory is the same as a system folder. network-path reference: If you need to include something on multiple scheme/protocols like both http:// and https:// <script src="//mysite.com/script.js"></script> if you’re viewing the file local, it’ll try to request with file:// relative paths: hash tag # (by itself directs to same page, if a fragment is added usually an anchor tag on the same page......but sites have been using them to navigate entire sites or scripts with them over the years) no identifier (just a directory or file) will append own host same directory / root directory ./ up one directory ../ up two directories ../../ up three directories ../../../ on and on for up directories absolute paths: any url (more correctly called uri) that includes the protocol and host with optional others following it just a few examples, is way too many to list every possible type. http://subdomain.domain.tld.sld/directory/file.ext?query=value#fragment http://subdomain.domain.tld/ http://subdomain.domain.tld.sld/folder/script.php http://domain.tld/script.php local paths: sometimes linked when are outside of the www directory C:\folder\ C:\folder\file C:/folder/file.ext \\folder\file If you include the same scripts with the same relative paths above or deeper in folders some are going to break. The absolute paths will always be the location you specify. You could do some discovery using $_SERVER variables Providing your configuration is correct <VirtualHost *> ServerName mysite.com UseCanonicalName on</VirtualHost> defined in server config $_SERVER['SERVER_NAME'] mysite.com obtained from the HTTP request header $_SERVER['HTTP_HOST'] mysite.com if you used this on a server not using port 80 would also show the port, SERVER_NAME would not $_SERVER['DOCUMENT_ROOT'] /var/www/ , C:/wamp/www $_SERVER['SCRIPT_FILENAME'] /index.php same path whether it is used in the main file or in an included file host and script $current_url = filter_var("http://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'], FILTER_SANITIZE_STRING); include the query if exists if (!empty($_SERVER['QUERY_STRING'])) { $query_string = filter_var($_SERVER['QUERY_STRING'], FILTER_SANITIZE_STRING); $current_url .= "?" . $query_string;} onto magic constants you can do something like this to include files include_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . ‘database.class.php); $_SERVER['SCRIPT_FILENAME'] versus __FILE__ SCRIPT_FILENAME returns the same path whether it is used in the main file or an included file __FILE__ returns the path of included file if used inside an included file also the path of the main file if was included in that To sum it up, you have to figure out which methods best suit your needs and plan it out. Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/#findComment-1498045 Share on other sites More sharing options...
NotionCommotion Posted November 30, 2014 Author Share Posted November 30, 2014 I'll ramble on about a few things. Wow, you're not kidding! Thank you. When you do your rewrite in htacces exclude for if is a file or directory You must do this before every rewrite rule you need it for not a file RewriteCond %{SCRIPT_FILENAME} !-f not a directory RewriteCond %{SCRIPT_FILENAME} !-d Do this before every rewrite rule? I either misunderstand, or I don't think so. It is only required once. If you need to include something on multiple scheme/protocols like both http:// and https:// <script src="//mysite.com/script.js"></script> Thanks, I did not know that. So, I could use <script src="//someOneElesesSite.com/script.js"></script>, it it will use the same protocol as which the browser is viewing it? Nice! Why, however, wouldn't one just use <script src="/script.js"></script> if it was the currently viewed site? UseCanonicalName on Never used before. I will check it out. $current_url = filter_var("http://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'], FILTER_SANITIZE_STRING); You know I've never used filter_var(). Thanks! Looks like it will greatly simplify my scripts. While your post was very helpful, I think it missing the actual main topic of my question. Let's say I enter https://example.com/page1/controller1 into the browser, but directories /page1 is not a directory in the root directory (/var/www/html), but instead, the request is rewritten to https://example.com/index.php?page=page1&controller=controller1 where index.php is located in the root directory. If within index.php, I include the following tag, <img alt="#" src="someImage.png">, will it expect the image to be located in /var/www/html or /var/www/html/page1/controller1? What is the proper way to add extra GET variables URI https://example.com/page1/controller1 where page1 and controller1 will be rewritten by mod_rewrite as GET variables to index.php? Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/#findComment-1498091 Share on other sites More sharing options...
Ch0cu3r Posted November 30, 2014 Share Posted November 30, 2014 (edited) If within index.php, I include the following tag, <img alt="#" src="someImage.png">, will it expect the image to be located in /var/www/html or /var/www/html/page1/controller1? If you use relative urls path in your HTML it will be added onto the current url. So if your url is https://example.com/page1/controller1 (no / at the end) it will attempt to load the image from https://example.com/page1/ if the url did end with a / then it attempt to load the image from https://example.com/page1/controller1/ Personally I always use absolute url paths in my HTML by starting them with a /. Ie /images/myimage.png will always load the image from http://site.com/images/myimage.png no matter what the current url is. What is the proper way to add extra GET variables URI https://example.com/page1/controller1 where page1 and controller1 will be rewritten by mod_rewrite as GET variables to index.php? As you normally would by adding by adding them after the ? in the url, eg https://example.com/page1/controller1?var=1&var2=foo. Note in order for these additional parameters to reach index.php you will need to apply the QSA (Query String Append) flag to your RewriteRule Edited November 30, 2014 by Ch0cu3r Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/#findComment-1498110 Share on other sites More sharing options...
QuickOldCar Posted December 1, 2014 Share Posted December 1, 2014 That's the default unless you add a different rewrite rule flag that's what it does. The reason I mentioned about the order of the rules. If for some reason you want to rename a directory or file then you would want it before this rule below You have RewriteCond %{REQUEST_FILENAME} -d [OR]RewriteCond %{REQUEST_FILENAME} -f [OR]RewriteCond %{REQUEST_FILENAME} -lRewriteRule ^ - [L] The [L] flag causes mod_rewrite to stop processing the rule set. In most contexts, this means that if the rule matches, no further rules will be processed My meaning was you may want that for just specific rewrite rules Consider the case when using the S flag The flag is used to skip rules that you don't want to run. # Is the request for a non-existent file?RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-d# If so, skip these two RewriteRulesRewriteRule .? - [s=2] RewriteRule (.*\.gif) images.php?$1RewriteRule (.*\.html) docs.php?$1 Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/#findComment-1498145 Share on other sites More sharing options...
QuickOldCar Posted December 1, 2014 Share Posted December 1, 2014 A tool for testing your htaccess rules online http://htaccess.madewithlove.be/ Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/#findComment-1498147 Share on other sites More sharing options...
NotionCommotion Posted December 1, 2014 Author Share Posted December 1, 2014 (edited) As you normally would by adding by adding them after the ? in the url, eg https://example.com/page1/controller1?var=1&var2=foo. Note in order for these additional parameters to reach index.php you will need to apply the QSA (Query String Append) flag to your RewriteRule Reason I wasn't sure is that https://example.com/page1/controller1 is rewritten to https://example.com?page=page1&controller=controller1, so it would seem https://example.com/page1/controller1?var=1&var2=foo would be rewritten to https://example.com?page=page1&controller=controller1?var=1&var2=foo (two question marks) PS. When posting messages on this forum, how do you prevent the URLs from being displayed as links? Edited December 1, 2014 by NotionCommotion Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/#findComment-1498171 Share on other sites More sharing options...
Ch0cu3r Posted December 1, 2014 Share Posted December 1, 2014 (edited) The QSA flag will merge the two query strings. The rewritten url will become https://example.com/?page=page1&controller=controller1&var=1&var2=foo If you did not apply the QSA flag the var=1&var2=foo query string will be ignored PS. When posting messages on this forum, how do you prevent the URLs from being displayed as links? Wrap it in nobbc tags or click the Special Tags button and select no parse Edited December 1, 2014 by Ch0cu3r Quote Link to comment https://forums.phpfreaks.com/topic/292789-paths-when-rewriting-urls/#findComment-1498173 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.