Giter Site home page Giter Site logo

rack-throttle's Introduction

DEPRECATED We suggest using rack-attack instead

https://github.com/rack/rack-attack Accomplishes the same goal as rack-throttle, but has more active maintenance, usage, and maturity. Please think about using rack-attack over rack-throttle.

rack-throttle will still continue to exist to support legacy ruby applications (<2.3), but will not be getting new features added as it exists strictly to support existing apps.

HTTP Request Rate Limiter for Rack Applications

This is Rack middleware that provides logic for rate-limiting incoming HTTP requests to Rack applications. You can use Rack::Throttle with any Ruby web framework based on Rack, including with Ruby on Rails and with Sinatra.

Features

  • Throttles a Rack application by enforcing a minimum time interval between subsequent HTTP requests from a particular client, as well as by defining a maximum number of allowed HTTP requests per a given time period (per minute, hourly, or daily).
  • Compatible with any Rack application and any Rack-based framework.
  • Stores rate-limiting counters in any key/value store implementation that responds to #[]/#[]= (like Ruby's hashes) or to #get/#set (like memcached or Redis).
  • Compatible with the gdbm binding included in Ruby's standard library.
  • Compatible with the memcached, memcache-client, memcache and redis gems.
  • Compatible with Heroku's memcached add-on (currently available as a free beta service).

Examples

Adding throttling to a Rails application

# config/application.rb
require 'rack/throttle'

class Application < Rails::Application
  config.middleware.use Rack::Throttle::Interval
end

Adding throttling to a Sinatra application

#!/usr/bin/env ruby -rubygems
require 'sinatra'
require 'rack/throttle'

use Rack::Throttle::Interval

get('/hello') { "Hello, world!\n" }

Adding throttling to a Rackup application

#!/usr/bin/env rackup
require 'rack/throttle'

use Rack::Throttle::Interval

run lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, world!\n"] }

Enforcing a minimum 3-second interval between requests

use Rack::Throttle::Interval, :min => 3.0

Allowing a maximum of 1 request per second

use Rack::Throttle::Second,   :max => 1

Allowing a maximum of 60 requests per minute

use Rack::Throttle::Minute,   :max => 60

Allowing a maximum of 100 requests per hour

use Rack::Throttle::Hourly,   :max => 100

Allowing a maximum of 1,000 requests per day

use Rack::Throttle::Daily,    :max => 1000

Combining various throttling constraints into one overall policy

use Rack::Throttle::Daily,    :max => 1000  # requests
use Rack::Throttle::Hourly,   :max => 100   # requests
use Rack::Throttle::Minute,   :max => 60    # requests
use Rack::Throttle::Second,   :max => 1     # requests
use Rack::Throttle::Interval, :min => 3.0   # seconds

Storing the rate-limiting counters in a GDBM database

require 'gdbm'

use Rack::Throttle::Interval, :cache => GDBM.new('tmp/throttle.db')

Storing the rate-limiting counters on a Memcached server

require 'memcached'

use Rack::Throttle::Interval, :cache => Memcached.new, :key_prefix => :throttle

Storing the rate-limiting counters on a Redis server

require 'redis'

use Rack::Throttle::Interval, :cache => Redis.new, :key_prefix => :throttle

Throttling Strategies

Rack::Throttle supports four built-in throttling strategies:

  • Rack::Throttle::Interval: Throttles the application by enforcing a minimum interval (by default, 1 second) between subsequent HTTP requests.
  • Rack::Throttle::Hourly: Throttles the application by defining a maximum number of allowed HTTP requests per hour (by default, 3,600 requests per 60 minutes, which works out to an average of 1 request per second).
  • Rack::Throttle::Daily: Throttles the application by defining a maximum number of allowed HTTP requests per day (by default, 86,400 requests per 24 hours, which works out to an average of 1 request per second).
  • Rack::Throttle::Minute: Throttles the application by defining a maximum number of allowed HTTP requests per minute (by default, 60 requests per 1 minute, which works out to an average of 1 request per second).
  • Rack::Throttle::Second: Throttles the application by defining a maximum number of allowed HTTP requests per second (by default, 1 request per second).
  • Rack::Throttle::Rules: Throttles the application by defining different rules of allowed HTTP request per time_window based on the request method and the request paths, or use a default.

