Tag Archives: FAQ

Wamp-Developer Server FAQ

Setting File Permissions with chmod on Windows for Apache and PHP

Oftentimes this question comes up for WAMP -

How do I chmod 777 (change) filesystem permissions for Apache and PHP to be able to read/write this file/folder on Windows?

The simple answer is you don’t, and you don’t need to. And here is why…

Apache already has all the permissions it needs, as it runs under the LocalSystem account on Windows, which has extensive read/write access to local paths. This is inherited by PHP.

For example, when you are using WordPress to upload a file (and already have the wp-content\uploads folder created), WP already has the needed permissions to be able to create a new sub-folder for the year + month in the uploads folder, and move that file in from the temporary folder. No file permission changes are needed. No php.ini edits are needed. No WP settings changes are needed.

If there is a problem with the above example -

  • The additional file permissions that have been set up afterwards are at fault (check Windows Event viewer).
  • Settings have been wrongly edited: WP upload path settings, php.ini temp folder location + upload settings, etc.
  • The Apache Service ‘Log On’ account has been switched from “LocalSystem” to something else (check Service’s Properties).
  • Or there are internal PHP errors (check the website’s HTTP and PHP error logs).

If you really really need to run chmod (read/write permissions) and chown (ownership) for some reason, there are some Windows equivalents and ports of these Linux commands that you can download, that just take the number, re-interpret it, and then use Windows native methods and commands to set the permissions…

http://gnuwin32.sourceforge.net/packages/coreutils.htm

But Apache, for the most part, already has *full* read and write permissions in the WAMP folder, so there is nothing that needs changing, unless you are trying to set lesser permissions.

You can even use a PHP script to do this, as PHP has chmod() and chown() functions…

http://php.net/manual/en/function.chmod.php

Aside form that, to set file-permissions under Windows, using Windows native ways, you can right-click any folder or file, go to Properties, Security, and set the permissions there. Or use any number of command-line utilities…

http://superuser.com/questions/106181/equivalent-of-chmod-to-change-file-permissions-in-windows

Setting MySQL Root Password

To set MySQL’s root account password -

Login to phpMyAdmin

http://127.0.0.1/phpmyadmin

Use username ‘root’ and do not enter anything for the password.

Username: root
Password:

Update Root Password

Go into phpMyAdmin’s Users Tab.

There are 3 root accounts… One for each loopback IP (IPv4′s ’127.0.0.1′ and IPv6′s ‘::1′), and one for host-name ‘localhost’.

  • root@127.0.0.1
  • root@::1
  • root@localhost

This represents the same account, the difference is the IP address and/or Host-name it’s accessed from.

Click the ‘Edit Privileges’ link that’s to the right of each account for the above.

In the ‘Change password’ Group, only fill in the Password box (and “Re-type” box), and then in that same Group click ‘Go’. Don’t change anything else.

Do this for all 3 root accounts, making sure that -
1) the password is the same in each account
2) the password only contains letters and numbers (don’t use any special characters like ‘&’ as they can later cause issues)

WampDeveloper

To let WampDeveloper know what the root password is (so WebApps Tab can install webapps) -

Once you’ve set root’s password, open file C:\WampDeveloper\WampDeveloper.xml with a simple editor like Notepad (and not a special XML editor), by right-clicking this file and selecting ‘Open With -> Notepad’, and near the bottom find these lines and fill in the password…

...
<values>
  <key name="dbUsername">root</key>
  <key name="dbPassword">fill-in-root-password-here</key>
...

Save file. Restart WampDeveloper.

