Tampilkan postingan dengan label Nginx Web Server. Tampilkan semua postingan
Tampilkan postingan dengan label Nginx Web Server. Tampilkan semua postingan

Minggu, 29 Mei 2011

Test Whether a Server Variable is Empty in Popular Web Servers

Q: How to test whether a variable is empty in server configurations of popular web servers such as Apache and Nginx?

Problem
It is AMAZING how unfriendly server configuration syntax can be. Even tasks as small as testing whether a value is empty can be confusing. Since I've personally used Apache and Nginx for a long time allow me to unravel the mysteries of how to evaluate whether a servervariable (e.g. document root, query string, etc.) is empty in server's configuration file.

Solution for Apache
In your httpd.conf or .htaccess simply use ="" to evaluate whether an Apache server variable is empty. Use !="" to test whether an Apache server variable is NOT empty. Here's an example:

RewriteEngine on
...
RewriteCond %{DOCUMENT_ROOT}/cache%{REQUEST_URI} -f
RewriteCond %{QUERY_STRING} =""
RewriteRule (.+)$ /cache/$1 [L]
...

This block of rules basically checks whether %{DOCUMENT_ROOT}/cache%{REQUEST_URI} exists as a file and whether the HTTP request has no URL parameters. If both are true rewrite current request to /cache/{current request uri}.

Common Apache Server Variables: By the way the following is some comments that tell you how common server variables such as %{DOCUMENT_ROOT}, %{REQUEST_URI} and %{REQUEST_FILENAME} work as they are often confusing as hell:

#
# Suppose your website is http://www.mensfashionforless.com/
# and document root is set to /usr/repository/trunk (via DocumentRoot directive in httpd.conf).
#
# Now someone issues a request for
# http://www.mensfashionforless.com/2010/10/g-by-guess-grey-low-boot-cut-jeans.html
# then the following is a list of common Apache server variables and their values:
#
# %{DOCUMENT_ROOT} = /usr/repository/trunk
# %{REQUEST_URI} = /2010/10/g-by-guess-grey-low-boot-cut-jeans.html
# %{REQUEST_FILENAME} = /usr/repository/trunk/2010/10/g-by-guess-grey-low-boot-cut-jeans.html
#

Questions? Let me know!

Solution for Nginx
Nginx is a popular web server for its speed and efficiency. Simply use ='' to check whether an Nginx server variable is empty. use !='' to check whether an Nginx server variable is not empty. Here's an example:
server {
listen 80;
server_name www.mensfashionforless.com;
rewrite_log on;
...
location / {
# test whether $document_root/cache$request_uri exists
# in the file system
if (-f $document_root/cache$request_uri) {
set $test P;
}
# test whether there's no URL argument to this request
# = '' tests whether the value is empty!
if ($args = ''){
set $test "${test}C";
}
# if both of the above tests are true, do the rewrite
if ($test = PC){
rewrite ^/(.+)$ /cache/$1 last;
break;
}
...
}
...
}
This block of code checks whether $document_root/cache$request_uri exists as a file in the file system AND whether there is no URL parameter to this HTTP request. If both are true rewrite current request to /cache/{current request uri}. Refer to the post on How do I test multiple conditions in Nginx server configuration? if you are confused by the syntax of testing multiple conditions.

If you have any questions please let me know and I will do my best to help you!

In Nginx Rewrite How To Test Multiple "if" Conditions

Q: How the HECK do I test multiple conditions in "if" statement in Nginx server configuration file?

Problem
It it AMAZING that Nginx server configuration does NOT support multiple conditions natively, meaning no such thing as the following:

if ($request_method = POST && -f $request_filename) {
...
}

In fact it does NOT even support nested conditions, meaning no such syntax as the following:
if ($request_method = POST) {
if (-f $request_filename) {
...
}
}
Why?? I am just as confused as you are. The fact that common conditionals like AND and OR are NOT supported is a serious inconvenience to webmasters especially those who are converting from Apache to Nginx. Below we'll see how to get around the issue of Nginx not supporting multiple conditions in "if" block.

