Testing a Mac OS X web site using a local hostname on a mobile device

If you have a locally-hosted version of a web site for testing or development, you’ll almost certainly want to test it on a mobile device.

Let’s say the local site is hosted on Mac OS X, and you access it with a URL containing a hostname defined locally in the Mac’s “hosts” file, such as http://exampledev.com.

How can you test the site using the same URL on a mobile device (that is, a real mobile device, not an emulator)—without jailbreaking the device, using a DNS server, or paying for additional software? In this post I’ll describe a way to do exactly that.

Some background

But first a bit of background.

The quickest way to view a locally-hosted site on a mobile device is to simply use the local IP address of your computer in the “host” portion of the URL, for example http://192.168.1.11.

However some web sites don’t like being accessed with a mixture of different hostnames—perhaps because they use absolute links or some kind of host header validation. In that case, you’d need to configure the site to use that IP address on all devices, even the computer. Depending on your situation, this may not be ideal—and besides, it doesn’t look great.

What if you want to use the local hostname on all devices?

If you have access to a DNS server—perhaps there’s one in your router—then great, all devices can use that instead of a local hosts entry. But in a typical home network-type environment, running your own DNS server may not be feasible.

Another option is to modify the local hosts file on the mobile device itself. But many mobile devices don’t allow this, or else are locked down by the carrier to prevent it. For example, iOS requires you to jailbreak the device before you can view or edit its local hosts file.

What if you don’t want to jailbreak the mobile device, and you can’t edit its local hosts file? The solution I’m going to describe gives you an easy way to view a local Mac OS X website on a mobile device:

  • using the same locally-defined hostname on both the Mac and the mobile device e.g. http://exampledev.com
  • using only free software
  • without setting up or using a DNS server
  • without jailbreaking the mobile device or updating its local hosts file.

The solution

The standard solution is to run an HTTP proxy server on the computer where the site is running, and then configure the mobile device to use the proxy.

The mobile device is then able to resolve the hostname on the computer, even though it’s defined in the computer’s local hosts file, because it uses the proxy for DNS resolution.

There are already good instructions on how to do this—on Mac OS X you can use the Charles web debugging proxy, and on Windows you can use a free HTTP proxy called Fiddler.

But the Charles Mac web proxy is not free: at the time of writing a single-user license costs $50. This might might be worth it if you want to use Charles’ advanced debugging features to intercept the HTTP traffic between client and server.

But what if all you want to do is view the site on a mobile device to see how it looks and behaves? Are there any free and simple HTTP proxies available for the Mac that will do the job?

As it turns out, there are a several of options. One is to use the built-in Apache web server that comes with Mac OS X, which is normally used for “Web Sharing” (System Preferences → Sharing → Web Sharing). By modifying its configuration to enable mod_proxy, you can make it act as a proxy. While this is a perfectly reasonable solution, it’s a little fiddly to set up, so I won’t describe it here.

The solution I’ll describe uses a free and simple standalone proxy called SquidMan, which is a friendly Mac front-end to the popular Unix caching proxy Squid. SquidMan also has a really cool-looking icon depicting a bright pink octopus.

However, the overall principle can be applied using any HTTP proxy—just replace Steps 2 and 3 with the proxy of your choice.

So, here’s how you do it.

Step 1. Create a local hostname

If you haven’t already, make sure you have a local hostname for the site, for example “exampledev.com”, mapped to 127.0.0.1 (localhost) in your Mac’s local hosts file. These instructions tell you how to do that. Note that several commenters reported below that using .local as your top-level domain may not work for this purpose.

Once that’s in place, make sure you can access your site with the local hostname in a URL such as http://exampledev.com on the Mac. Make sure everything in the web site works with this URL.

Step 2. Install the proxy

The next step is to install the HTTP proxy on the machine where the local site is running, which in this case will be SquidMan.

The first time you run SquidMan, it may prompt for admin credentials so that it can install some system stuff.

