reverse_proxy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fd7a654ee0db628e1d8cd826eaa284355beb6563
4
+ data.tar.gz: 6921bff9fe9fcdce24c6151a1a9e910dbd27d12c
5
+ SHA512:
6
+ metadata.gz: f5bc61ef28f897978545e1a611bd2f172e16926da98394fc199186748f0b9762a8d95689ebf9185ea61a464145dc3a5a356ada9a5caee981ab39a0eed86ae6f4
7
+ data.tar.gz: 4fc4a47acef6dde4ad4557de8fddd61b39b242078ddba6b82a19b748f12a08f1eee7ad8972f304e9f80c1b0207de28189e1746d1888aec796b019db7e3cac87d
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ reverse_proxy
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.2
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in reverse_proxy.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # ReverseProxy
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/reverse_proxy`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'reverse_proxy'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install reverse_proxy
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it ( https://github.com/[my-github-username]/reverse_proxy/fork )
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "reverse_proxy"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,16 @@
1
+ require "reverse_proxy/version"
2
+ require "reverse_proxy/patch"
3
+
4
+ require "reverse_proxy/instance"
5
+ require "reverse_proxy/logger"
6
+
7
+ require "reverse_proxy/bind"
8
+ require "reverse_proxy/config"
9
+ require "reverse_proxy/proxy"
10
+ require "reverse_proxy/server"
11
+ require "reverse_proxy/application"
12
+
13
+ module ReverseProxy
14
+ extend ReverseProxy::Instance
15
+ end
16
+
@@ -0,0 +1,25 @@
1
+ module ReverseProxy
2
+ class Application
3
+ include Logger
4
+ attr_reader :proxy
5
+ def initialize proxy
6
+ @proxy = proxy
7
+ end
8
+ def socket
9
+ proxy.server.socket.unix.to_puma
10
+ end
11
+ def send_assets?
12
+ return false unless Object.const_defined?(:Rails)
13
+ return Rails.application.config.assets.compile == false
14
+ end
15
+ def assets
16
+ "/assets"
17
+ end
18
+ def mime_types
19
+ return unless Object.const_defined? :Mime
20
+ types = {}
21
+ Mime::EXTENSION_LOOKUP.each{|ext,type| types[type.to_s] ||= []; types[type.to_s] << ext }
22
+ types.collect{|name,extensions| [name,extensions.join(" ")]}.to_h
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ module ReverseProxy
2
+ class Bind
3
+ class Formatter
4
+ class << self
5
+ def add type, format
6
+ formats[type.to_s] = format
7
+ end
8
+ def formats
9
+ @@formats ||= {}
10
+ end
11
+ end
12
+ attr_reader :data
13
+ def initialize data
14
+ @data = data
15
+ end
16
+ private
17
+ def format target
18
+ self.class.formats[target].call(self)
19
+ end
20
+ def method_missing method
21
+ return @bind.send method if @bind.respond_to? method
22
+ format("#{method}".scan(/^to_([a-z]+)/)[0][0])
23
+ end
24
+ end
25
+
26
+ class Unix < Formatter; def scheme; "unix"; end; end
27
+ class Tcp < Formatter; def scheme; "tcp"; end; end
28
+
29
+ def initialize bind
30
+ @bind = "#{bind}".sub(/[a-z0-9]+:\/\//,'')
31
+ end
32
+ def add type, format
33
+ Formatter.add type, format
34
+ end
35
+ def tcp
36
+ @tcp ||= Tcp.new @bind
37
+ end
38
+ def unix
39
+ @unix ||= Unix.new @bind
40
+ end
41
+ private
42
+ def method_missing method, *args, &block
43
+ @bind.send method, *args, &block
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,11 @@
1
+ require "reverse_proxy/config/generic"
2
+ require "reverse_proxy/config/nginx"
3
+
4
+ module ReverseProxy
5
+ module Config
6
+ def self.for instance
7
+ config_klass = self.const_get instance.class.name.split('::').last
8
+ config_klass.new instance
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ module ReverseProxy
2
+ module Config
3
+ class Generic
4
+ include Logger
5
+ attr_reader :proxy
6
+ def initialize proxy
7
+ @proxy = proxy
8
+ proxy.config = self
9
+ @written = false
10
+ end
11
+ def prepare type
12
+ return unless block_given?
13
+ result = yield
14
+ name = result.to_s.strip
15
+ mkdir name if type.to_s =~ /^dir/
16
+ touch name if type.to_s =~ /^file/
17
+ result
18
+ end
19
+ private
20
+ def mkdir dir
21
+ FileUtils.mkdir_p dir
22
+ end
23
+ def touch file
24
+ mkdir File.dirname file
25
+ FileUtils.touch file
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,148 @@
1
+ require "pathname"
2
+ require "fileutils"
3
+ require "active_support/core_ext/string/strip"
4
+ require "erb"
5
+
6
+ module ReverseProxy
7
+ module Config
8
+ class Nginx < Generic
9
+
10
+ def clean
11
+ File.unlink(file) rescue nil
12
+ File.unlink(pid) rescue nil
13
+ FileUtils.rmdir(dir) rescue nil
14
+ end
15
+ alias_method :delete, :clean
16
+
17
+ def write
18
+ File.write(file, content) and updated! if updated?
19
+ end
20
+
21
+ def updated?
22
+ Digest::MD5.hexdigest(content) != @hash
23
+ end
24
+ def updated!
25
+ @hash = Digest::MD5.hexdigest(content)
26
+ end
27
+
28
+ def written?
29
+ File.exists? file
30
+ end
31
+
32
+ def content
33
+ ERB.new(<<-CONTENT.strip_heredoc).result(binding).gsub(/\n/,'').gsub(/\s{2,}/, ' ')
34
+ daemon off;
35
+ worker_processes 2;
36
+ worker_rlimit_nofile 8192;
37
+ pid <%= pid.relative_path_from chroot %>;
38
+ error_log error.log;
39
+ events {
40
+ worker_connections 2048;
41
+ }
42
+ http {
43
+ <%= types %>
44
+ <%= upstream %>
45
+ default_type <%= default_type %>;
46
+ charset_types <%= charset_types %>;
47
+ keepalive_timeout 5;
48
+ tcp_nopush on;
49
+ sendfile on;
50
+ gzip on;
51
+ gzip_comp_level 5;
52
+ gzip_min_length 256;
53
+ gzip_proxied any;
54
+ gzip_vary on;
55
+ gzip_types <%= gzip_types %>;
56
+ server {
57
+ <%= listeners %>
58
+ <%= assets %>
59
+ <%= root %>
60
+ <%= redirect %>
61
+ }
62
+ }
63
+ CONTENT
64
+ end
65
+ def upstream
66
+ "upstream #{upstream_label} { server #{proxy.server.socket.unix.to_upstream} fail_timeout=0; }"
67
+ end
68
+ def default_type
69
+ "application/octet-stream"
70
+ end
71
+ def charset_types
72
+ %w{
73
+ text/xml
74
+ text/plain
75
+ text/vnd.wap.wml
76
+ application/x-javascript
77
+ application/rss+xml
78
+ text/css
79
+ application/javascript
80
+ application/json
81
+ }.join(" ")
82
+ end
83
+ def upstream_label
84
+ "application_#{proxy.id}"
85
+ end
86
+ def gzip_types
87
+ proxy.application.mime_types.keys.select do |type|type
88
+ type.match(/((font)|(^text)|(css)|(script)|(bmp$)|(ml$))/)
89
+ end.reject{|x|x=="text/html"}.join(" ")
90
+ end
91
+ def types
92
+ @types = proxy.application.mime_types.collect{|type,extensions|"#{type} #{extensions};"}
93
+ @types ||= ["text/plain txt;"]
94
+ "types {" + @types.join + "}"
95
+ end
96
+ def listeners
97
+ proxy.binds.collect do |bind|
98
+ "listen #{bind.tcp.to_nginx};\n"
99
+ end.join
100
+ end
101
+ def root
102
+ "location / {
103
+ try_files $uri $uri/index.html $uri.html @#{proxy.id};
104
+ }"
105
+ end
106
+ def redirect
107
+ <<-REDIRECT.strip_heredoc
108
+ location @#{proxy.id} {
109
+ proxy_read_timeout 300;
110
+ proxy_connect_timeout 300;
111
+ proxy_redirect off;
112
+
113
+ proxy_set_header X-Forwarded-Proto https;
114
+ proxy_set_header X-Forwarded-Ssl on;
115
+ proxy_set_header Host $http_host;
116
+ proxy_set_header X-Real-IP $remote_addr;
117
+
118
+ proxy_pass http://#{upstream_label};
119
+ }
120
+ REDIRECT
121
+ end
122
+ def assets
123
+ return unless proxy.application.send_assets?
124
+ <<-ASSETS.strip_heredoc
125
+ location ~ ^#{proxy.application.assets}/ {
126
+ root #{Rails.root.join("public")};
127
+ gzip_static on;
128
+ expires max;
129
+ add_header Cache-Control public;
130
+ access_log /dev/null;
131
+ }
132
+ ASSETS
133
+ end
134
+ def pid
135
+ chroot.join("nginx.pid")
136
+ end
137
+ def file
138
+ chroot.join("nginx.cfg")
139
+ end
140
+ def chroot
141
+ prepare :dir do
142
+ Pathname.new "/tmp/#{proxy.id}"
143
+ end
144
+ end
145
+ alias_method :dir, :chroot
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,8 @@
1
+ module ReverseProxy
2
+ module Instance
3
+ attr_accessor :instance
4
+ def reload
5
+ instance.reload if instance
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module ReverseProxy
2
+ module Logger
3
+ def log *args
4
+ proxy.log *args
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require "reverse_proxy/patch/puma"
2
+
3
+ module ReverseProxy
4
+ module Patch
5
+ def self.apply
6
+ ReverseProxy::Patch::Puma.patch
7
+ end
8
+ end
9
+ end
10
+
11
+ ReverseProxy::Patch.apply
@@ -0,0 +1,42 @@
1
+ module ReverseProxy
2
+ module Patch
3
+ module Puma
4
+ module DSL
5
+ def reverse_proxy proxy
6
+ @proxy_klass ||= ReverseProxy::Proxy.const_get(proxy)
7
+ @proxy ||= @proxy_klass.new server: :Puma
8
+
9
+ @proxy.hijack do |secondary_bind|
10
+ bind secondary_bind.unix.to_puma
11
+ end
12
+
13
+ after_worker_boot do
14
+ @options[:logger].register(:on_booted){@proxy.on_booted}
15
+ end
16
+
17
+ @proxy.application_config = self
18
+ %i{
19
+ after_worker_boot
20
+ on_restart
21
+ on_worker_boot
22
+ on_worker_shutdown
23
+ }.each do |event|
24
+ self.send(event){ @proxy.send(event)}
25
+ end
26
+ end
27
+ end
28
+ def self.patch
29
+ require "puma/configuration" rescue return
30
+ require "puma/dsl" rescue return
31
+ require "puma/cluster" rescue return
32
+ ::Puma::DSL.send :include, ReverseProxy::Patch::Puma::DSL
33
+ # FIXME: This is a really ugly hack to receive events while the app is running
34
+ ::Puma::Cluster::Worker.send :remove_method, :booted?
35
+ ::Puma::Cluster::Worker.send :define_method, :booted? do
36
+ ::ReverseProxy.instance.send :"on_#{@stage}" if @stage == :booted
37
+ @stage == :booted
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ require "reverse_proxy/proxy/generic"
2
+ require "reverse_proxy/proxy/nginx"
3
+
4
+ module ReverseProxy
5
+ module Proxy
6
+ class << self
7
+ attr_accessor :id
8
+ end
9
+ self.id = SecureRandom.hex
10
+ end
11
+ end
@@ -0,0 +1,68 @@
1
+ require "thread"
2
+ require "set"
3
+
4
+ module ReverseProxy
5
+ module Proxy
6
+ class Generic
7
+ class << self
8
+ attr_reader :events
9
+ private
10
+ def register_event event, *args, &callback
11
+ @events ||= {}
12
+ @events[event] ||= {}
13
+ @events[event][:methods] ||= []
14
+ @events[event][:methods] << args
15
+ @events[event][:callbacks] ||= []
16
+ @events[event][:callbacks] << callback
17
+ end
18
+ def method_missing method, *args, &block
19
+ self.send(:register_event, method, *args, &block) if method.to_s =~ /^(on|before|after)_/
20
+ end
21
+ end
22
+
23
+ attr_reader :pid, :lock
24
+ attr_accessor :application, :config, :server, :binds
25
+
26
+ def initialize params={}
27
+ ReverseProxy.instance = self
28
+ @pid = Process.pid
29
+ @lock ||= Mutex.new
30
+ @server = ReverseProxy::Server.const_get(params[:server]).new self
31
+ @binds ||= Set.new
32
+ @application = Application.new self
33
+ @config ||= Config.for self
34
+ prepare
35
+ on_initialize
36
+ end
37
+ def log message
38
+ puts "[#{pid}] #{message}"
39
+ end
40
+ def id
41
+ ReverseProxy::Proxy.id
42
+ end
43
+ def start
44
+ @start.call
45
+ end
46
+ def stop
47
+ @stop.call
48
+ end
49
+ def reload
50
+ @reload.call
51
+ end
52
+ private
53
+ def server_event event
54
+ methods = self.class.events[event][:methods].flatten.compact rescue []
55
+ callbacks = self.class.events[event][:callbacks].flatten.compact rescue []
56
+ methods.each do |method|
57
+ self.send method
58
+ end
59
+ callbacks.map do |callback|
60
+ callback.call
61
+ end
62
+ end
63
+ def method_missing method, *args, &block
64
+ self.send(:server_event, method) if method.to_s =~ /^(on|before|after)_/
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,77 @@
1
+ require "uri"
2
+
3
+ module ReverseProxy
4
+ module Proxy
5
+ class Nginx < Generic
6
+
7
+ on_booted :start
8
+ on_worker_shutdown :stop
9
+
10
+ attr_reader :stage
11
+ attr_accessor :nginx_executable
12
+
13
+ def prepare
14
+ Bind::Formatter.add :upstream, ->(data) { "#{data.scheme}:#{data.data}"}
15
+ Bind::Formatter.add :nginx, ->(data) { "#{data.data}"}
16
+ @stage = :initialized
17
+ @nginx_executable = "nginx"
18
+ end
19
+
20
+ def start
21
+ sleep(Random.rand*0.1)
22
+ return if config.written?
23
+ config.write
24
+ log "Start Nginx, #{start_command}"
25
+ at_exit{ log "Stop Nginx"; stop }
26
+ Thread.new { `#{start_command}` }
27
+ end
28
+
29
+ def stop
30
+ return unless started?
31
+ `#{stop_command}`
32
+ config.clean
33
+ end
34
+
35
+ def restart
36
+ log "Restart NGinx"
37
+ stop
38
+ start
39
+ end
40
+ def reload
41
+ return unless config.updated?
42
+ start unless started?
43
+ log "Reload Nginx"
44
+ config.write
45
+ `#{reload_command}`
46
+ end
47
+
48
+ def hijack
49
+ @binds += server.binds.select{|x| x.match(/^tcp:/)}
50
+ server.binds = server.binds.reject{|x| x.match(/^tcp:/) }
51
+ @binds << server.default_bind if @binds.empty?
52
+ @binds = @binds.map{|b|Bind.new(b)}
53
+ yield Bind.new(application.socket)
54
+ log "Nginx listenens at #{@binds.map{|b|b.tcp.to_nginx}.join(", ")}"
55
+ end
56
+
57
+ def listen
58
+ @binds.collect do |bind|
59
+ bind.tcp.to_nginx
60
+ end
61
+ end
62
+
63
+ def basic_command
64
+ "#{nginx_executable} -p #{config.dir} -c #{config.file.relative_path_from config.dir}"
65
+ end
66
+ def reload_command
67
+ "#{basic_command} -s reload"
68
+ end
69
+ def stop_command
70
+ "#{basic_command} -s quit"
71
+ end
72
+ def start_command
73
+ "#{basic_command}"
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,2 @@
1
+ require "reverse_proxy/server/generic"
2
+ require "reverse_proxy/server/puma"
@@ -0,0 +1,12 @@
1
+ module ReverseProxy
2
+ module Server
3
+ class Generic
4
+ include Logger
5
+ def name
6
+ self.class.name.split("::").last
7
+ end
8
+ def socket
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ module ReverseProxy
2
+ module Server
3
+ class Puma < Generic
4
+ attr_reader :server, :proxy, :default_bind
5
+ def initialize proxy
6
+ Bind::Formatter.add :puma, Proc.new {|data| "#{data.scheme}://#{data.data}"}
7
+ @server = ::Puma
8
+ @proxy = proxy
9
+ @default_bind = 'tcp://0.0.0.0:9292'
10
+ end
11
+ def config
12
+ @server.cli_config
13
+ end
14
+ def socket
15
+ @socket ||= Bind.new proxy.config.dir.join('puma.sock').to_s
16
+ end
17
+ def binds
18
+ ([] + config.options[:binds]).compact
19
+ end
20
+ def binds= binds
21
+ config.options[:binds] = binds
22
+ log "#{name} listens at #{binds.empty? ? "default" : binds.join(", ")}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module ReverseProxy
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'reverse_proxy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "reverse_proxy"
8
+ spec.version = ReverseProxy::VERSION
9
+ spec.authors = ["Mathias Kaufmann"]
10
+ spec.email = ["me@stei.gr"]
11
+
12
+ spec.summary = %q{ReverseProxy starts a reverse proxy in front of a rails application server.}
13
+ spec.description = %q{ReverseProxy starts a reverse proxy in front of a rails application server.}
14
+ spec.homepage = "https://ruby.stei.gr/reverse_proxy"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.9"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reverse_proxy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mathias Kaufmann
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-04-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ description: ReverseProxy starts a reverse proxy in front of a rails application server.
56
+ email:
57
+ - me@stei.gr
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".ruby-gemset"
64
+ - ".ruby-version"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - lib/reverse_proxy.rb
72
+ - lib/reverse_proxy/application.rb
73
+ - lib/reverse_proxy/bind.rb
74
+ - lib/reverse_proxy/config.rb
75
+ - lib/reverse_proxy/config/generic.rb
76
+ - lib/reverse_proxy/config/nginx.rb
77
+ - lib/reverse_proxy/instance.rb
78
+ - lib/reverse_proxy/logger.rb
79
+ - lib/reverse_proxy/patch.rb
80
+ - lib/reverse_proxy/patch/puma.rb
81
+ - lib/reverse_proxy/proxy.rb
82
+ - lib/reverse_proxy/proxy/generic.rb
83
+ - lib/reverse_proxy/proxy/nginx.rb
84
+ - lib/reverse_proxy/server.rb
85
+ - lib/reverse_proxy/server/generic.rb
86
+ - lib/reverse_proxy/server/puma.rb
87
+ - lib/reverse_proxy/version.rb
88
+ - reverse_proxy.gemspec
89
+ homepage: https://ruby.stei.gr/reverse_proxy
90
+ licenses: []
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.6
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: ReverseProxy starts a reverse proxy in front of a rails application server.
112
+ test_files: []