You can fully customize the implementation details of any of these strategies by simply subclassing one of the aforementioned default implementations. And, of course, should your application-specific requirements be significantly more complex than what we've provided for, you can also define entirely new kinds of throttling strategies by subclassing the Rack::Throttle::Limiter base class directly.

Example

Customize the max_per_second to be different depending on the request's method.

class Rack::Throttle::RequestMethod < Rack::Throttle::Second

  def max_per_second(request = nil)
    return (options[:max_per_second] || options[:max] || 1) unless request
    if request.request_method == "POST"
      4
    else
      10
    end
  end
  alias_method :max_per_window, :max_per_second

end

Passing the correct options for Rules strategy.

rules = [
  { method: "POST", limit: 5 },
  { method: "GET", limit: 10 },
  { method: "GET", path: "/users/.*/profile", limit: 3 },
  { method: "GET", path: "/users/.*/reset_password", limit: 1 },
  { method: "GET", path: "/external/callback", whitelisted: true }
]
ip_whitelist = [
  "1.2.3.4",
  "5.6.7.8"
]
default = 10


use Rack::Throttle::Rules, rules: rules, ip_whitelist: ip_whitelist, default: default

This configuration would allow a maximum of 3 profile requests per second (default), i 1 reset password requests per second, 5 POST and 10 GET requests per second (always also based on the IPaddress). Additionally it would whitelist the external callback and add a ip-whitelisting for the given ips.

Rules are checked in this order:

  • ip whitelist
  • rules with paths,
  • rules with methods only,
  • default.

It is possible to set the time window for this strategy to: :second (default), :minute, :hour or :day, to change the check interval to these windows.

use Rack::Throttle::Rules, rules: rules, time_window: :minute

HTTP Client Identification

The rate-limiting counters stored and maintained by Rack::Throttle are keyed to unique HTTP clients.

By default, HTTP clients are uniquely identified by their IP address as returned by Rack::Request#ip. If you wish to instead use a more granular, application-specific identifier such as a session key or a user account name, you need only subclass a throttling strategy implementation and override the #client_identifier method.

HTTP Response Codes and Headers

403 Forbidden (Rate Limit Exceeded)

When a client exceeds their rate limit, Rack::Throttle by default returns a "403 Forbidden" response with an associated "Rate Limit Exceeded" message in the response body.

An HTTP 403 response means that the server understood the request, but is refusing to respond to it and an accompanying message will explain why. This indicates an error on the client's part in exceeding the rate limits outlined in the acceptable use policy for the site, service, or API.

503 Service Unavailable (Rate Limit Exceeded)

However, there exists a widespread practice of instead returning a "503 Service Unavailable" response when a client exceeds the set rate limits. This is technically dubious because it indicates an error on the server's part, which is certainly not the case with rate limiting - it was the client that committed the oops, not the server.

An HTTP 503 response would be correct in situations where the server was genuinely overloaded and couldn't handle more requests, but for rate limiting an HTTP 403 response is more appropriate. Nonetheless, if you think otherwise, Rack::Throttle does allow you to override the returned HTTP status code by passing in a :code => 503 option when constructing a Rack::Throttle::Limiter instance.

Dependencies

Installation

The recommended installation method is via RubyGems. To install the latest official release of the gem, do:

% [sudo] gem install rack-throttle

Authors

Contributors

Contributing

  • Do your best to adhere to the existing coding conventions and idioms.
  • Don't use hard tabs, and don't leave trailing whitespace on any line. Before committing, run git diff --check to make sure of this.
  • Do document every method you add using YARD annotations. Read the tutorial or just look at the existing code for examples.
  • Don't touch the gemspec or VERSION files. If you need to change them, do so on your private branch only.
  • Do feel free to add yourself to the CREDITS file and the corresponding list in the the README. Alphabetical order applies.
  • Don't touch the AUTHORS file. If your contributions are significant enough, be assured we will eventually add you in there.

License

This is free and unencumbered public domain software. For more information, see http://unlicense.org/ or the accompanying UNLICENSE file.

rack-throttle's People

Contributors