OS X may also ask you Do you want the application “squid” to accept incoming network connections? In this case you need to allow incoming connections, because the incoming connections to Squid will be from other devices on your network.

» note SquidMan is a UI for controlling Squid. Squid is the actual HTTP proxy. Squid can run in the backround regardless of whether SquidMan is still running. You only use SquidMan to configure, monitor, start and stop Squid.

Step 3. Configure the proxy

The next step is to configure Squid using the SquidMan UI.

Go to SquidMan → Preferences, and set the following.

General tab

On the General tab, set the HTTP Port squid will listen on.

The default is 8080, which works fine.

SquidMan General tab

clients tab

On the Clients tab, enter the IP address (or IP address range) of the clients you want to be allowed to use the proxy, in this case your mobile devices.

If your mobile device is running iOS, you can find its own local IP address by going to Settings → Wi-Fi, then find your network, and tap its blue “>” icon.

iOS Wi-Fi Settings

Then look under IP Address.

iOS Network Settings

In this example the phone’s local IP address is 192.168.1.10.

Alternatively, you can specify a range of IP addresses, which is especially useful if you have multiple devices. Your router probably assigns IP addresses from a fixed range according to its DHCP settings. The SquidMan UI displays some useful examples—for example you can put “192.168.1.0/24” to allow the whole 192.168.1 subnet to use the proxy.

SquidMan Clients tab

template tab

Squid uses a configuration file called squid.conf.

However, you don’t need to touch this file directly. Instead, SquidMan automatically generates this file when you start Squid, based on what you put in the Template tab in the UI. (If you edit the actual squid.conf file directly then it will just get overwritten.)

The first change you need to make in the Template tab is find the following section:

# protect web apps running on the proxy host from external users
http_access deny to_localhost

… and comment out the second line with a #.

If you leave this line uncommented, Squid will block clients from accessing web content hosted on the same machine that Squid is running on, which results in an “Access Denied” message when you attempt to access the local web site. Clients will be able to use the proxy, but only to access external web sites.

SquidMan Template tab

The reason for this piece of configuration being enabled by default is that the normal usage pattern for an HTTP proxy is to use it to access content hosted elsewhere, not on the same machine as the proxy. Hence, if you want Squid to serve files hosted on the same machine as itself you need to remove the constraint by commenting out this directive.

Next, you need to tell Squid where your hosts file is, by adding the directive shown below. Thanks to Tomek Augustyn for pointing this out (for some reason it wasn’t necessary on my machine).

# hosts file
hosts_file /private/etc/hosts

I do not think the use of “/private/etc/hosts” vs. “/etc/hosts” is significant here—they actually reference the same file, since /etc is a symlink to /private/etc in OS X.

Finally click the Start Squid button to run the proxy.

SquidMan main window

Step 4. Configure the mobile device to use the proxy

The next step is to configure the mobile device to use the the proxy.

On the client device such as a phone or tablet, you’ll need to configure the device to use an HTTP proxy by specifying the proxy’s IP Address and Port.

You can determine the proxy’s IP Address and Port as follows.

  • The IP Address of the proxy is simply be the local IP address of the Mac on which you installed SquidMan, which you can find in System Preferences → Network → IP Address.

Mac OS X System Preferences > Network

In this example the Mac’s local IP address is 192.168.1.11.

  • The Port of the proxy is the port that you configured Squid to listen on, e.g. 8080.

The specific steps required to configure your mobile device to use this proxy depend on the mobile OS—the instructions below are for iOS, but other mobile OS’s should be similar.

Configuring a mobile device running iOS to use THE proxy

A mobile device running iOS can be configured to use the proxy as follows.

  • Go to Settings → Wi-Fi, find your Wi-Fi network, and tap the blue “>” icon for your network.

iOS Wi-Fi Settings

  • Scroll to the HTTP Proxy section at the bottom, tap Manual, and enter the proxy’s IP Address in the Server field and Port in the Port field.

