15

I am developing a website using a local server, but I have remote dependencies. I would like to fake requests for files from remote servers. For instance, when the browser makes a request for fooCDN.com/bloatedLib.js the contents of /Users/name/Desktop/bloatedLib.js will be returned.

I use a mac and a solution that works at the system or browser level would be fine. If it works at the browser level, only a Firefox or Chrome solution will be alright. I cannot use a windows computer.

gregg
  • 5,598
  • 2
  • 21
  • 36
Daniel F
  • 251
  • 2
  • 10
  • Are you able to use a Windows computer? – geek1011 Aug 09 '15 at 13:21
  • @geek1011 No, that would not be possible – Daniel F Aug 09 '15 at 13:22
  • 6
    Not sure if I understand you correctly, but are you trying to be able to access a website even when you have no connection to the internet? and if so, access a local copy? Like a proxy server does? – LPChip Aug 09 '15 at 13:33
  • @LPChip I need external dependencies like jQuery to be loaded even when I am offline. This is someone else's repository, so I can't just make external dependencies local. If it could just load the version in the browser cache when it is offline ti would be perfect. Most of the website is in a local server. – Daniel F Aug 09 '15 at 13:35
  • You could use HTML5 "offline web apps" – Michael Aug 09 '15 at 23:35
  • @Michael I can't make that drastic modifications to the website – Daniel F Aug 10 '15 at 07:26
  • Couldn't you just not use CDNs? They violate the users privacy, and it is not really slower to put the resources on your own server. It even saves one TCP connection to do so, if you either concatenate the files or use HTTP/2.0. So it could very well get even faster than using the CDN. – Jost Aug 10 '15 at 11:32
  • @Jost it is a project that I am working on in an internship and I can't make that change. – Daniel F Aug 10 '15 at 11:34
  • How about Service Workers? It works on modern browsers and localhost, also it's simple as creating a file to handle the requests (`new Response` can create fake responses) and adding `if(location.hostname=='localhost')navigator.serviceWorker.register('path-to-worker.js');` to some existent file. – Gustavo Rodrigues Aug 10 '15 at 12:57
  • have a look at this too as it shows you how to handle when CDNs go down in code http://stackoverflow.com/questions/5257923/how-to-load-local-script-files-as-fallback-in-cases-where-cdn-are-blocked-unavai – Mauro Aug 10 '15 at 15:04
  • @DanielF "Not with that attitude" ;-) – Michael Aug 10 '15 at 16:57
  • @Michael What do you mean? – Daniel F Aug 10 '15 at 17:24
  • Related: [Proxy for a home network](http://superuser.com/questions/81055/proxy-for-a-home-network). – Arjan Aug 12 '15 at 12:50

4 Answers4

24

It sounds like you're running a local web server. Excellent.

In your Mac's filesystem, there is a file called /etc/hosts. You can redirect all requests for fooCDN.com to your local machine by adding this line in /etc/hosts:

127.0.0.1   foocdn.com www.foocdn.com

You will need root (super user) permissions to edit /etc/hosts.

The above line means that fooCDN.com will load from your own computer, where a web server is listening.

You didn't specify what web server you're running locally, though. Following the web server's documentation, you should create a virtual host that points the document root of fooCDN.com to /Users/name/Desktop/.

This is a sample configuration (I haven't tested it myself) you can try to use with Apache:

<VirtualHost 127.0.0.1:80>
    ServerName foocdn.com
    ServerAlias www.foocdn.com
    DocumentRoot /Users/name/Desktop
</VirtualHost>

Here's a sample configuration for Nginx (also untested):

server {
    listen 80;
    root /Users/name/Desktop;
    server_name foocdn.com;
}

Don't forget to restart the you web server service or reload the new configuration file.

Deltik
  • 19,353
  • 17
  • 73
  • 114
12

I hacked together this little proxy server to only download missing files. Just set up your /etc/hosts file to point sites you want to cache at 127.0.0.1 and those you want to block at 0.0.0.0

#!/bin/sh 
nc -ll -p 80 -e sh -c ' 
while read A B DUMMY 
do 
   case "$A" in 
      [Gg][Ee][Tt]) 
         FULL=$B #full path of the file
         F=${FULL##*/}
         F=${F%%\?*} #file name only
         #if we have it cat it back to browser
         [ -f "$F" ] && cat "$F" && break 
      ;; 
      [Hh][Oo][Ss][Tt]*) 
         [ -f "$F" ] && break #file already exists
         HOST=${B:0:$((${#B}-1))} #the host name
         #resolve by DNS first so we can cache it
         sed -i "s/hosts:\t\tfiles /hosts:\t\t/g" /etc/nsswitch.conf 
         wget -t 0 -q --no-dns-cache $HOST$FULL
         #got it now revert to checking host file 1st
         sed -i "s/hosts:\t\t/hosts:\t\tfiles /g" /etc/nsswitch.conf
         #cat the file because I didn't think to wget through tee
         cat "$F" 
         break 
      ;; 
   esac 
done 
'

Note that it puts all files in one directory, so it may cause version conflicts. (I did this intentionally so I wouldn't have 500 copies of jquery)

technosaurus
  • 1,072
  • 5
  • 8
  • Can you comment your code so that I can understand it better. I like this answer a lot because I don't need to install a lot of software – Daniel F Aug 10 '15 at 12:17
  • 1
    @DanielF I added some inline comments. Let me know if it makes sense, it's probably one of the hackiest hacks I've written. I only wrote it out of necessity because I kept getting browser stalls waiting for one busy resource. I should mention I was using puppy Linux when I wrote it, so some lines may need to be run sudo. – technosaurus Aug 10 '15 at 12:38
  • Note: some browsers may need an actual http header instead of just "catting" the file (though none of mine did). If you have a browser that doesn't accept/fix this bad behavior, you can use stat to get the file size and use it to printf a proper header. – technosaurus Aug 12 '15 at 10:55
  • @technosaurus: I'm trying to implement something similar, however I'm getting an error: `illegal option -- e`, can you help with this? – Anurag Peshne Sep 16 '15 at 11:25
  • @AnuragPeshne there are several varied implementations of netcat; depending on which implementation you are using, you may be able to use the `-c` parameter for running a script (same as `-e` without the `sh -c` part) – technosaurus Sep 17 '15 at 07:45
2

You could use proxy server software that supports URL rewriting to accomplish the task. Many proxy server applications support URL rewriting. E.g., the Charles Web Debugging Proxy Application for Windows, Mac OS, and Linux supports URL rewriting. You could install it on your Mac system and then configure the browsers on the system to use the proxy server.

Alternatively, Apache, which is free and open source, has mod_proxy and mod_rewrite modules.

Mitmproxy is free and will also run on a Mac OS X system.

If you need to pull items out of your browser's cache to make them available via the proxy server, you can use techniques provided at Viewing Chrome cache (the easy way). E.g., in Google Chrome you can put chrome:\\cache in the browser's address bar and then locate the relevant items in the Chrome cache and copy them elsewhere.

moonpoint
  • 5,080
  • 2
  • 19
  • 22
  • Do you know of any software other than Charles, especially free software? – Daniel F Aug 09 '15 at 14:50
  • Your answer is good, but I accepted the other answer that doesn't require non free software. – Daniel F Aug 09 '15 at 14:59
  • That's fine; Deltik's solution is a good one for your situation. I added a couple of free alternatives to Charles. – moonpoint Aug 09 '15 at 15:13
  • 1
    @DanielF Another debugging proxy is Fiddler, which [has an alpha OS X build](http://fiddler.wikidot.com/mono) and supports [file responses](http://docs.telerik.com/fiddler/KnowledgeBase/AutoResponder) and [replaying specific responses](http://docs.telerik.com/fiddler/Generate-Traffic/Tasks/ReplayAutoresponder). It's more fine-grained than redirecting the whole domain too. – Bob Aug 10 '15 at 06:01
2

Sounds like good old wwwoffle should suite your needs. It's a proxy server where you can select resources for offline usage.

MvG
  • 1,479
  • 2
  • 14
  • 26