Solution
When there's a will there's a way. You can use a hack by setting a variable in each tested-true condition and when the variable reflects that both conditions are true, do what you need to do. Here's an example:
server {
listen 80;
server_name www.mensfashionforless.com;
rewrite_log on;
...
location / {
# test whether $document_root/cache$request_uri exists
# in the file system
if (-f $document_root/cache$request_uri) {
set $test P;
}
# test whether there's no URL argument to this request
# = '' tests whether the value is empty!
# for more info refer to how to test whether a server variable is empty
if ($args = ''){
set $test "${test}C";
}
# if both of the above tests are true, do the rewrite
if ($test = PC){
rewrite ^/(.+)$ /cache/$1 last;
break;
}
...
}
...
}

Incidentally if you are confused by the test-empty-variable syntax refer to how to test whether a server variable is empty. You need to pay extra attention to Nginx's syntax! For example there MUST be a space between if and ( according to the syntax. The following will fail:
...
if($test = PC){
rewrite ^/(.+)$ /cache/$1 last;
break;
}
...
Nginx's server configuration syntax is very unforgiving. So make sure you check the correctness of syntax before you restart Nginx server. The way to do is it use Nginx's command line tool with "-t" option. Assume it's installed at /usr/sbin/nginx you run the following command:

/usr/sbin/nginx -t -c {location to nginx configuration file or no -c to check the default location}
If you see the following then it means your syntax is correct:

$ /usr/sbin/nginx -t
2011/05/29 11:43:04 [info] 29803#0: the configuration file /etc/nginx/nginx.conf syntax is ok
2011/05/29 11:43:04 [info] 29803#0: the configuration file /etc/nginx/nginx.conf was tested successfully
$

If your nginx config has syntax errors you'll see something like the following:

$ /usr/sbin/nginx -t
2011/05/29 11:52:08 [emerg] 30258#0: unknown directive "abc" in /etc/nginx/nginx.conf:2
2011/05/29 11:52:08 [emerg] 30258#0: the configuration file /etc/nginx/nginx.conf test failed
$

Simply correct the errors and run the command again until you see the success message. By the way this command will check your nginx configuration RECURSIVELY! Suppose your nginx.conf contains such statements as the following:

include /etc/nginx/sites-enabled/*;
Now you run "nginx -t" to check syntax, and it'll check syntax of every configuration file located in /etc/nginx/sites-enabled/!

If you have any questions please let me know and I will do my best to help you!

Minggu, 17 April 2011

Fix 403 Error When You Go To Your Website's Web or Document Root

Q: How do you fix 403 error when you go to your website's homepage?

For example suppose your website is http://www.mensfashionforless.com/ but when you go there you see something like the following if your web server is Nginx:

403 Forbidden



nginx/0.6.32


And you see the following if your web server is Apache:

Forbidden

You don't have permission to access /
on this server.


SOLUTION
And you wonder WHY?? The answer is easy. You need to configure your web server to do two things:

1. Allow access to the document root.
2. Specify what file or script to run when document root is accessed.


If you are using Apache and the web root is C:\repository\trunk-php, then the following configuration is an example of allowing access to your document root (placed in httpd.conf):

<directory "C:\repository\trunk-php">
...
Allow from all
...
</Directory>

<IfModule dir_module>
DirectoryIndex index.php
</IfModule>


You'll have to go through Apache's tutorial to find exactly how the configuration works, but the above configuration basically says everyone is allowed to access C:\repository\trunk-php via whatever reachable name. For example if your website can be reached by 127.0.0.1, 192.168.0.33, www.mensfashionforless.com this configuration makes your site accessible by all of them. When you do go to www.mensfashionforless.com you'll see C:\repository\trunk-php\index.php as the 2nd part of the configuration suggests.

If you are using Nginx the configuration may look something like this:

server {
listen 80;
server_name www.mensfashionforless.com;
...
location / {
root /home/repository/trunk-php/;
index index.php
allow all;
}
}


This configuration means when you go to www.mensfashionforless.com you'll see /home/repository/trunk-php/index.php served and 'allow all' means it's accessible from all reachable names.

Error Reflected In The Log
By the way you can also see the 403 error reflected in your log. In nginx log you'd see:

2011/03/08 14:40:59 [error] 7659#0: *1 directory index of "/home/repository/trunk-php/" is forbidden, client: 61.218.81.34, server: www.mensfashionforless.com, request: "GET / HTTP/1.1", host: "www.mensfashionforless.com"

In Aache log you'd see:

[Tue Mar 08 23:17:25 2011] [error] [client 127.0.0.1] Directory index forbidden by Options directive: C:/repository/trunk-php/

Questions? Let me know!

Kamis, 17 Maret 2011

How Do You 301 Redirect a Naked Domain To a Subdomain such as www

QUESTION
How do you 301 redirect a naked domain to some sub domain, most commonly www, so that when someone goes to yourDomain.com they'll be 301 redirected to www.yourDomain.com?

ANSWER
For those who don't understand what 301 redirect is here's a quick answer. When your webpage has been moved to a new place you usually want to set your web server to tell whoever wanting to access your old webpage that it's been moved to a new place permanently. This behavior is realized with a 301 redirect. If the client is a search engine they'll know your web page has been moved permanently.

There are at least 2 ways to 301 redirect a naked domain to a subdomain:

1: In your IP host setting add an 'A record' with host @ and configure your web server accordingly.

2: Have your domain name registry do that for you.


Below we'll look at each method in more detail and also look at the pros and cons of each.

1. In your web host setting add an 'A record' with Host set to @ that points to your machine's IP and configure your web server accordingly.
In your web host setting add an 'A record' with Host set to @ that points to your machine's IP.

If you use GoDaddy.com here's a screen shot of that setting:

GoDaddy DNS Manager A Host Setting For Naked Domain

Once you finish the setting you may need to wait for up to 1 hour for the setting to take effect. Then configure your web server to recognize the naked domain and 301 redirect it to any subdomain you want such as www. This depends on the capabilities of your web server but it should have this feature. For example if you use Nginx and your domain is mensfashionforless.com then here's what you put in your web server's configuration file:

server {
listen 80;
server_name mensfashionforless.com;
rewrite ^/(.*) http://www.mensfashionforless.com/$1 permanent;
}


This rule simply means that the web server listens on port 80 and it responds to domain name 'mensfashionforless.com' by 301 redirecting it to 'www.mensfashionforless.com' (what 'permanent' means).

In fact, this rule exhibits a great benefit that this way offers: You have total control over how the redirect happens. In this case you'll be able to redirect http://mensfashionforless.com/some-page.html to http://www.mensfashionforless.com/some-page.html. Again you have total control.

2. Have your domain name registry do that for you.
Have your domain name registry (e.g. GoDaddy) do that for you (read http://www.printfection.com/help/article.php?articleid=41 if you use GoDaddy). Basically you'll be able to pick 'Forward Domain' option to forward your naked domain, or non-www domain, to any domain you'd like via 301 redirect. Typically you'd forward your naked domain to your www domain but you can actually forward it to any domain you want.

This depends on the abilities of the registry you registered your domain with but they usually have this functionality.

This way is very limited because you might not be able to forward your old path to your new path. For example you might want to redirect http://mensfashionforless.com/some-page.html to http://www.mensfashionforless.com/some-page.html but whether you can do this totally depends on your web host. In addition your web host, although unlikely, can alter their functionality any time they want. You are basically at their mercy.

Questions? Shoot me an email.
 
support by: infomediaku.com