iOS Proxy Settings

To stop using the proxy, tap on Off under HTTP Proxy. For a while, it remembers your settings so that all you have to do is tap Manual to turn it on again.

The end result

After this is done, you should be able to sync all your local site’s bookmarks between your Mac and mobile device(s), and the site should be fully operational using the same locally-defined URLs on all devices.

  • Jay

    Thanks! This is exactly what I needed.

  • http://twitter.com/ceaserrudolp ceaserrudolphkondo

    available nice meet

  • Pingback: Digital Luz is Denison Luz | Blog | Denison Luz()

  • Walter

    Excellent! Thanks for this. Perfect description.

  • http://www.rosic.net/ Marko Rosic

    I get (51) Network is unreachable error… :(

    • http://egalo.com/ James Greenwood

      Hi Marko, are you saying the site is working on the computer using a locally defined hostname, but you get that error on the mobile device using the exact same URL? Does the error look like it’s generated by Squid? Do you think the mobile device can connect to Squid, but Squid can’t connect to the web site? If so, why might that might be? I’m trying to prompt you down the path of doing diagnostic tests; the kind of investigation that can only be done by someone with access to your computer… (i.e. probably not me).

      • http://www.rosic.net/ Marko Rosic

        It seems that for some reason Squid is not getting the hosts file. Virtual host does work when accessed from computer and Squid works too with all external sites.

        • http://egalo.com/ James Greenwood

          I’m sure there are further tests you can do to find out if that’s true, and if so why it’s happening. For example, you could change the IP in the hosts file to an external web site and try the corresponding local hostname with port 80 on the mobile device – if it still doesn’t work you know Squid can’t read the hosts file; but if it works then the previous (local) IP / port really was unreachable at the network level (a firewall perhaps?)

    • http://twitter.com/blog2t Tomek/og2t/Augustyn

      Having a similar issue here, I am getting this Squid error: “The requested URL could not be retrieved” and then “Unable to determine IP address from host name …”. Seems like Squid cannot read vhosts file for some reason?

      • http://twitter.com/blog2t Tomek/og2t/Augustyn

        Have figured it out! :) You have to add the path to the hosts file (in the template).

        # hosts file
        hosts_file /private/etc/hosts

        Thanks for this awesome article James! Saved my day :)

        • http://egalo.com/ James Greenwood

          Great! And thanks for posting the solution as well. For some strange reason, that extra step wasn’t necessary on my machine. Btw I’m running Snow Leopard.

          • http://twitter.com/blog2t Tomek/og2t/Augustyn

            Maybe that’s why, I am running Lion. Could you update your article James? I am going to use it as a reference. Thanks!

          • http://egalo.com/ James Greenwood

            Updated.

  • heskethm

    Thanks a lot for this. Was set up and testing on my old android phones and ipads in minutes :)

    • http://gplus.to/alexmasters Alex Masters

      HI @heskethm:disqus , can you tell me what settings you inputted into android in order to get this working, there are a fair few more than on iOS and I don’t seem to be able to figure out what is what? Your help would be appreciated! :)

      • Mark Hesketh

        Hey alex, I think it depends on the version of Android you’re using.

        On Android 2.2.5 I found the proxy settings within the browser’s settings (Dolphin HD) rather than the WiFi settings.

        On Android 4 if you long-press on the wifi network, and select Modify Network.
        Scroll down and check ‘Show advanced options’, which should reveal Proxy settings where you can put your local webserver’s iP following the post’s instructions.

        Hope that helps!

        • http://gplus.to/alexmasters Alex Masters

          Thanks, I can’t seem to find proxy settings in Dolphin HD on my Nexus 4, the Android 4 settings under modify network provide several extra fields and I can’t determine what to use where, it just isn’t connecting up. Although it is showing up the favicon of the page I’m trying to access, strange.

          Hopefully I will have some more luck soon, thanks anyway.

  • Ravi

    Great solution and most excellently documented. Thank you! One thing to note. You cannot use .local as the domain name – it does not work! When i changed from .local to just it worked perfectly!

    • http://egalo.com/ James Greenwood

      Thanks Ravi for the comment and for the note about .local, I’ve updated the post to include that.

      • Oskar Risberg

        Thought i should add some information to this since it’s not really that simple.

        .local as tld works differently on different browsers and different OSes. I’ve tested a bunch and this is what i manage to find so far.

        Works:
        iPad2 iOS 6.1.2 – Safari
        iPad2 iOS 6.1.2 – Chrome
        iPhone 4 iOS 6.1 – Chrome
        iPhone 3GS iOS 6.0 – Chrome
        SIII Android 4.0.4 – Stock
        SIII Android 4.0.4 – Chrome

        Doesn’t work:
        iPhone 4 iOS 6.1 – Safari
        iPhone 3GS iOS 6.0 – Safari

        • http://egalo.com/ James Greenwood

          Sounds like it’s easier to just not use .local as a tld.

    • noslouch

      this was killing me! Using a different TLD instead of .local solved the issue and all I had to do was assign my server’s IP to the http proxy in my iPhone’s wifi settings. No Squidman or any software besides apache required.

      • nicooprat

        Weird : it seems to work without Squidman on my MBP which has MAMP Pro installed and running. But on my iMac which has only the “native” Apache running, it doesn’t work unless I run and configure Squidman. Is MAMP playing the role of the proxy itself ?

        • noslouch

          No idea, but I know that MAMP can be a factor in these kinds of things.

    • mickyhulse

      Wow, suprisingly, “.local” doesn’t work. I spent an hour trying to get this to work. Finally, I setup my vhost to use “.foo” (as a test) and it worked! Thanks!

  • nicooprat

    Works like a charm ! Many thanks.

  • http://aaronpollock.co.uk/ Aaron Pollock

    Thanks for posting – this is fantastic.

  • Giacomo Triggiano

    THANK YOU!
    This solved a big problem

  • ceege

    Total life saver. Thanks a ton!

  • imouto

    oh my god, THANK YOU! Nothing from StackOverflow was working for me, but your solution worked for the most part. For some bizarre reason I can only view my local sites in the default Android browser and not Opera Mini. But that’s really a minor quibble. Thank you SO MUCH!

  • ashour

    Thank you for pointing out the hosts bit! I’ve been using SquidMan for months to test Win/IE on virtual machines and it was hit or miss whether my *.dev local addresses would work. The hosts file directive seems to have done the trick. Article bookmarked. Thanks again!

  • Colin Murphy

    Thank you for the excellent tutorial.

  • vinhkhoa

    This is a very well written tutorial and it solves my problem perfectly! Thanks a lot for this. You just saved me hours of searching and configuring (and frustration)!

  • Pablo Enrici

    Thank you very much for such a comprehensive explanation. This is just what I needed!

  • http://www.focal55.com Joe Ybarra

    I wanted to allow my PC to access my MBP’s locally hosted websites. Thanks to this article it got me 90% there. Only thing missing was getting Windows 7 configured. In order to do that, I got to my LAN settings (Control Panel -> Internet Options -> Connections -> LAN settings). From that dialog window I left “Automatic detect settings” checked, checked off “Use a proxy server for your LAN…” and added my MBP IP address and the 8080 in the port field. Everything was good to go after that. Thanks again for the article egalo!

  • Marijn D.

    Fantastic tutorial. It might be over 2 years old, but still works, also on my Mountain Lion.

  • HunterJones

    Thanks for the great article! I’m… almost there… but not quite. :( I’m afraid I’m going to go insane because of some strange errors.

    Setting: OS10.9.4, MAMP Pro 3.0.5, SquidMan 3.5.1 –

    Problem: Squid is mashing together several iterations of the destination URL when attempting to resolve it. I can’t find anything online about the issue. My error is “ERROR: The requested URL could not be retrieved”, and when I look at the URL itself it bizarre. An actual example:

    http://192.168.14.112http/192.168.14.112/mytestsite.com

    (Note the missing “/” and “:” are not a typo, nor is run-on. Crazy. Also note: in this example I’m using my IP instead because I’m struggling to get this thing to work correctly.)

    Suggestions?

    Baffled. Going nuts. Thanks!

  • seanom

    Thank you for the article :) worked great and got me remote debugging on all the devices

  • Kino10

    This works except when I need to go to https files on my computer. Is there something I need to do for that?

  • Natasha Pierre-Louis

    Thank you!

  • Andrei Petre

    thanks, missed adding the clients and got access denied! :)

  • dotred

    Thanks now it works thanks to you!

  • RichieLoco

    This is awesome! Just what I needed! Many thanks

  • akkdio

    I recently worked this out for a tradeshow network so we would not have to pay the internet fee for our application demo… The discussion is on SuperUser http://superuser.com/questions/883016/how-to-setup-a-private-captive-network-using-wi-fi-at-a-tradeshow-for-in-booth-a

  • jzatt

    Thank you for this! Got my Varying Vagrant Vagrants .dev adresses to work easily! Found this guide from https://github.com/Varying-Vagrant-Vagrants/VVV/issues/263 which got me thinking that it’d be really hard to setup, but this was easy as pie! :)

  • Dennis

    What if you connect your iPhone via USB and share your internet connection (WiFi or LAN) on the macbook via USB shouldn’t you be able to access the macbook’s web server via it’s ip address?

  • John

    Hi,

    I’ve got the latest squidman software: v3.6 running on Yosemite, but still got problems accessing my localhost website from my current machine.

    I’ve succeeded a few months ago on my other macbook on Snow Leopard, but that doesn’t work either anymore.

    I’m already spending two freaking nights to look for an solution. But googling doesn’t get me there either.

    I’ve read the squidman documentation and even everystep on this page.

    Even though, this is the error i still get:

    The requested URL could not be retrieved

    The following error was encountered while trying to retrieve the URL: /

    Invalid URL

    Some aspect of the requested URL is incorrect.

    Some possible problems are:

    Missing or incorrect access protocol (should be “http://” or similar)

    Missing hostname

    Illegal double-escape in the URL-Path

    Illegal character in hostname; underscores are not allowed.

    Your cache administrator is webmaster.

    Help me please!

  • Alex McCabe

    This works with iOS Chrome but for the life of me I can’t figure out why it doesn’t with iOS Safari. Any insights?

    • Tramtrist

      I had the same problem. I got it working in both browsers in iOS 8.4. In chrome, it works using http://mywebsite.local. In safari I had to use http://mywebsite without the .local. I set up the host file to redirect both domains, and set up virtual hosts for both.

      • Alex McCabe

        I couldn’t even get this to work. Safari just hates me.

  • rhythmania

    Mac OS X 10.10 + iOS 8.3, works fine.

    Thanx! And yes – it not works with .local domains. Be carefully.

  • https://github.com/ranelpadon Ranel Padon

    Very good article. Thank you.

  • Neetu Morwani

    This is really wonderful and is exactly what I needed. Thank you for the wonderful write up.:)

  • Ferran

    Thanks mate!

  • http://www.tatenda.info/ Tatenda

    Nice and succinct. Thanks!

  • http://malinky.media Craig Ramsay

    Thanks for this! Really well written and explained.

  • Ori Dahan

    I think I got it to work but when I access my site on the iPhone (local.testdomain.com) I get a blank page.
    On my mac it works without any problem. Anyone know how can I fix this?

  • ray

    Thank you so much, this tutorial has helped me set up my dev environment !

  • Mark Langdon

    Thank you. This worked perfectly.