If the password contains special XML characters (", &, ‘, <, >, etc), enclose that password string within “<![CDATA[string]]>“…

...
  <key name="dbPassword"><![CDATA[fill-in-root-password-here]]></key>
  ...
...

* Fancy XML editors can re-structure this file and mess it up; and since it’s ultimately just a text file, editing with Notepad is perfectly fine for this.

Blocking Download Managers and Accelerators

Some users like to use Download Managers & Accelerators in an attempt to complete file downloads faster.

These download managers/accelerators work by creating dozens to hundreds (and sometimes thousands) of independent concurrent and sequential connections, with each connection downloading a different part (byte range) of the same file.

The client sends a request with a “Range” Header specifying the part of the file it wants, and the server returns that part of the file back to the client using the HTTP 206 (“Partial Content”) Response.

This type of download abuse can easily overload your server’s connection limits and resources, and also get around any per-connection bandwidth restrictions you might have set.

Here is how to stop these Download Managers dead in their tracks by using mod_headers and mod_rewrite under Apache (or a WAMP Server such as WampDeveloper Pro).

This example will abort all partial requests for content located within URL:

http://www.example.com/files/

Unset Accept-Ranges Header

Indicate to the clients that the server will not attempt to honor Range requests (partial content requests), by changing Response Header “Accept-Ranges” from “bytes” to “none“.

<IfModule !mod_headers.c>
    LoadModule headers_module modules/mod_headers.so
</IfModule>

<Location /files/>
    <IfModule mod_headers.c>
        Header set Accept-Ranges none
    </IfModule>
</Location>

But this is only a superficial message to the client, that the download manager/accelerator software can easily ignore…

The client is still able to send “Range” requests (partial content requests), and Apache will still return the requested byte range of the file. So let’s remove that option once and for all…

Abort All Range (Partial Content) Requests

<IfModule !mod_rewrite.c>
    LoadModule rewrite_module modules/mod_rewrite.so
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine On

    # Detect URL /files/...
    RewriteCond %{REQUEST_URI} ^files/
    # Detect "Range" request header
    RewriteCond %{HTTP:Range} !^$
    # Stop and Return HTTP FORBIDDEN (403) response header
    RewriteRule .* - [F,L]
</IfModule>

* If instead of placing this inside a VirtualHost block, you place it in an .htaccess file, then “AllowOverride FileInfo” (or “AllowOverride All“) and “Options +FollowSymLinks” (or “Options All“) have to be set (in the VirtualHost) for the directory the .htaccess file is in (otherwise neither mod_rewrite, nor working with the Header data, will work).

* Don’t use “RequestHeader unset Range” as this will get around the mod_rewrite configuration while turning all partial content downloads into full size downloads.

Problems

Incomplete downloads are not resumable… A client will not be able to pause or stop a download, and later resume it.

Downloads started with download accelerators will stop at whatever % of full file size the first connection retrieves.

May also break some -

  • Clients that do streaming of video and audio
  • Clients that do reading/loading of meta-data from large files
  • e-Readers
  • Client-side bandwidth throttling

Notes on using mod_rewrite

Per-directory Rewrites

http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

For mod_rewrite, “Options FollowSymLinks” must be enabled for anything related to directories to work…

To enable the rewrite engine in this context, you need to set “RewriteEngine On” and “Options FollowSymLinks” must be enabled. If your administrator has disabled override of FollowSymLinks for a user’s directory, then you cannot use the rewrite engine. This restriction is required for security reasons.

Behavior of mod_rewrite in <Location> sections can be unpredictable…

Although rewrite rules are syntactically permitted in <Location> and <Files> sections, this should never be necessary and is unsupported.

Download Speed Limit and Throttling for Apache 2.4

Restricting download speeds is extremely easy with Apache 2.4, which now comes standard with mod_ratelimit (a very simple and straight-forward module).

Download limits can be set per:

  • Server (all websites)
  • VirtualHost (specific website)
  • URL
  • The download limit will be applied per download connection, restricting each download to a specific maximum speed.

    Load mod_ratelimit

    Add the loading of mod_ratelimit into Apache’s configuration.

    <IfVersion >= 2.4>
        LoadModule ratelimit_module modules/mod_ratelimit.so
    </IfVersion>

    Limit Download Speed

    To limit download speed per URL in a specific website, open the website’s VirtualHost files (both the HTTP and SSL VH), and insert the rate limiting configuration inside the VirtualHost block.

    This example sets the limit to 350KB/s for all downloads under URL “/downloads”.

    <IfModule mod_ratelimit.c>
        <Location /downloads>
            SetOutputFilter RATE_LIMIT
            SetEnv rate-limit 350
        </Location>
    </IfModule>

    Save file(s), and restart Apache for configuration changes to take effect.

    Test Bandwidth Throttling

    Place a large file into the /downloads location, and attempt to download this file multiple times. Check the results -

    apache-download-limits

    * This works best under IE, as Chrome will not download the same file multiple times at the same time.

    More Specific Limits

    Anything other then per connection limits require more comprehensive Apache modules such as mod_bw (docs) or mod_limitipconn (docs).

    *mod_security can also limit bandwidth, but I would not recommend it as it’s too complex to setup, use, and maintain.

    Also, according to the mod_ratelimit docs (well, the comments in the docs), you can dynamically adjust this rate limit per request, using PHP…

    Note that if you are using PHP, you can set rate-limit to 0 in httpd.conf (no limiting) and then dynamically set “rate-limit” env variable for each request in your PHP scripts, but you cannot use putenv() function for this. You must use apache_setenv() in order to make it work properly.

    This could allow you to create your own management script that tracks the use of, and allots, the download bandwidth.

Accessing Websites on a Local Network (LAN) Web Server

There are a number of different ways that local websites can be viewed from other computers (running Windows, Mac OS X, Linux) and mobile devices (iPads, iPhones, Android phones, etc), that are all connected within the same LAN (local network).

To get every LAN connected computer and mobile device to find and connect to a local website, you have these options:

Use the LAN IP of Server

Connect directly to the server via its LAN IP address, using that IP in the URL:
http://192.168.1.100/

For this to work, the LAN IP address must be assigned as one of the website’s Domain Aliases, and all redirects from Aliases to the Primary Domain Name must be turned off.

Downside – as only 1 IP address is assigned per NIC (network card), only 1 website can be accessed.

Use the LAN host-name of Server

Connect to the server via its LAN host-name (computer name), using that host-name in the URL:
http://computer-name/

For this to work, the LAN host-name must be assigned as one of the website’s Domain Aliases, and all redirects from Aliases to the Primary Domain Name must be turned off.

Downside – as only 1 host-name (computer name) is assigned per computer, only 1 website can be accessed. Also, there might be issues with some non-Windows devices, such as the iPad, which either don’t inter-operate (work with) WINS and NetBIOS or require further configuration.

Use a LAN-wide Hosts file Set Up

Connect to the server by using LAN-wide (global) Hosts files…

This is done by editing every LAN systems’ Hosts file with entries that resolve each and every website’s domain-name and aliases to the LAN IP of the server:

192.168.1.100 www.domain1.name domain1.alias1 domain1.alias2
192.168.1.100 www.domain2.name domain2.alias1 domain2.alias2
192.168.1.100 www.domain3.name domain3.alias1 domain3.alias2

This way all the other LAN systems know to which IP address to send the request to when the www.domain.name is used in the local Browser.

Downside – while this will work on Windows, Linux, and Mac OS X, this will not work on most mobile devices unless they are jail-broken / rooted (as you can’t edit their Hosts file).

Hosts file path: C:\Windows\system32\drivers\etc\hosts

Use Registered Domain Names

Connect via any website’s domain-name, as long as that domain-name is:

  • Registered (bought and paid for on Namecheap, GoDaddy, etc)
  • And has a DNS “A” record set (resolved) to either the LAN IP of the server (ex: 192.168.1.100) or the Public IP of the Router (via the domain Registrar’s DNS servers).

* It’s perfectly valid to resolve a domain-name to a local LAN IP address.

If you only have 1 registered domain name, you can use its sub-domains to represent your different local websites, by using a wild-card (*) / catch-all DNS record. This way all *.domain.name requests, regardless of what they are, will always be resolved to your LAN IP or Public IP. And once that request reaches your web server, the web server will match the sub.domain.name to the proper website. The downside of this is that every website’s domain-name must use a common base (which can make the full address long).

Use a WiFi Router that’s capable of DNS Masquerading

Some Routers are supported by 3rd-party firmware such as the OpenWRT and DD-WRT (2) projects.

Both OpenWRT and DD-WRT are able to inject custom domain-name to IP address resolves via their own internal Hosts files and/or internal bundled DNS Masquerading software such as DNSmasq.

This is probably the best option as ALL WiFi connected computers (regardless of OS) and mobile devices (everything from iPads to Android phones) will be able to connect to each and every website… Without configuring anything or doing anything to those computers and devices.

Use Own DNS Servers

Local networks (that are behind a typical wifi Router) use outside DNS servers, which “resolve” (convert) domain names to IP addresses.

Typically, the Router gets the addresses of 2-4 DNS servers from your Internet Provider (via a protocol called DHCP), and acts as the middle-man, for domain name resolve requests, between the computers and devices within the LAN, and the external DNS servers.

These external DNS servers are unable to answer and resolve requests for your “virtual” (non-registered) domain names to your locally hosted websites and their LAN IPs.

You can however, via your Router settings, switch-over these DNS servers with your own local DNS server, which will be able to resolve all “virtual” (fake) domain names, and wildcards (ex: *.local), to the server’s LAN IP address.

There are several options for DNS Servers for Windows, and Linux.

Notes

On some mobile devices, you can set them to use an HTTP Proxy server, that will then custom-resolve the domain-name to the LAN IP address. This gets around the problem of not being able to edit the device’s Hosts file without jail-breaking or rooting it. But you’ll need one Linux PC or VM running the proxy server software.

Mobile devices have to be connected to your WiFi to be able to access the server via the LAN IP address. Otherwise, you must use a registered domain-name that has a DNS record resolving the domain-name to the the Public IP of the Router (which then “port-forwards” from WAN:80 to LAN:80 of server).

LAN IPs are usually reassigned/changed after reboot or power-off of the LAN connected computers and devices and/or the Router. You’ll have to go into the Router’s configuration and settings, and make sure to manually assign the same LAN IP to the same LAN system (by assigning that LAN IP to the server’s MAC address).

When a request comes in to the web-server for a domain-name or IP address that is not assigned to any website, the first Apache Virtual Host (DefaultWebsite, localhost) gets returned.

When accessing the server directly via an IP address, you’ll only be able to access 1 website (the website that has that IP assigned as a Domain Alias)… Unless you run each website on a separate port number (8080, 8081, etc). *Some Apache configurations/setups and some PHP web-app scripts might not work correctly, as they expect regular port 80 access.

While most mobile devices OS (iOS, Android) has a Hosts file, those devices have to be jail-broken/rooted, and/or you have to go through complicated steps to modify their Hosts file.

Running your own DNS server is not recommended as it could be complicated to set up and operate, and the system it’s on has to always be On for everything else to work. If you do run your own DNS, you’ll need to set it’s LAN IP in the Router’s settings and make sure no other DNS servers are used (by the Router). DNSMasq is the recommended choice.

You can host multiple websites under 1 main domain-name/website by treating the other websites as folders: C:\WampDeveloper\Websites\main.domain.name\webroot\other.domain\

http://en.wikipedia.org/wiki/Hosts_(file)
http://www.rackspace.com/knowledge_center/article/how-do-i-modify-my-hosts-file

* Make sure to turn off any redirects of the Domain Aliases to the Primary Domain Name (*select website in WampDeveloper’s Websites Tab, click Settings; or just create a website with the LAN host-name as the Primary Domain Name, and the LAN IP as one of the Domain Aliases).

* Make sure to open (on the web-server) the Windows Firewall inbound port 80 (http) and 443 (https) connections (TCP and UDP). Windows Firewall will block these by default.

* If you are resolving domain-names to the Public IP (of the Router), make sure to update the Router’s settings to “port forward” incoming port 80 (http) and 443 (https) requests to the proper LAN IP of the web-server.

How to Uninstall WampDeveloper

Uninstalling WampDeveloper is very easy, but it is not done through Windows’ Control Panel\Programs and Features interface.

To uninstall WampDeveloper:

1. Go into WampDeveloper’s Components Tab.

2. At the very bottom, locate and click the “Uninstall WampDeveloper” link.

3. Proceed by clicking “Run Uninstallation Tasks”, then afterwards, once it’s done, click “Continue” to close it.

4. Once it’s finished and closed, delete the remaining C:\WampDeveloper\ folder to clear everything out (changes made, websites, databases, etc) and to start with a clean state before installing again.

* If Windows won’t let you delete the WampDeveloper folder, then some files inside it are still in use, just reboot/restart the system, then try deleting the folder once more.

* WampDeveloper is entirely self-contained (in it’s folder), and the uninstallation process does not delete any files – just in case you have websites and databases to keep. The task of deleting WampDeveloper’s folder is left to the user.

If you are uninstalling due to issues right after installation, you should go over this information:

Enabling IonCube Loader in WAMP

IonCube Loader enables WAMP servers such as WampDeveloper Pro to run encoded and secured PHP files. These files are usually commercial (not free) PHP scripts and apps that have been secured against reverse-engineering and piracy – such as WHMCS, vBulletin, Blesta, KBPublisher, and extensions/plugins for Joomla, WordPress, ExpressionEngine, etc.

To enable the IonCube PHP Extension in WampDeveloper Pro:

1. Open file php.ini -
C:\WampDeveloper\Config\Php\php.ini

2. Near the end of php.ini, locate the IonCube section -

[Ioncube]
;zend_extension="C:\WampDeveloper\Components\Php\ext\ioncube_loader.dll"

3. Un-comment the load line for this extension (remove the ‘;’ character from the beginning of the line) -

[Ioncube]
zend_extension="C:\WampDeveloper\Components\Php\ext\ioncube_loader.dll"

4. Save file. Restart Apache.

Afterwards, IonCube will be loaded by PHP and you can verify this via phpinfo.php.

* Generally IonCube Loader should be loaded in php.ini before any of the other extra PHP Extensions.

* The latest IonCube Loader version can be downloaded from here http://www.ioncube.com/loaders.php, but it must match Apache’s + PHP’s compiler version (“VC11″ is Apache 2.4, “VC9″ is Apache 2.2, “VC6″ is Apache 2.0) and PHP run-type (“TS” is regular PHP / mod_php, “Non-TS” is PHP-FCGI). The newer versions can replace the older versions by simply copying-over …\Php\ext\ioncube_loader.dll.

IE Displaying Pages Differently Between Website on Local Host and Website on Live Server

If your website is rendering differently in IE when – hosted from a local development system (localhost, local network, etc) and the live server (hosting account), it’s because IE is…
A) Detecting that this website is coming from the Local Intranet Zone (vs. the Internet Zone).
B) And, in-turn, rendering the website in Compatibility View (usually in IE7 mode!).

