Working with API’s such as Twitter from your local machine can be a pain. A problem that comes up is Twitter does not let you set your callback URL to hit your localhost. If you are working with OAuth on your local machine and want to test the user authorization flow, you are screwed. I will explain how to circumnavigate this issue on Mac OS X with Firefox. This tutorial assumes you have set up a Twitter oauth application and specified a callback url in the application settings. At the end of the tutorial, I will present a much faster way to accomplish this task.
Important Update:
As Mark Puig mentioned in the comments below, Twitter is currently allowing you to register URL’s like “http://127.0.0.1:8000/twitter_callback” as your Twitter callback URL (pretty sure this was not allowed before) . That being said, this article is still useful for those using API’s that do not allow you to register your local host as a callback and for those who want to learn more about hacking your DNS settings. And if Twitter restricts this in the future…
Step 1 (optional): Force Firefox to expire your DNS cache.
Expiring your DNS cache will force Firefox to take a fresh look at your /etc/hosts file on each request. Otherwise you may have to wait a minute forchanges to /etc/hosts to take effect. This step isn’t necessary but it will save you time if you edit /etc/hosts often.
- Type “about:config” into your browser address bar.
- When you get to the config options, right click and go to “New” -> “Integer”. Enter “network.dnsCacheExpiration” as the preference name and “0″ as the integer value.
- Repeat for Step 2 preference name “network.dnsCacheEntries” and the integer value “0″.
The integer value “0″ for dnsCacheExpiration is the number of seconds it will take for the DNS cache to expire. As a side note, you can increase the performance of Firefox by expiring the cache much less often (set dnsCacheExpiration to “3600″ for once per hour). Obviously you do not want to do this if you are messing around with your DNS settings such as in this example.
Step 2: Trick your browser
Open up /etc/hosts and add a line like the following:
127.0.0.1 xyz.com
where xyz.com is your real host.
If your Twitter callback URL has “www” like www.xyz.com, you must use www.xyz.com instead of xyz.com. This line forces your browser to resolve xyz.com to your localhost instead of visiting the actual website. If you completed step 1 you can type http://xyz.com into your browser address bar and watch it hit your localhost. If you skipped step 1, flush your browser’s DNS cache or wait a minute for the settings to pick up.
Step 3: Add directory and port redirection
Chances are your application’s twitter callback URL is not http://xyz.com, but rather something like http://xyz.com/twitter_callback …plus the oauth_token GET parameter. If this is true, you need to create an identical path on your localhost to a callback directory and forward to wherever you want. This is best explained by example.
My callback URL is http://xyz.com/twitter_callback and Twitter appends the oauth_token to the URL so it looks something like:
http://www.xyz.com/twitter_callback?oauth_token=pyOYM5tbvK71fvt…
Since my localhost points to “/Library/WebServer/Documents”, I created a directory “/Library/WebServer/Documents/twitter_callback/” which is where my browser will go when Twitter redirects me to the callback URL. Of course my browser will be looking for an index.php file, so I created one that looks like this:
<?php if($_SERVER['HTTP_HOST'] == 'xyz.com'){ //$_SERVER['REQUEST_URI'] makes sure the oauth_token is appended header("Location: http://localhost:3000".$_SERVER['REQUEST_URI']); } ?>
This file forwards the request to port 3000 which you cannot accomplish through DNS settings. Now I have the Twitter callback URL pointing to the proper directory in my Ruby On Rails application. Again, if your Twitter callback URL is of the form www.xyz.com, you must use www.xyz.com instead of xyz.com for the HTTP_HOST check.
Update:
There is actually a much easier way to accomplish this assuming you don’t need any URL parameters passed from the service to your application upon callback. You can use bit.ly, a URL shortening service. Just shorten the url “http://localhost:3000/twitter_callback” and register the shortened URL as the callback in your Twitter app. For this method, you have to create another Twitter OAuth app for development so that the callback URL’s can differ. Using bit.ly is faster and easier than the 3-step method above, but I will leave that method posted because it allows parameters to be passed back if necessary and it teaches you a little bit about FF and OS X.
If you enjoyed this post, make sure you subscribe to my RSS feed!











Configuring Phusion Passenger on a 256MB Ubuntu Slice @Slicehost
I installed Phusion Passenger a few weeks ago to get a production environment up and running for my Rails app. It was super easy to install and felt like magic. I checked off the item on my TODO and moved on. After all it didn’t say “YOUR APP WILL BE SLOW AS HELL IF YOU DON’T READ THIS MANUAL!!!” in their documentation. Well…it was too slow…and here’s how I fixed it.
Referencing the Phusion Passenger User Guide I was able to make changes that made my app run about 10 times faster. If you want to do this in 15 minutes, read this article. If you have a few hours, read through the user guide and experiment. My hardware setup is a 256MB Ubuntu VPS at my favorite hosting company – Slicehost.
The following are global settings I added to my httpd.conf:
RailsSpawnMethod smart/smart-lv2/conservative
This can speed up the spawn time tremendously (by as much as 90%) if your app is compatible. However, some Ruby on Rails applications and libraries are not compatible with smart spawning. Set your configuration to smart spawning and if your app works, then you are all good. If not, use another spawning method.
PassengerUseGlobalQueue ON/OFF
Turning this option ON tells Passenger to add requests to a global queue when your Rails instances are busy. As soon as an instance becomes available it will grab a request from the queue. If the option is OFF, each process will maintain its own queue. Localized queues can hurt you if an instance is processing a 60-second request and Passenger adds a 1-second request to the instance’s queue. ( Imagine waiting in a 10 person non-express line at Whole Foods when all you want is a bottle of water ). Therefore, it only makes sense to turn this OFF for the 5% performance gain if all of your requests take about the same amount of time.
PassengerMaxPoolSize INTEGER
This simply says how many application instances Passenger is aloud to Spawn. The default is 6 but the user guide recommends 2 for a 256MB slice so that’s what I went with. More could consume a lot of memory and crash my server. You can use 30 if you have 2GB of RAM.
***PassengerPoolIdleTime INTEGER
This is the minimum time an application instance can be idle without Passenger shutting it down. The default value was 300 which means if my app received no traffic for 300 seconds, it could shut down all of my app instances. The result? A visitor would have to wait way too long when viewing my website. I triple starred this because I think this setting alone will greatly improve your app speed. Note there is an obvious memory trade-off because your application instances will always be running.
PassengerMaxRequests INTEGER
This provides a safety net for memory leaks. It tells Passenger to restart an application instance after it receives a certain number of requests. My app is young so I am keeping it at 1000 requests but ideally you should set this to zero meaning no maximum.
RailsAutoDetect ON/OFF
Turn off auto-detection and tell Passenger exactly which directory contains your Rails app. Do this by adding the following line to your VirtualHost configuration block:
RailsAppSpawnerIdleTime INTEGER
This is a similar setting to PassengerPoolIdleTime but applied to the ApplicationSpawner server. If the ApplicationSpawner server hasn’t done anything for the specified amount of time, it will automatically shut down. I set this at zero so it will never shut down and therefore take 10% of the time to spawn a Rails process as it would with the ApplicationSpawner server shut down. I would imagine this becomes increasingly important as your PassengerMaxPoolSize increases. Note that if your application is at it’s maximum number of instances allocated (PassengerMaxPoolSize), you may want the Spawner to shut down immediately after it spawns an app instance since the Spawner won’t be used much. Set the value to 1 if this is the case. I will probably do this in the future when my website has a more constant load ( another option is to write a script to periodically hit your Rails app and keep it at a constant load ).
PassengerStatThrottleRate INTEGER
Tell Passenger to only check for restart.txt up to once every 5 seconds instead of once per processed request.
Finally, try to turn on PassengerHighPerformance:
Adding that line to your VirtualHost configuration block will improve your performance but make your Rails app incompatible with some Apache modules. If you turn that on, restart apache, and your Rails app works fine, chances are you are in the clear. Just keep this in mind for the future in case you add more Apache modules.
If you enjoyed this post, make sure you subscribe to my RSS feed!