artob avatar bemurphy avatar brandonhilkert avatar dentarg avatar dependabot[bot] avatar ecnepsnai avatar freekingdean avatar hendricius avatar holoiii avatar karmi avatar kevinweaver avatar spone avatar thewudu avatar tr4wzified avatar ursm avatar wpeterson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rack-throttle's Issues

Key conflict when combining various throttling constraints into one overall policy

Under the section of the Readme entitled "Combining various throttling constraints into one overall policy", the following example is provided:

use Rack::Throttle::Daily,    :max => 1000  # requests
use Rack::Throttle::Hourly,   :max => 100   # requests
use Rack::Throttle::Minute,   :max => 60    # requests
use Rack::Throttle::Second,   :max => 1     # requests
use Rack::Throttle::Interval, :min => 3.0   # seconds

The only problem with this approach is that the cache keys for the same second, minute, etc can clash.

For example, consider that you have defined the throttling policy exactly as described above. Now consider the following:

  • At 12:11:10 PM, assume that throttle:10.0.2.2:2016-10-05T12:11 (the current minute) is set to 59.
  • At 12:11:10 PM, a request comes in from 10.0.2.2, which is allowed, because the max is 60 per minute. The key is now incremented to 60.
  • At 12:11:11 PM, a request comes in from 10.0.2.2, which is blocked because the key for the per-second policy is the same as the minute policy -- throttle:10.0.2.2:2016-10-05T12:11 -- which is currently 30, greatly exceeding the maximum of 1 per second.

The same thing happens at 12:12:00 PM, if the per-hour counter is higher than the max for the per-minute counter.

This looks like just a copy & paste error with the cache key for Rack::Throttle::Second.

Ideally, these keys would be distinct.

No tag for 0.4.0

The 0.4.0 version of the gem available at https://rubygems.org/gems/rack-throttle doesn't have per second limit constraint. But in the github repo, it is available. Can you please add a tag for the current version in the github repo so that I can use the github source directly in my project's gemfile?

interval.rb allowed? not calling super

I may be missing something but it seems strange that

 def allowed?(request)
      t1 = request_start_time(request)
      t0 = cache_get(key = cache_key(request)) rescue nil
      allowed = !t0 || (dt = t1 - t0.to_f) >= minimum_interval
      begin
        cache_set(key, t1)
        allowed
      rescue => e
        # If an error occurred while trying to update the timestamp stored
        # in the cache, we will fall back to allowing the request through.
        # This prevents the Rack application blowing up merely due to a
        # backend cache server (Memcached, Redis, etc.) being offline.
        allowed = true
      end
    end

in interval.rb doesn't call the super implementation in limiter.rb

def allowed?(request)
  case
    when whitelisted?(request) then true
    when blacklisted?(request) then false
    else true # override in subclasses
  end
end

use different rate-limiting for controllers

my web application has two parts, one for web, one for api.

I want to different interval rate-limiting for the them

api : use Rack::Throttle::Hourly, :max => 100 # requests
web : use Rack::Throttle::Interval, :min => 1.0 # seconds

ERROR Rack::Lint::LintError

Hi, was trying to use rack-throttle on Interval 3sec, and it works just fine until you hit the threshold, in which it errors out with:

[2011-02-04 21:00:37] ERROR Rack::Lint::LintError: Response body must respond to each
/Users/kris/.rvm/gems/ruby-1.9.2-p136@rails3/gems/rack-1.2.1/lib/rack/lint.rb:19:in assert' /Users/kris/.rvm/gems/ruby-1.9.2-p136@rails3/gems/rack-1.2.1/lib/rack/lint.rb:513:ineach'
/Users/kris/.rvm/gems/ruby-1.9.2-p136@rails3/gems/rack-1.2.1/lib/rack/handler/webrick.rb:64:in service' /Users/kris/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/webrick/httpserver.rb:111:inservice'
/Users/kris/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/webrick/httpserver.rb:70:in run' /Users/kris/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/webrick/server.rb:183:inblock in start_thread'

Wrong request IP determined in container/proxy context

Working on rack-dedos for some apps deployed to render.com (which uses Cloudflare by default), I bumped into a flaw in Rack:

Despite there being code in Rack (at least in Rack 3) which should determine the real client IP of the request not only by looking at the X-Remote-Addr but also at the X-Forwarded-For header, all versions of Rack up to 3.0.7 report the non-public IPs thru request.ip. See these remarks for details.

