net-ptth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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