IE does this because most intranet use is done in the Corporate and Enterprise setting, which is built around an enormous amount of internal legacy code, pages, and webapps. And backward compatibility is the #1 selling point for Microsoft in this market.

Setting IE’s Compatibility Mode

To clear out the above IE behavior:

IE Settings > Tools > Compatibility View Settings

Uncheck “Display intranet sites in Compatibility View”, and also uncheck (if set) “Display all websites in Compatibility View”.

Then in IE Dev Tools (press key: F12), make sure that “Browser Mode:” and “Document Mode:” are set to the latest version.

Setting Page’s Document Mode

In the page’s template and/or source code, add “X-UA-Compatible” META Tag to force:

  • Browser’s highest document mode:
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  • Full IE8 Standards Mode:
    <meta http-equiv="X-UA-Compatible" content="IE=8">
  • IE8 Quirks Mode if no valid DOCTYPE is defined:
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">

*This Meta Tag must be placed in the <header> section before any other tags.

Or you can set this server-side by sending a “X-UA-Compatible” Response Header:

<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    BrowserMatch MSIE ie
    Header set X-UA-Compatible "IE=edge" env=ie
    Header append Vary User-Agent
  </IfModule>
</IfModule>

The above code can be placed in the website’s VirtualHost file or an .htaccess file.