TL;DR request.ip is not reliable and if rack-throttle is used on an app deployed to render.com and maybe other providers, the throttling will be catastrophic since it's based on the private IP behind the proxy and not the real client IP.

This should of course be fixed on Rack, but since it's such a central piece and most notably Rails is lagging behind on Rack versions (Rails 7 still requires Rack 2), gems which perform traffic shaping will have to deal with it themselves.

Here's how I did it: https://github.com/svoop/rack-dedos/blob/main/lib/rack/dedos/filters/base.rb#L40

Missing minute directive in second.rb cache_key

In Second#cache_key method, minute directive is missing. This caused some incorrect cache hits when run in same second of same hour.

Current: [super, Time.now.strftime('%Y-%m-%dT%H:%S')].join(':')

Correct: [super, Time.now.strftime('%Y-%m-%dT%H:%M:%S')].join(':')

No such middleware to insert after: Rack::Lock

Hi

I'm using Rails 4, added custom lib that uses rack-throttle.
So, deploying failing with this notice

"No such middleware to insert after: Rack::Lock"

What is the workaround?
Thanks

Clearing Cache

Hi,

I implementing throttling on one of my websites and a client has gone over the threshold and been rate limited. I've increased the throttling limits, however the client is still rate limited a day later.

I tried restarting apache (using Passenger) but still get the error. How do I 'reset' the counter and allow this client to start fresh?

Thanks ๐Ÿ˜„

NameError: uninitialized constant Rack::Throttle::Second

Hi.
Basically as title states,

    config.middleware.use Rack::Throttle::Daily,    max: 1000  # requests
    config.middleware.use Rack::Throttle::Hourly,   max: 100   # requests
    config.middleware.use Rack::Throttle::Minute,   max: 40    # requests
    config.middleware.use Rack::Throttle::Interval, min: 3.0   # seconds
    # NameError: uninitialized constant Rack::Throttle::Second
    # config.middleware.use Rack::Throttle::Second,   max: 1     # requests

config.middleware.use Rack::Throttle::Second is throwing

NameError: uninitialized constant Rack::Throttle::Second

Rails 4.2.7
Ruby 2.3.0

Are API requests not being a subject to throttling?

Are API requests not being a subject to throttling?

I've created custom limiter, but it is not being hit while running my API specs.

    module RpmLimits
      class LimitPerMinute < ::Rack::Throttle::Minute
        def allowed?(request)
          raise # never happpens
          path_info = Rails.application.routes.recognize_path(request.url) || {}

          path_info[:controller].include?('api') ? super : true
        end
      end
    end
    # application.rb
    config.middleware.use ::RpmLimits::LimitPerMinute, max: 1

When I run other tests exception is thrown each time.

Problem with version and rubygems

I have installed the gem in my Rails object, and trying to customize the response to make it return a application/json I have found out that even if bundle install has installed me the last version 0.4.0, the code is not the same of the repo.

here is the code on my pc:

    ##
    # Outputs an HTTP `4xx` or `5xx` response.
    #
    # @param  [Integer]                code
    # @param  [String, #to_s]          message
    # @param  [Hash{String => String}] headers
    # @return [Array(Integer, Hash, #each)]
    def http_error(code, message = nil, headers = {})
      [code, {'Content-Type' => 'text/plain; charset=utf-8'}.merge(headers),
        [http_status(code), (message.nil? ? "\n" : " (#{message})\n")]]
    end

but the code of this repo is:

    ##
    # Outputs an HTTP `4xx` or `5xx` response.
    #
    # @param  [Integer]                code
    # @param  [String, #to_s]          message
    # @param  [Hash{String => String}] headers
    # @return [Array(Integer, Hash, #each)]
    def http_error(code, message = nil, headers = {})
       contentType = 'text/plain; charset=utf-8'
      if options[:type]
        contentType = options[:type]
      end
      [code, {'Content-Type' => 'text/plain; charset=utf-8'}.merge(headers),
        [http_status(code), (message.nil? ? "\n" : " (#{message})\n")]]
    end

How is this possible?

Is there maybe an error with the versioning?

Concurrency issue in setting count (time_window.rb:14) / JRuby

I'm seeing what looks like a concurrency issue in a custom Limiter based on rack-throttle.

