rails-threaded-proxy 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +39 -0
- data/Gemfile +10 -9
- data/Gemfile.lock +24 -0
- data/Rakefile +10 -10
- data/VERSION +1 -1
- data/bin/rubocop +27 -0
- data/lib/rails-threaded-proxy.rb +3 -1
- data/lib/threaded-proxy.rb +3 -1
- data/lib/threaded_proxy/client.rb +43 -35
- data/lib/threaded_proxy/controller.rb +5 -5
- data/lib/threaded_proxy/http.rb +4 -1
- data/lib/threaded_proxy.rb +3 -3
- data/rails-threaded-proxy.gemspec +6 -3
- data/spec/spec_helper.rb +2 -0
- data/spec/threaded_proxy/client_spec.rb +13 -9
- metadata +18 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbc7f9b0318c1136497926119e07a245bacd9d017126add8a1da34e7426d79e0
|
4
|
+
data.tar.gz: 6506ac75b092ad1530ef54ceaf5d4c75775b3589cb1db2648afef0598e54c9de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38bfa986e8033530bdddcf28a201ce18648bb8d8b46cd7d6738c8addc736aee573f685fc355d45072f6dcd4b632f22e5280891a67d56f7ccb75d9391d92300bb
|
7
|
+
data.tar.gz: 5a03daa8831574b0dc693916f11a7ebc8bfe8f409578a45e1de82f0f849b60c76dab4c929bf7c91322030f74ce6060df0eb99fdbab28390641df81f195844959
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
4
|
+
# any parameters. The file can be placed either in your home
|
5
|
+
# directory or in some project directory.
|
6
|
+
#
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
9
|
+
#
|
10
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
11
|
+
|
12
|
+
AllCops:
|
13
|
+
Exclude:
|
14
|
+
- '*.gemspec'
|
15
|
+
- 'bin/*'
|
16
|
+
|
17
|
+
Metrics/BlockLength:
|
18
|
+
Exclude:
|
19
|
+
- 'spec/**/*.rb'
|
20
|
+
|
21
|
+
Metrics/PerceivedComplexity:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Metrics/MethodLength:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Metrics/AbcSize:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
Metrics/CyclomaticComplexity:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Style/Documentation:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
Naming/FileName:
|
37
|
+
Exclude:
|
38
|
+
- 'lib/rails-threaded-proxy.rb'
|
39
|
+
- 'lib/threaded-proxy.rb'
|
data/Gemfile
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem
|
6
|
-
gem
|
5
|
+
gem 'actionpack'
|
6
|
+
gem 'addressable'
|
7
7
|
|
8
8
|
group :development do
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
gem
|
13
|
-
gem
|
14
|
-
gem
|
9
|
+
gem 'bundler', '~> 2.0'
|
10
|
+
gem 'jeweler', '~> 2.3.9'
|
11
|
+
gem 'nokogiri', '>= 1.16.7'
|
12
|
+
gem 'rdoc', '~> 6.7.0'
|
13
|
+
gem 'rspec', '>= 0'
|
14
|
+
gem 'rubocop', '>= 0'
|
15
|
+
gem 'webrick', '>= 0'
|
15
16
|
end
|
data/Gemfile.lock
CHANGED
@@ -30,6 +30,7 @@ GEM
|
|
30
30
|
securerandom (>= 0.3)
|
31
31
|
tzinfo (~> 2.0, >= 2.0.5)
|
32
32
|
addressable (2.4.0)
|
33
|
+
ast (2.4.2)
|
33
34
|
base64 (0.2.0)
|
34
35
|
bigdecimal (3.1.8)
|
35
36
|
builder (3.3.0)
|
@@ -69,8 +70,10 @@ GEM
|
|
69
70
|
rake
|
70
71
|
rdoc
|
71
72
|
semver2
|
73
|
+
json (2.7.2)
|
72
74
|
jwt (2.9.3)
|
73
75
|
base64
|
76
|
+
language_server-protocol (3.17.0.3)
|
74
77
|
logger (1.6.1)
|
75
78
|
loofah (2.22.0)
|
76
79
|
crass (~> 1.0.2)
|
@@ -99,6 +102,10 @@ GEM
|
|
99
102
|
multi_json (~> 1.3)
|
100
103
|
multi_xml (~> 0.5)
|
101
104
|
rack (>= 1.2, < 3)
|
105
|
+
parallel (1.26.3)
|
106
|
+
parser (3.3.5.0)
|
107
|
+
ast (~> 2.4.1)
|
108
|
+
racc
|
102
109
|
psych (5.1.2)
|
103
110
|
stringio
|
104
111
|
racc (1.8.1)
|
@@ -114,10 +121,12 @@ GEM
|
|
114
121
|
rails-html-sanitizer (1.6.0)
|
115
122
|
loofah (~> 2.21)
|
116
123
|
nokogiri (~> 1.14)
|
124
|
+
rainbow (3.1.1)
|
117
125
|
rake (13.2.1)
|
118
126
|
rchardet (1.8.0)
|
119
127
|
rdoc (6.7.0)
|
120
128
|
psych (>= 4.0.0)
|
129
|
+
regexp_parser (2.9.2)
|
121
130
|
reline (0.5.10)
|
122
131
|
io-console (~> 0.5)
|
123
132
|
rspec (3.13.0)
|
@@ -133,12 +142,26 @@ GEM
|
|
133
142
|
diff-lcs (>= 1.2.0, < 2.0)
|
134
143
|
rspec-support (~> 3.13.0)
|
135
144
|
rspec-support (3.13.1)
|
145
|
+
rubocop (1.66.1)
|
146
|
+
json (~> 2.3)
|
147
|
+
language_server-protocol (>= 3.17.0)
|
148
|
+
parallel (~> 1.10)
|
149
|
+
parser (>= 3.3.0.2)
|
150
|
+
rainbow (>= 2.2.2, < 4.0)
|
151
|
+
regexp_parser (>= 2.4, < 3.0)
|
152
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
153
|
+
ruby-progressbar (~> 1.7)
|
154
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
155
|
+
rubocop-ast (1.32.3)
|
156
|
+
parser (>= 3.3.1.0)
|
157
|
+
ruby-progressbar (1.13.0)
|
136
158
|
securerandom (0.3.1)
|
137
159
|
semver2 (3.4.2)
|
138
160
|
stringio (3.1.1)
|
139
161
|
thread_safe (0.3.6)
|
140
162
|
tzinfo (2.0.6)
|
141
163
|
concurrent-ruby (~> 1.0)
|
164
|
+
unicode-display_width (2.6.0)
|
142
165
|
useragent (0.16.10)
|
143
166
|
webrick (1.8.2)
|
144
167
|
|
@@ -158,6 +181,7 @@ DEPENDENCIES
|
|
158
181
|
nokogiri (>= 1.16.7)
|
159
182
|
rdoc (~> 6.7.0)
|
160
183
|
rspec
|
184
|
+
rubocop
|
161
185
|
webrick
|
162
186
|
|
163
187
|
BUNDLED WITH
|
data/Rakefile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'bundler'
|
5
5
|
begin
|
6
6
|
Bundler.setup(:default, :development)
|
7
7
|
rescue Bundler::BundlerError => e
|
8
|
-
|
9
|
-
|
8
|
+
warn e.message
|
9
|
+
warn 'Run `bundle install` to install missing gems'
|
10
10
|
exit e.status_code
|
11
11
|
end
|
12
12
|
require 'rake'
|
@@ -14,13 +14,13 @@ require 'rake'
|
|
14
14
|
require 'jeweler'
|
15
15
|
Jeweler::Tasks.new do |gem|
|
16
16
|
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
17
|
-
gem.name =
|
18
|
-
gem.homepage =
|
19
|
-
gem.license =
|
20
|
-
gem.summary = %
|
21
|
-
gem.description = %
|
22
|
-
gem.email =
|
23
|
-
gem.authors = [
|
17
|
+
gem.name = 'rails-threaded-proxy'
|
18
|
+
gem.homepage = 'http://github.com/mnutt/rails-threaded-proxy'
|
19
|
+
gem.license = 'MIT'
|
20
|
+
gem.summary = %(Threaded reverse proxy for Ruby on Rails)
|
21
|
+
gem.description = %(Threaded reverse proxy for Ruby on Rails)
|
22
|
+
gem.email = 'michael@nuttnet.net'
|
23
|
+
gem.authors = ['Michael Nutt']
|
24
24
|
# dependencies defined in Gemfile
|
25
25
|
end
|
26
26
|
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bin/rubocop
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
12
|
+
|
13
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
14
|
+
|
15
|
+
if File.file?(bundle_binstub)
|
16
|
+
if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
|
17
|
+
load(bundle_binstub)
|
18
|
+
else
|
19
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
20
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require 'bundler/setup'
|
26
|
+
|
27
|
+
load Gem.bin_path('rubocop', 'rubocop')
|
data/lib/rails-threaded-proxy.rb
CHANGED
data/lib/threaded-proxy.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'addressable/uri'
|
4
|
+
require 'active_support/notifications'
|
2
5
|
require 'net/http'
|
3
6
|
require_relative 'http'
|
4
7
|
|
5
8
|
module ThreadedProxy
|
6
9
|
class Client
|
7
|
-
DISALLOWED_RESPONSE_HEADERS = %w[keep-alive]
|
10
|
+
DISALLOWED_RESPONSE_HEADERS = %w[keep-alive].freeze
|
8
11
|
|
9
12
|
METHODS = {
|
10
13
|
'get' => Net::HTTP::Get,
|
@@ -14,62 +17,69 @@ module ThreadedProxy
|
|
14
17
|
'head' => Net::HTTP::Head,
|
15
18
|
'options' => Net::HTTP::Options,
|
16
19
|
'trace' => Net::HTTP::Trace
|
17
|
-
}
|
20
|
+
}.freeze
|
18
21
|
|
19
22
|
DEFAULT_OPTIONS = {
|
20
23
|
headers: {},
|
21
|
-
debug: false
|
22
|
-
|
24
|
+
debug: false,
|
25
|
+
method: :get
|
26
|
+
}.freeze
|
23
27
|
|
24
|
-
def initialize(origin_url, options={})
|
28
|
+
def initialize(origin_url, options = {})
|
25
29
|
@origin_url = Addressable::URI.parse(origin_url)
|
26
30
|
@options = DEFAULT_OPTIONS.merge(options)
|
27
31
|
end
|
28
32
|
|
29
33
|
def log(message)
|
30
|
-
|
34
|
+
warn message if @options[:debug]
|
31
35
|
end
|
32
36
|
|
33
37
|
def start(socket)
|
34
|
-
request_method =
|
35
|
-
|
38
|
+
request_method = @options[:method].to_s.downcase
|
39
|
+
request_headers = @options[:headers].merge('Connection' => 'close')
|
40
|
+
|
41
|
+
request_class = METHODS[request_method]
|
42
|
+
http_request = request_class.new(@origin_url, request_headers)
|
36
43
|
if @options[:body].respond_to?(:read)
|
37
44
|
http_request.body_stream = @options[:body]
|
38
|
-
elsif
|
45
|
+
elsif @options[:body].is_a?(String)
|
39
46
|
http_request.body = @options[:body]
|
40
47
|
end
|
41
48
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
49
|
+
ActiveSupport::Notifications.instrument('threaded_proxy.fetch', method: request_method, url: @origin_url.to_s,
|
50
|
+
headers: request_headers) do
|
51
|
+
http = HTTP.new(@origin_url.host, @origin_url.port || default_port(@origin_url))
|
52
|
+
http.use_ssl = (@origin_url.scheme == 'https')
|
53
|
+
http.set_debug_output($stderr) if @options[:debug]
|
54
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @options[:ignore_ssl_errors]
|
46
55
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
56
|
+
http.start do
|
57
|
+
http.request(http_request) do |client_response|
|
58
|
+
# We don't support reusing connections once we have disconnected them from rack
|
59
|
+
client_response['connection'] = 'close'
|
51
60
|
|
52
|
-
|
61
|
+
yield client_response if block_given?
|
53
62
|
|
54
|
-
|
55
|
-
|
56
|
-
|
63
|
+
# start writing response
|
64
|
+
log('Writing response status and headers')
|
65
|
+
socket.write "HTTP/1.1 #{client_response.code} #{client_response.message}\r\n"
|
57
66
|
|
58
|
-
|
59
|
-
|
60
|
-
|
67
|
+
client_response.each_header do |key, value|
|
68
|
+
socket.write "#{key}: #{value}\r\n" unless DISALLOWED_RESPONSE_HEADERS.include?(key.downcase)
|
69
|
+
end
|
61
70
|
|
62
|
-
|
63
|
-
|
71
|
+
# Done with headers
|
72
|
+
socket.write "\r\n"
|
64
73
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
74
|
+
# There may have been some existing data in client_response's read buffer, flush it out
|
75
|
+
# before we manually connect the raw sockets
|
76
|
+
log('Flushing existing response buffer to client')
|
77
|
+
http.flush_existing_buffer_to(socket)
|
69
78
|
|
70
|
-
|
71
|
-
|
72
|
-
|
79
|
+
# Copy the rest of the client response to the socket
|
80
|
+
log('Copying response body to client')
|
81
|
+
http.copy_to(socket)
|
82
|
+
end
|
73
83
|
end
|
74
84
|
end
|
75
85
|
end
|
@@ -80,8 +90,6 @@ module ThreadedProxy
|
|
80
90
|
80
|
81
91
|
when 'https'
|
82
92
|
443
|
83
|
-
else
|
84
|
-
nil
|
85
93
|
end
|
86
94
|
end
|
87
95
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'client'
|
2
4
|
|
3
5
|
module ThreadedProxy
|
4
6
|
module Controller
|
5
|
-
def proxy_fetch(origin_url, options={})
|
7
|
+
def proxy_fetch(origin_url, options = {})
|
6
8
|
# hijack the response so we can take it outside of the rack request/response cycle
|
7
9
|
request.env['rack.hijack'].call
|
8
10
|
socket = request.env['rack.hijack_io']
|
@@ -17,12 +19,10 @@ module ThreadedProxy
|
|
17
19
|
elsif request.env['CONTENT_LENGTH']
|
18
20
|
options[:headers]['content-length'] = request.env['CONTENT_LENGTH'].to_s
|
19
21
|
else
|
20
|
-
raise
|
22
|
+
raise 'Cannot proxy a non-chunked POST request without content-length'
|
21
23
|
end
|
22
24
|
|
23
|
-
if request.env['CONTENT_TYPE']
|
24
|
-
options[:headers]['Content-Type'] = request.env['CONTENT_TYPE']
|
25
|
-
end
|
25
|
+
options[:headers]['Content-Type'] = request.env['CONTENT_TYPE'] if request.env['CONTENT_TYPE']
|
26
26
|
end
|
27
27
|
|
28
28
|
client = Client.new(origin_url, options)
|
data/lib/threaded_proxy/http.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'net/http'
|
2
4
|
|
3
5
|
module ThreadedProxy
|
@@ -5,6 +7,7 @@ module ThreadedProxy
|
|
5
7
|
def flush_existing_buffer_to(dest_socket)
|
6
8
|
while (data = @socket.send(:rbuf_consume))
|
7
9
|
break if data.empty?
|
10
|
+
|
8
11
|
dest_socket.write data
|
9
12
|
end
|
10
13
|
|
@@ -27,7 +30,7 @@ module ThreadedProxy
|
|
27
30
|
|
28
31
|
# We read the response ourselves; don't need net/http to try to read it again
|
29
32
|
def hijack_response(res)
|
30
|
-
res.instance_variable_set(
|
33
|
+
res.instance_variable_set('@read', true)
|
31
34
|
res
|
32
35
|
end
|
33
36
|
end
|
data/lib/threaded_proxy.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'threaded_proxy/client'
|
2
4
|
require 'threaded_proxy/controller'
|
3
5
|
|
4
6
|
module ThreadedProxy
|
5
7
|
def version
|
6
|
-
File.open(File.expand_path(
|
8
|
+
File.open(File.expand_path('../VERSION', __dir__)).read.strip
|
7
9
|
end
|
8
|
-
|
9
|
-
extend self
|
10
10
|
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: rails-threaded-proxy 0.
|
5
|
+
# stub: rails-threaded-proxy 0.3.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "rails-threaded-proxy".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.3.0".freeze
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
@@ -14,13 +14,14 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.date = "2024-10-14"
|
15
15
|
s.description = "Threaded reverse proxy for Ruby on Rails".freeze
|
16
16
|
s.email = "michael@nuttnet.net".freeze
|
17
|
-
s.executables = ["bundle".freeze, "htmldiff".freeze, "jeweler".freeze, "ldiff".freeze, "nokogiri".freeze, "racc".freeze, "rackup".freeze, "rake".freeze, "rdoc".freeze, "ri".freeze, "rspec".freeze, "semver".freeze]
|
17
|
+
s.executables = ["bundle".freeze, "htmldiff".freeze, "jeweler".freeze, "ldiff".freeze, "nokogiri".freeze, "racc".freeze, "rackup".freeze, "rake".freeze, "rdoc".freeze, "ri".freeze, "rspec".freeze, "rubocop".freeze, "semver".freeze]
|
18
18
|
s.extra_rdoc_files = [
|
19
19
|
"LICENSE"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".bundle/config",
|
23
23
|
".rspec",
|
24
|
+
".rubocop.yml",
|
24
25
|
".ruby-version",
|
25
26
|
"Gemfile",
|
26
27
|
"Gemfile.lock",
|
@@ -38,6 +39,7 @@ Gem::Specification.new do |s|
|
|
38
39
|
"bin/rdoc",
|
39
40
|
"bin/ri",
|
40
41
|
"bin/rspec",
|
42
|
+
"bin/rubocop",
|
41
43
|
"bin/semver",
|
42
44
|
"lib/rails-threaded-proxy.rb",
|
43
45
|
"lib/threaded-proxy.rb",
|
@@ -63,6 +65,7 @@ Gem::Specification.new do |s|
|
|
63
65
|
s.add_development_dependency(%q<nokogiri>.freeze, [">= 1.16.7".freeze])
|
64
66
|
s.add_development_dependency(%q<rdoc>.freeze, ["~> 6.7.0".freeze])
|
65
67
|
s.add_development_dependency(%q<rspec>.freeze, [">= 0".freeze])
|
68
|
+
s.add_development_dependency(%q<rubocop>.freeze, [">= 0".freeze])
|
66
69
|
s.add_development_dependency(%q<webrick>.freeze, [">= 0".freeze])
|
67
70
|
end
|
68
71
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails-threaded-proxy'
|
2
4
|
require 'json'
|
3
5
|
|
4
|
-
|
5
|
-
BACKEND_PORT = 38293
|
6
|
+
BACKEND_STUB_PORT = 38_293
|
6
7
|
|
8
|
+
RSpec.describe ThreadedProxy::Client do
|
7
9
|
before(:all) do
|
8
|
-
@backend_server = WEBrick::HTTPServer.new(Port:
|
9
|
-
Logger: WEBrick::Log.new(
|
10
|
+
@backend_server = WEBrick::HTTPServer.new(Port: BACKEND_STUB_PORT,
|
11
|
+
Logger: WEBrick::Log.new('/dev/null'),
|
10
12
|
AccessLog: [])
|
11
13
|
@backend_server.mount_proc '/get' do |req, res|
|
12
14
|
raise unless req.request_method == 'GET'
|
15
|
+
|
13
16
|
res.body = "Received request: #{req.path}"
|
14
17
|
end
|
15
18
|
|
16
19
|
@backend_server.mount_proc '/post' do |req, res|
|
17
20
|
raise unless req.request_method == 'POST'
|
21
|
+
|
18
22
|
res.content_type = 'application/json'
|
19
23
|
res.body = JSON.generate(path: req.path,
|
20
24
|
headers: req.header,
|
@@ -29,19 +33,19 @@ RSpec.describe ThreadedProxy::Client do
|
|
29
33
|
@server_thread.kill
|
30
34
|
end
|
31
35
|
|
32
|
-
it
|
36
|
+
it 'proxies a GET request' do
|
33
37
|
socket = StringIO.new
|
34
38
|
|
35
|
-
client = ThreadedProxy::Client.new("http://localhost:#{
|
39
|
+
client = ThreadedProxy::Client.new("http://localhost:#{BACKEND_STUB_PORT}/get")
|
36
40
|
client.start(socket)
|
37
41
|
|
38
|
-
expect(socket.string).to include(
|
42
|
+
expect(socket.string).to include('Received request: /get')
|
39
43
|
end
|
40
44
|
|
41
|
-
it
|
45
|
+
it 'proxies a POST request with content-length' do
|
42
46
|
socket = StringIO.new
|
43
47
|
|
44
|
-
client = ThreadedProxy::Client.new("http://localhost:#{
|
48
|
+
client = ThreadedProxy::Client.new("http://localhost:#{BACKEND_STUB_PORT}/post",
|
45
49
|
method: 'post',
|
46
50
|
body: 'hello world')
|
47
51
|
client.start(socket)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-threaded-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Nutt
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: webrick
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +150,7 @@ executables:
|
|
136
150
|
- rdoc
|
137
151
|
- ri
|
138
152
|
- rspec
|
153
|
+
- rubocop
|
139
154
|
- semver
|
140
155
|
extensions: []
|
141
156
|
extra_rdoc_files:
|
@@ -143,6 +158,7 @@ extra_rdoc_files:
|
|
143
158
|
files:
|
144
159
|
- ".bundle/config"
|
145
160
|
- ".rspec"
|
161
|
+
- ".rubocop.yml"
|
146
162
|
- ".ruby-version"
|
147
163
|
- Gemfile
|
148
164
|
- Gemfile.lock
|
@@ -160,6 +176,7 @@ files:
|
|
160
176
|
- bin/rdoc
|
161
177
|
- bin/ri
|
162
178
|
- bin/rspec
|
179
|
+
- bin/rubocop
|
163
180
|
- bin/semver
|
164
181
|
- lib/rails-threaded-proxy.rb
|
165
182
|
- lib/threaded-proxy.rb
|