net-ptth 0.0.2 → 0.0.3
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.
- data/Gemfile +4 -0
- data/Gemfile.lock +21 -1
- data/README.md +27 -1
- data/lib/net/ptth.rb +72 -25
- data/net-ptth.gemspec +3 -1
- data/test/ptth_test.rb +59 -0
- metadata +34 -2
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
net-ptth (0.0.
|
4
|
+
net-ptth (0.0.3)
|
5
5
|
celluloid-io (~> 0.12.1)
|
6
6
|
http-parser-lite (~> 0.6.0)
|
7
7
|
rack (~> 1.4.4)
|
@@ -15,18 +15,38 @@ GEM
|
|
15
15
|
celluloid-io (0.12.1)
|
16
16
|
celluloid (~> 0.12.0)
|
17
17
|
nio4r (>= 0.4.0)
|
18
|
+
columnize (0.3.6)
|
19
|
+
cuba (3.1.0)
|
20
|
+
rack
|
21
|
+
debugger (1.2.0)
|
22
|
+
columnize (>= 0.3.1)
|
23
|
+
debugger-linecache (~> 1.1.1)
|
24
|
+
debugger-ruby_core_source (~> 1.1.3)
|
25
|
+
debugger-linecache (1.1.2)
|
26
|
+
debugger-ruby_core_source (>= 1.1.1)
|
27
|
+
debugger-ruby_core_source (1.1.3)
|
18
28
|
facter (1.6.17)
|
19
29
|
http-parser-lite (0.6.0)
|
20
30
|
minitest (4.4.0)
|
21
31
|
nio4r (0.4.3)
|
22
32
|
rack (1.4.4)
|
33
|
+
rack-protection (1.2.0)
|
34
|
+
rack
|
23
35
|
rake (10.0.3)
|
36
|
+
sinatra (1.3.3)
|
37
|
+
rack (~> 1.3, >= 1.3.6)
|
38
|
+
rack-protection (~> 1.2)
|
39
|
+
tilt (~> 1.3, >= 1.3.3)
|
40
|
+
tilt (1.3.3)
|
24
41
|
timers (1.0.2)
|
25
42
|
|
26
43
|
PLATFORMS
|
27
44
|
ruby
|
28
45
|
|
29
46
|
DEPENDENCIES
|
47
|
+
cuba (~> 3.1.0)
|
48
|
+
debugger
|
30
49
|
minitest (~> 4.4.0)
|
31
50
|
net-ptth!
|
32
51
|
rake
|
52
|
+
sinatra (~> 1.3.3)
|
data/README.md
CHANGED
@@ -9,7 +9,7 @@ No I don't: http://wiki.secondlife.com/wiki/Reverse_HTTP
|
|
9
9
|
## Installation
|
10
10
|
|
11
11
|
```bash
|
12
|
-
|
12
|
+
gem install net-ptth
|
13
13
|
```
|
14
14
|
|
15
15
|
## Usage
|
@@ -28,3 +28,29 @@ ptth.request(request) do |incomming_request|
|
|
28
28
|
# ptth.close
|
29
29
|
end
|
30
30
|
```
|
31
|
+
|
32
|
+
## Rack compatiblity
|
33
|
+
|
34
|
+
_Remember that letting an app handle the responses it's also in charge of
|
35
|
+
closing the reverse connection if needed_
|
36
|
+
|
37
|
+
An app can be defined to be mounted like rackup will. So you can do things like
|
38
|
+
this:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
require 'net/ptth'
|
42
|
+
require 'net/http'
|
43
|
+
|
44
|
+
ptth = Net::PTTH.new("http://localhost:23045")
|
45
|
+
ptth.app = Cuba.define do
|
46
|
+
on "dog" do
|
47
|
+
res.write "Hello? this is dog"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
request = Net::HTTP::Post.new("/reverse")
|
52
|
+
ptth.request(request)
|
53
|
+
```
|
54
|
+
|
55
|
+
And let the app handle the responses of the reverse connection.
|
56
|
+
Both Cuba and sinatra were tested
|
data/lib/net/ptth.rb
CHANGED
@@ -5,8 +5,18 @@ require "http-parser"
|
|
5
5
|
require "celluloid/io"
|
6
6
|
|
7
7
|
class Net::PTTH
|
8
|
+
class Request
|
9
|
+
attr_accessor :path, :body, :headers
|
10
|
+
|
11
|
+
def initialize(path = "", body = "", headers = {})
|
12
|
+
@path, @body, @headers = path, body, headers
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
8
16
|
include Celluloid::IO
|
9
17
|
|
18
|
+
attr_accessor :app
|
19
|
+
|
10
20
|
# Public: Constructor
|
11
21
|
#
|
12
22
|
# address: The address where the connection will be made
|
@@ -66,32 +76,12 @@ class Net::PTTH
|
|
66
76
|
log "[Incoming response]"
|
67
77
|
log res
|
68
78
|
|
69
|
-
|
70
|
-
|
71
|
-
body = ""
|
72
|
-
|
73
|
-
@parser.reset
|
74
|
-
parse_headers(headers)
|
79
|
+
request = Request.new
|
80
|
+
build_request(request)
|
75
81
|
|
76
|
-
@parser.on_url { |url| path = url }
|
77
|
-
@parser.on_body { |response_body| body = StringIO.new(response_body) }
|
78
82
|
@parser.on_message_complete do
|
79
|
-
env =
|
80
|
-
|
81
|
-
"rack.input" => body,
|
82
|
-
"REQUEST_METHOD" => @parser.http_method,
|
83
|
-
}
|
84
|
-
|
85
|
-
env.tap do |h|
|
86
|
-
h["CONTENT_LENGTH"] = body.length if body
|
87
|
-
end
|
88
|
-
|
89
|
-
request = Rack::Request.new(env)
|
90
|
-
headers.each do |header, value|
|
91
|
-
request[header] = value
|
92
|
-
end
|
93
|
-
|
94
|
-
block.call(request)
|
83
|
+
env = build_env(request)
|
84
|
+
callbacks(env, &block)
|
95
85
|
end
|
96
86
|
|
97
87
|
@parser << res
|
@@ -104,6 +94,57 @@ class Net::PTTH
|
|
104
94
|
|
105
95
|
private
|
106
96
|
|
97
|
+
# Private: Executes the app and/or block callbacks
|
98
|
+
#
|
99
|
+
# env: The Rack compatible env
|
100
|
+
# &block: From the request
|
101
|
+
#
|
102
|
+
def callbacks(env, &block)
|
103
|
+
case
|
104
|
+
when app then app.call(env)
|
105
|
+
when block
|
106
|
+
request = Rack::Request.new(env)
|
107
|
+
block.call(request)
|
108
|
+
else
|
109
|
+
close
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Private: Builds a Rack compatible env from a PTTH::Request
|
114
|
+
#
|
115
|
+
# request: A PTTH parsed request
|
116
|
+
#
|
117
|
+
def build_env(request)
|
118
|
+
env = {
|
119
|
+
"PATH_INFO" => request.path,
|
120
|
+
"SCRIPT_NAME" => "",
|
121
|
+
"rack.input" => request.body,
|
122
|
+
"REQUEST_METHOD" => @parser.http_method,
|
123
|
+
}
|
124
|
+
|
125
|
+
env.tap do |h|
|
126
|
+
h["CONTENT_LENGTH"] = request.body.length if request.body
|
127
|
+
end
|
128
|
+
|
129
|
+
env.merge!(request.headers) if request.headers
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# Private: Builds a PTTH::Request from the parsed input
|
134
|
+
#
|
135
|
+
# request: The object where the parsed content will be placed
|
136
|
+
#
|
137
|
+
def build_request(request)
|
138
|
+
@parser.reset
|
139
|
+
parse_headers(request.headers)
|
140
|
+
|
141
|
+
@parser.on_url { |url| request.path = url }
|
142
|
+
@parser.on_body do |response_body|
|
143
|
+
request.body = StringIO.new(response_body)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
107
148
|
# Private: Logs a debug message
|
108
149
|
#
|
109
150
|
# message: The string to be logged
|
@@ -125,7 +166,13 @@ class Net::PTTH
|
|
125
166
|
@parser.on_header_value &add_header
|
126
167
|
@parser.on_headers_complete do
|
127
168
|
raw_headers.each_slice(2) do |key, value|
|
128
|
-
|
169
|
+
header_name = key.
|
170
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
171
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
172
|
+
tr("-", "_").
|
173
|
+
upcase
|
174
|
+
|
175
|
+
headers["HTTP_" + header_name] = value
|
129
176
|
end
|
130
177
|
end
|
131
178
|
end
|
data/net-ptth.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "net-ptth"
|
3
|
-
s.version = "0.0.
|
3
|
+
s.version = "0.0.3"
|
4
4
|
s.summary = "Net::HTTP compatible reverse HTTP version"
|
5
5
|
s.description = "PTTH Ruby client. Net::HTTP compatible... kind of"
|
6
6
|
s.authors = ["elcuervo"]
|
@@ -15,4 +15,6 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_dependency("http-parser-lite", "~> 0.6.0")
|
16
16
|
|
17
17
|
s.add_development_dependency("minitest", "~> 4.4.0")
|
18
|
+
s.add_development_dependency("cuba", "~> 3.1.0")
|
19
|
+
s.add_development_dependency("sinatra", "~> 1.3.3")
|
18
20
|
end
|
data/test/ptth_test.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require_relative "./test_helper"
|
2
|
+
require "cuba"
|
3
|
+
require "sinatra/base"
|
2
4
|
require "net/ptth"
|
3
5
|
require "net/ptth/test"
|
4
6
|
|
@@ -23,6 +25,63 @@ describe "PTTH connection" do
|
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
28
|
+
describe "Using a Rack compatible app to receive requests" do
|
29
|
+
before do
|
30
|
+
response = Net::HTTP::Get.new("/custom_app")
|
31
|
+
|
32
|
+
@server = Net::PTTH::TestServer.new(port: 23045, response: response)
|
33
|
+
@ptth = Net::PTTH.new("http://localhost:23045")
|
34
|
+
@request = Net::HTTP::Post.new("/reverse")
|
35
|
+
|
36
|
+
Thread.new { @server.start }
|
37
|
+
end
|
38
|
+
|
39
|
+
after do
|
40
|
+
@server.close
|
41
|
+
end
|
42
|
+
|
43
|
+
def check_app_compatibility(app)
|
44
|
+
app.ptth = @ptth
|
45
|
+
@ptth.app = app
|
46
|
+
|
47
|
+
timeout(1) { @ptth.request(@request) }
|
48
|
+
rescue Timeout::Error
|
49
|
+
flunk("The reverse connection was not closed")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be able to receive a Cuba app" do
|
53
|
+
CubaApp = Class.new(Cuba) do
|
54
|
+
class << self
|
55
|
+
attr_accessor :ptth
|
56
|
+
end
|
57
|
+
|
58
|
+
define do
|
59
|
+
on "custom_app" do
|
60
|
+
res.write "indeeed!"
|
61
|
+
self.class.ptth.close
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
check_app_compatibility(CubaApp)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should be able to receive a sinatra app" do
|
70
|
+
SinatraApp = Sinatra.new do
|
71
|
+
class << self
|
72
|
+
attr_accessor :ptth
|
73
|
+
end
|
74
|
+
|
75
|
+
get "/custom_app" do
|
76
|
+
self.class.ptth.close
|
77
|
+
"indeeed!"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
check_app_compatibility(SinatraApp)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
26
85
|
describe "PTTH Test server" do
|
27
86
|
before do
|
28
87
|
response = Net::HTTP::Get.new("/other")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ptth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -75,6 +75,38 @@ dependencies:
|
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: 4.4.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: cuba
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 3.1.0
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 3.1.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: sinatra
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.3.3
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.3.3
|
78
110
|
description: PTTH Ruby client. Net::HTTP compatible... kind of
|
79
111
|
email:
|
80
112
|
- yo@brunoaguirre.com
|