*The Meta Tag takes precedence and will override the Response Header (if both are present).

Further Reading

A guide to IE Compatibility View and X-UA-Compatible
What’s the difference if meta tag X-UA-Compatible exists or not?

Microsoft

X-UA-Compatibility Meta Tag and HTTP Response Header
Controlling default rendering
Specifying legacy document modes
Defining document compatibility

Installing PEAR For WAMP

Installing and setting up PEAR is very easy.

1. Create this folder if it does not already exist:
C:\WampDeveloper\Tools\PEAR

2. Download the latest version of PEAR’s installation file and save it into the above folder:
http://pear.php.net/go-pear.phar

3. Open the command line (WampDeveloper, System Tab, button: Command Line) and within run these commands:

cd \WampDeveloper\Tools\PEAR
php go-pear.phar

4. Select to install PEAR system-wide.

Notes

WampDeveloper already includes path "C:\WampDeveloper\Tools\PEAR" in PHP’s "include_path" setting (php.ini).

PEAR Installation Guide

List Of PEAR Packages

Enabling WampDeveloper’s PHP OPcache (OPcode Cache)

To enable the PHP’s OPcode cache extension “php_opcache.dll”:

1. Open PHP’s configuration file php.ini (Reliability Tab, click button: php.ini).

2. Near the bottom of the file find section “[Zend OPcache]“, and uncomment that section (remove the ‘;’ from each line).

