QuotaGuard

This add-on is operated by Teachmatic Ltd

Proxy your API calls to stop sharing IP quotas

QuotaGuard

Last Updated: 18 January 2014

Table of Contents

QuotaGuard is an add-on for proxying API requests so they don’t originate from Heroku IP addresses.

Services like Google Maps geocoding will now work as if you had your own dedicated server with dedicated IP address.

QuotaGuard is accessible as an HTTP Proxy so is language and platform agnostic. There is native support across Ruby, Python, Node.js, Scala, Java and every other mainstream language.

Provisioning the add-on

QuotaGuard can be attached to a Heroku application via the CLI:

A list of all plans available can be found here.

$ heroku addons:add quotaguard:starter
-----> Adding quotaguard:starter to sharp-mountain-4005... done, v18 (free)

Once QuotaGuard has been added a QUOTAGUARD_URL setting will be available in the app configuration and will contain the full URL you should use to proxy your API requests. This can be confirmed using the heroku config:get command.

$ heroku config:get QUOTAGUARD_URL
http://user:pass@proxy.quotaguard.com:9292

After installing QuotaGuard the application should be configured to fully integrate with the add-on.

Local setup

Environment setup

After provisioning the add-on it’s necessary to locally replicate the config vars so your development environment can operate against the service. This should be used for initial testing only as usage will count against your daily limits.

Though less portable it’s also possible to set local environment variables using export QUOTAGUARD_URL=value.

Use Foreman to configure, run and manage process types specified in your app’s Procfile. Foreman reads configuration variables from an .env file. Use the following command to add theQUOTAGUARD_URL value retrieved from heroku config to .env.

$ heroku config -s | grep QUOTAGUARD_URL >> .env
$ more .env

Credentials and other sensitive configuration values should not be committed to source-control. In Git exclude the .env file with: echo .env >> .gitignore.

Using with Rails

Geocoding is the most common usage for QuotaGuard so this tutorial will focus on that use case.

To add geocoding to your Rails project we recommend the Geocoder gem.

Once you have completed the standard setup of Ruby Geocoder you can use QuotaGuard by adding the following to your geocoder initializer:

# config/initializers/geocoder.rb
Geocoder.configure(
  ...
  :http_proxy => ENV['QUOTAGUARD_URL'],
  :timeout => 5
)

All geocoding requests will now go via QuotaGuard automatically.

Using with Python/Django

There are many geocoding libraries available for Python but the most used is geopy which uses urllib2 environment variables to set a proxy service.

In your application initialization you should set the http_proxy variable to match the QUOTAGUARD_URL. If using Geopy you also need to force it to use the http version of Google’s API, not https by passing in scheme="http" to the Geocoder constructor.

# Assign QuotaGuard to your environment's http_proxy variable
import os
from geopy import geocoders
os.environ['http_proxy'] = os.environ['QUOTAGUARD_URL']
g = geocoders.GoogleV3(scheme="http")
place, (lat, lng) = g.geocode("10900 Euclid Ave in Cleveland")
print "%s: %.5f, %.5f" % (place, lat, lng)

Testing in the Python interpreter

This code will check the IP your requests originate from with and without using the QuotaGuard proxy. If the IP addresses are different then you are successfully routing requests through QuotaGuard.

import urllib2
import os
url = 'http://ip.jsontest.com/'
heroku_ip_request = urllib2.urlopen(url)
print "Heroku IP:"
heroku_ip_response = heroku_ip_request.read()
print heroku_ip_response
os.environ['http_proxy'] = os.environ['QUOTAGUARD_URL']
proxy = urllib2.ProxyHandler()
opener = urllib2.build_opener(proxy)
in_ = opener.open(url)
qg_response = in_.read()
print "QuotaGuard IP:"
print qg_response
if heroku_ip_response != qg_response:
    print "SUCCESS! The IP addresses are different so everything is working!"
else:
    print "SOMETHING WENT WRONG. The IP addresses are the same. Are you sure you have a QUOTAGUARD_URL environment variable set?"

Using with Node.js

Accessing an HTTP API with Node.js

To access an HTTP API you can use the standard HTTP library in Node.js but must ensure you correctly set the “Host” header to your target hostname, not the proxy hostname.

var http, options, proxy, url;

http = require("http");

url = require("url");

proxy = url.parse(process.env.QUOTAGUARD_URL);
target  = url.parse("http://ip.jsontest.com/");

options = {
  hostname: proxy.hostname,
  port: proxy.port || 80,
  path: target.href,
  headers: {
    "Proxy-Authorization": "Basic " + (new Buffer(proxy.auth).toString("base64")),
    "Host" : target.hostname
  }
};

http.get(options, function(res) {
  res.pipe(process.stdout);
  return console.log("status code", res.statusCode);
});

Accessing an HTTPS API with Node.js

The standard Node.js HTTPS module does not handle making requests through a proxy very well. If you need to access an HTTPS API we recommend using the Request module (npm install request). Please note accessing an HTTPS endpoint requires our Enterprise plan.

var request = require('request');

var options = {
    proxy: process.env.QUOTAGUARD_URL,
    url: 'https://api.github.com/repos/joyent/node',
    headers: {
        'User-Agent': 'node.js'
    }
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);

Monitoring & logging

Real-time and historical usage stats can be displayed on the QuotaGuard Dashboard accessible from your Heroku Dashboard.

Dashboard

The QuotaGuard dashboard allows you to view your real-time and historical usage of every API.

The dashboard can be accessed via the CLI:

$ heroku addons:open quotaguard
Opening quotaguard for sharp-mountain-4005...

or by visiting the Heroku apps web interface and selecting the application in question. Select QuotaGuard from the Add-ons menu.

Troubleshooting

Once you pass your plan limit you will receive a response including the message status: "PROXY_OVER_QUERY_LIMIT"

This will resolve itself at the end of the 24 hour period. You may also receive this message if you send excessive requests to rate-throttled services like Google Maps in a short period of time. If you see this message and believe you have not reached your limit raise a support ticket.

HTTP vs HTTPS

HTTPS access is limited to our Enterprise plan. If you are accessing Google Maps you have the choice to use the HTTP or HTTPS endpoint so upgrading is not necessary unless you want to secure all requests between your app and the Google API.

Static IP Address

If you require a static IP address we have an alternative service called QuotaGuard Static that is currently in private alpha on Heroku. Email support@teachmatic.com if you’d like an invite to the free trial.

Migrating between plans

Application owners can migrate at any time with no interruption to your service. Your new limits/features will take effect immediately.

Use the heroku addons:upgrade command to migrate to a new plan.

$ heroku addons:upgrade quotaguard:enterprise
-----> Upgrading quotaguard:enterprise to sharp-mountain-4005... done, v18 ($20/mo)
       Your plan has been updated to: quotaguard:enterprise

Removing the add-on

QuotaGuard can be removed via the CLI.

This will destroy all associated data and cannot be undone!

$ heroku addons:remove quotaguard
-----> Removing quotaguard from sharp-mountain-4005... done, v20 (free)

Support

All QuotaGuard support and runtime issues should be submitted via the Heroku Support channels. Any non-support related issues or product feedback is welcome at feedback@teachmatic.com or by visiting QuotaGuard.com.