But I'm not 100% sure, so thought I'd ask issue here.

Specifically, the retrieval and storage of count values in time_window (for example) is not atomic, so it is possible for two simultaneous increments to occur but one of the increments will not be recorded.

This is what I'm seeing in my logs:
I, [2014-08-14T16:49:04.491000 #5547] INFO -- : Rate limiting: 6061dcae08b043d9889169bd9f153fdc-d10de8798db7ced7b5850c6d7000f339:2014-08-14T16 count = 11/15 => allowed? true
I, [2014-08-14T16:49:05.201000 #5547] INFO -- : Rate limiting: 6061dcae08b043d9889169bd9f153fdc-d10de8798db7ced7b5850c6d7000f339:2014-08-14T16 count = 12/15 => allowed? true
I, [2014-08-14T16:49:05.799000 #5547] INFO -- : Rate limiting: 6061dcae08b043d9889169bd9f153fdc-d10de8798db7ced7b5850c6d7000f339:2014-08-14T16 count = 13/15 => allowed? true
I, [2014-08-14T16:49:05.806000 #5547] INFO -- : Rate limiting: 6061dcae08b043d9889169bd9f153fdc-d10de8798db7ced7b5850c6d7000f339:2014-08-14T16 count = 13/15 => allowed? true
I, [2014-08-14T16:49:07.001000 #5547] INFO -- : Rate limiting: 6061dcae08b043d9889169bd9f153fdc-d10de8798db7ced7b5850c6d7000f339:2014-08-14T16 count = 14/15 => allowed? true
I, [2014-08-14T16:49:08.630000 #5547] INFO -- : Rate limiting: 6061dcae08b043d9889169bd9f153fdc-d10de8798db7ced7b5850c6d7000f339:2014-08-14T16 count = 15/15 => allowed? true
I, [2014-08-14T16:49:10.463000 #5547] INFO -- : Rate limiting: 6061dcae08b043d9889169bd9f153fdc-d10de8798db7ced7b5850c6d7000f339:2014-08-14T16 count = 16/15 => allowed? false

The cache is a remote redis, being accessed via Ohm. Less than optimal, but I'm picking up someone else's code.

Also this is running in JRuby, and there are both hourly and daily limits in play.

The ruby threading model is not my forte, so I might be missing something obvious.

ActiveSupport::Cache::MemCacheStore unsupported

Hi.

We recently upgraded from the dalli gem to mem_cache_store. This silently broke the rack-throttle gem since it expects the cache to support :has_key?, :get, and :set.

To fix it, we applied this monkey patch...

  class RackThrottleMemCacheStore < ActiveSupport::Cache::MemCacheStore
    alias_method :has_key?, :exist?
    alias_method :get, :read
    alias_method :set, :write
  end

  # Limits :max requests per minute by session id
  cache_servers   = Rails.application.config.cache_store[1...-1]
  cache_options   = Rails.application.config.cache_store.last
  memcache_store  = RackThrottleMemCacheStore.new(cache_servers, cache_options)

  Rails.application.config.middleware.use Rack::Throttle::Minute,
                                          max:        60,
                                          key_prefix: :throttle,
                                          cache:      memcache_store

I'm not sure if there's a better way but sharing this tidbit for others who may be running this with dalli and then switched to mem_cache_store.

Thanks for this gem!
Owen

Change client identification

Instead of IP address, I would like to use the user_id to establish the limits.
From the documentation I got this:

"If you wish to instead use a more granular, application-specific identifier such as a session key or a user account name, you need only subclass a throttling strategy implementation and override the #client_identifier method."

However I don't understand how to do it..

Thanks

Use HTTP Status 429 - Too Many Requests

When throttling, it might be more accurate to return the following status code:

429 Too Many Requests

The user has sent too many requests in a given amount of time.

This is apparently intended for use with rate limiting schemes.

I realise that defaulting to this error code would be a backwards incompatible, but I think this should be documented. I can provide a PR updating the README.

Related: #5 (which changed the default status code, rather than simply documenting it)

README in latest release & tagging

Describe the bug

This is a minor bug I noticed today, and it likely won't affect many people. When running solargraph bundle locally, I got an error while building the yard docs for rack-throttle 0.7.0.

No such file or directory @ rb_sysopen - README (Errno::ENOENT)

After doing some digging, I noticed the README in the current published version is a symlink to a file that doesn't exist in the gem (README -> README.md). I couldn't confirm this immediately because of two other minor housekeeping issues:

  • Rubygems.org probably needs an update (the gem still points to bendiken/rack-throttle, which correctly forwards to this repo) to reduce confusion
  • Published gem versions after 0.5.0 don't appear tagged, or as releases on this repo (this was confusing, coupled with the item above I wasn't sure if there was 2 rack-throttles or not)

To reproduce
Steps to reproduce the behavior:

I was running solargraph bundle on a repository that had the rack-throttle in the Gemfile, but I think this probably affects anyone trying to builds the docs w/ yard

  1. Download the build gem from here: https://rubygems.org/downloads/rack-throttle-0.7.0.gem
  2. Extract/open view it however you would normally (I just unzipped everything)
  3. Observe a README symlink, but no README.md

image

Expected behavior

This appears to be fixed in latest master, but the the latest published version isn't correct

Additional context

I don't think there's anything I can contribute, PR wise, since it appears fixed in master but I'm happy to help validate after the new version is published. I can certainly point to master for now but it would be nice to see a new release published & the links updated (and versions tagged in github also)

Add cache expiration for Redis

It seems like the per-second / per-minute / etc. keys that rack-throttle creates in Redis are permanent. We run a high traffic site, which means that we're going to end up with a lot of pollution and wasted space in Redis. Ideally, there should be some way for these keys to expire.

uninitialized constant Rack::Throttle::Limiter (NameError)

gem 'rack-throttle', '~> 0.4.2'

when i run i am getting this error, can you please provide solution for this

/data/project/vendor/bundle/ruby/2.2.0/gems/rack-throttle-0.4.2/lib/rack/throttle/time_window.rb:3:in <module:Throttle>': uninitialized constant Rack::Throttle::Limiter (NameError) from /data/project/vendor/bundle/ruby/2.2.0/gems/rack-throttle-0.4.2/lib/rack/throttle/time_window.rb:1:in module:Rack'
from /data/project/vendor/bundle/ruby/2.2.0/gems/rack-throttle-0.4.2/lib/rack/throttle/time_window.rb:1:in <top (required)>' from /data/project/vendor/bundle/ruby/2.2.0/gems/backports-3.6.8/lib/backports/std_lib.rb:9:in require'
from /data/project/vendor/bundle/ruby/2.2.0/gems/backports-3.6.8/lib/backports/std_lib.rb:9:in require_with_backports' from /data/project/lib/app/rate_limiter/request_throttle.rb:1:in <top (required)>'
from /data/project/vendor/bundle/ruby/2.2.0/gems/backports-3.6.8/lib/backports/std_lib.rb:9:in require' from /data/project/vendor/bundle/ruby/2.2.0/gems/backports-3.6.8/lib/backports/std_lib.rb:9:in require_with_backports'
from config.ru:11:in block in <main>' from /data/project/vendor/bundle/ruby/2.2.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in instance_eval'
from /data/project/vendor/bundle/ruby/2.2.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in initialize' from config.ru:1:in new'
from config.ru:1:in <main>' from /data/project/vendor/bundle/ruby/2.2.0/gems/unicorn-4.6.3/lib/unicorn.rb:48:in eval'
from /data/project/vendor/bundle/ruby/2.2.0/gems/unicorn-4.6.3/lib/unicorn.rb:48:in block in builder' from /data/project/vendor/bundle/ruby/2.2.0/gems/unicorn-4.6.3/lib/unicorn/http_server.rb:722:in call'
from /data/project/vendor/bundle/ruby/2.2.0/gems/unicorn-4.6.3/lib/unicorn/http_server.rb:722:in build_app!' from /data/project/vendor/bundle/ruby/2.2.0/gems/unicorn-4.6.3/lib/unicorn/http_server.rb:140:in start'
from /data/project/vendor/bundle/ruby/2.2.0/gems/unicorn-4.6.3/bin/unicorn:126:in <top (required)>' from /data/project/vendor/bundle/ruby/2.2.0/bin/unicorn:23:in load'
from /data/project/vendor/bundle/ruby/2.2.0/bin/unicorn:23:in `

'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.