This setting should already be set to “1″, which enables OPcache globally for all websites (…the other option is to only enable it for specific websites via their VirtualHost files):
opcache.enable=1

* Be careful not to uncomment the plain-text lines (the real comments that explain things) or Apache might not start.

3. Open the website’s HTTP and SSL VirtualHost files (Websites Tab, select website, click buttons ‘HTTP VirtualHost’ + ‘SSL VirtualHost’). Remove, or comment out, this line:
php_admin_flag opcache.enable Off

* The above line might be inside both a “<IfModule php5_module>” (for PHP5) and “<IfModule sapi_apache2.c>” (for PHP4) blocks.

4. Save files (php.ini and VirtualHost files), and restart Apache for configuration changes to take effect. * Close and open WampDeveloper again to see changes in UI checkbox of Zend OPcache.

Notes

* There is a minor bug in the current release of Apache and/or PHP versions that makes phpMyAdmin eventually crash Apache while the PHP OPcode cache is enabled, unless you implement the fix shown here:
http://www.devside.net/wamp-server/wampdeveloper-5-known-issues-and-solutions

Edit file:
C:\WampDeveloper\Config\Apache\extra\wampd-phpmyadmin.conf

Comment out line (add ‘#’ in front):
php_admin_flag opcache.enable Off

* If you update your PHP scripts while the PHP OPcode cache is enabled, this configuration line in the “[Zend OPcache]” section will cause the previous results to remain for 60 seconds before your changes are displayed (which confuses a lot of developers when they don’t see the changes immediately):
opcache.revalidate_freq=60

* OPcache must be enabled globally (opcache.enable=1) when using PHP-FCGI, as in this case, it’s not possible to set this value via a website’s VirtualHost.