net-ptth 0.0.1

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 ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+ gem "rake"
data/Gemfile.lock ADDED
@@ -0,0 +1,30 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ net-ptth (0.0.1)
5
+ celluloid-io (~> 0.12.1)
6
+ http-parser-lite (~> 0.6.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ celluloid (0.12.4)
12
+ facter (>= 1.6.12)
13
+ timers (>= 1.0.0)
14
+ celluloid-io (0.12.1)
15
+ celluloid (~> 0.12.0)
16
+ nio4r (>= 0.4.0)
17
+ facter (1.6.17)
18
+ http-parser-lite (0.6.0)
19
+ minitest (4.4.0)
20
+ nio4r (0.4.3)
21
+ rake (10.0.3)
22
+ timers (1.0.2)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ minitest (~> 4.4.0)
29
+ net-ptth!
30
+ rake
data/HUGS ADDED
@@ -0,0 +1,15 @@
1
+ THE HUGWARE LICENSE
2
+
3
+ LICENSE
4
+
5
+ If there is no other license you can do whatever you want with this while you
6
+ retain the attribution to the author.
7
+
8
+ HUGS
9
+
10
+ The author spent time to make this software so please show some grattitude,
11
+ in any
12
+ form. A hug, a tweet, a beer on a conference or just a plain old email. Your
13
+ choice.
14
+
15
+ Less hate, more hugs.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Bruno Aguirre
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # Net::PTTH
2
+
3
+ `Net::HTTP` compatible `PTTH` client
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install net-ptth
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ require 'net/ptth'
15
+ require 'net/http'
16
+
17
+ ptth = Net::PTTH.new("http://localhost:23045")
18
+ request = Net::HTTP::Post.new("/reverse")
19
+ ptth.request(request) do |body, headers|
20
+ # Handle the body of the incomming request through the reverse connection
21
+ end
22
+ ```
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new("spec") do |t|
4
+ t.pattern = "test/**/*_test.rb"
5
+ end
6
+
7
+ task :default => [:test]
8
+ task :test => [:spec]
data/lib/net/ptth.rb ADDED
@@ -0,0 +1,129 @@
1
+ require "uri"
2
+ require "net/http"
3
+ require "http-parser"
4
+ require "celluloid/io"
5
+
6
+ class Net::PTTH
7
+ include Celluloid::IO
8
+
9
+ # Public: Constructor
10
+ #
11
+ # address: The address where the connection will be made
12
+ # port: An optional port if the port is different from the one in the
13
+ # address
14
+ #
15
+ def initialize(address, port = 80)
16
+ info = URI.parse(address)
17
+
18
+ @host, @port = info.host, info.port || port
19
+ @parser = HTTP::Parser.new
20
+ @debug_output = StringIO.new
21
+ end
22
+
23
+ # Public: Mimics Net::HTTP set_debug_output
24
+ #
25
+ # output: A StringIO compatible object
26
+ #
27
+ def set_debug_output=(output)
28
+ @debug_output = output
29
+ end
30
+
31
+ # Public: Closes de current connection
32
+ #
33
+ def close
34
+ log "[Closing connection]"
35
+ @socket.close if @socket
36
+ end
37
+
38
+ # Public: Generates a request based on a Net::HTTP object and yields a
39
+ # response
40
+ #
41
+ # req: The request to be executed
42
+ # &block: That will handle the response
43
+ #
44
+ def request(req, &block)
45
+ @socket ||= TCPSocket.new(@host, @port)
46
+
47
+ log "[Connecting...]"
48
+
49
+ packet = build(req)
50
+
51
+ log "[Writting packet]"
52
+ log packet
53
+
54
+ @socket.write(packet)
55
+
56
+ response = @socket.readpartial(1024)
57
+ log "[Reading response]"
58
+ log response
59
+ @parser << response
60
+
61
+ if @parser.http_status == 101
62
+ log "[Switching protocols]"
63
+
64
+ while res = @socket.readpartial(1024)
65
+ log "[Incoming response]"
66
+ log res
67
+
68
+ headers = {}
69
+ body = nil
70
+
71
+ @parser.reset
72
+ parse_headers(headers)
73
+
74
+ @parser.on_body { |response_body| body = response_body }
75
+ @parser.on_message_complete { block.call(body, headers) }
76
+
77
+ @parser << res
78
+ end
79
+ end
80
+ rescue IOError => e
81
+ rescue EOFError => e
82
+ @socket.close
83
+ end
84
+
85
+ private
86
+
87
+ # Private: Logs a debug message
88
+ #
89
+ # message: The string to be logged
90
+ #
91
+ def log(message)
92
+ @debug_output << message + "\n"
93
+ end
94
+
95
+ # Private: Parses the incoming request headers and adds the information to a
96
+ # given object
97
+ #
98
+ # headers: The object in which the headers will be added
99
+ #
100
+ def parse_headers(headers)
101
+ raw_headers = []
102
+ add_header = proc { |header| raw_headers << header }
103
+
104
+ @parser.on_header_field &add_header
105
+ @parser.on_header_value &add_header
106
+ @parser.on_headers_complete do
107
+ raw_headers.each_slice(2) do |key, value|
108
+ headers[key] = value
109
+ end
110
+ end
111
+ end
112
+
113
+ # Private: Builds a reversed request
114
+ #
115
+ # req: The request to be build
116
+ #
117
+ def build(req)
118
+ req["Upgrade"] ||= "PTTH/1.0"
119
+ req["Connection"] ||= "Upgrade"
120
+
121
+ package = "#{req.method} #{req.path} HTTP/1.1\n"
122
+ req.each_header do |header, value|
123
+ package += "#{header.split("-").map(&:capitalize).join("-")}: #{value}\n"
124
+ end
125
+
126
+ package += "\n\r#{req.body}"
127
+ package += "\n\r\n\r"
128
+ end
129
+ end
data/net-ptth.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "net-ptth"
3
+ s.version = "0.0.1"
4
+ s.summary = "Net::HTTP compatible reverse HTTP version"
5
+ s.description = "PTTH Ruby client. Net::HTTP compatible... kind of"
6
+ s.authors = ["elcuervo"]
7
+ s.email = ["yo@brunoaguirre.com"]
8
+ s.licenses = ["MIT", "HUGWARE"]
9
+ s.homepage = "http://github.com/elcuervo/net-ptth"
10
+ s.files = `git ls-files`.split("\n")
11
+ s.test_files = `git ls-files test`.split("\n")
12
+
13
+ s.add_dependency("celluloid-io", "~> 0.12.1")
14
+ s.add_dependency("http-parser-lite", "~> 0.6.0")
15
+
16
+ s.add_development_dependency("minitest", "~> 4.4.0")
17
+ end
data/test/ptth_test.rb ADDED
@@ -0,0 +1,47 @@
1
+ require_relative "./test_helper"
2
+ require "net/ptth"
3
+
4
+ describe "PTTH connection" do
5
+ before do
6
+ Thread.new do
7
+ @server = TCPServer.new(23045)
8
+
9
+ loop do
10
+ client = @server.accept
11
+
12
+ switch_protocols = <<-EOS.gsub(/^\s+/, '')
13
+ HTTP/1.1 101 Switching Protocols
14
+ Date: Mon, 14 Jan 2013 11:54:24 GMT
15
+ Upgrade: PTTH/1.0
16
+ Connection: Upgrade
17
+
18
+
19
+ EOS
20
+
21
+ post_response = "POST /reversed HTTP/1.1\n"
22
+ post_response += "Content-Length: 8\n"
23
+ post_response += "Accept: */*\n"
24
+ post_response += "\n"
25
+ post_response += "reversed"
26
+
27
+ client.puts switch_protocols
28
+ sleep 0.5
29
+ client.puts post_response
30
+ end
31
+ end
32
+ end
33
+
34
+ after do
35
+ @server.close
36
+ end
37
+
38
+ it "should stablish a reverse connection" do
39
+ ptth = Net::PTTH.new("http://localhost:23045")
40
+ request = Net::HTTP::Post.new("/reverse")
41
+
42
+ ptth.request(request) do |body|
43
+ assert_equal "reversed", body
44
+ ptth.close
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,8 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ require "bundler/setup"
4
+ require "minitest/spec"
5
+ require "minitest/pride"
6
+ require "minitest/autorun"
7
+ require "net/ptth"
8
+
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: net-ptth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - elcuervo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: celluloid-io
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.12.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.12.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: http-parser-lite
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.6.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.6.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 4.4.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 4.4.0
62
+ description: PTTH Ruby client. Net::HTTP compatible... kind of
63
+ email:
64
+ - yo@brunoaguirre.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - Gemfile
70
+ - Gemfile.lock
71
+ - HUGS
72
+ - LICENSE
73
+ - README.md
74
+ - Rakefile
75
+ - lib/net/ptth.rb
76
+ - net-ptth.gemspec
77
+ - test/ptth_test.rb
78
+ - test/test_helper.rb
79
+ homepage: http://github.com/elcuervo/net-ptth
80
+ licenses:
81
+ - MIT
82
+ - HUGWARE
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.23
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Net::HTTP compatible reverse HTTP version
105
+ test_files:
106
+ - test/ptth_test.rb
107
+ - test/test_helper.rb