cool.io-http 0.2.0 → 0.2.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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ *.rbc
data/CHANGES.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGES
2
2
 
3
+ ## cool.io-http 0.2.1 -- 2012-01-09
4
+
5
+ * Added SSL (HTTPS) supports
6
+ * Added Coolio::Http#ssl?
7
+
3
8
  ## cool.io-http 0.2.0 -- 2012-01-01
4
9
 
5
10
  * Birthday!
data/README.md CHANGED
@@ -29,7 +29,7 @@ Asynchrony client:
29
29
 
30
30
  require 'cool.io/http'
31
31
 
32
- Coolio::Http.request(:url => 'http://example.com'){ |response, headers|
32
+ Coolio::Http.request(:url => 'https://google.com'){ |response, headers|
33
33
  puts "Response: #{response}"
34
34
  puts
35
35
  puts " Headers: #{headers}"
@@ -42,7 +42,7 @@ Fiber-aware synchrony client:
42
42
  require 'cool.io/http'
43
43
 
44
44
  Fiber.new{
45
- Coolio::HttpFiber.request(:url => 'http://example.com'){ |r, h|
45
+ Coolio::HttpFiber.request(:url => 'https://google.com'){ |r, h|
46
46
  puts "Response: #{r}"
47
47
  puts
48
48
  puts " Headers: #{h}"
data/TODO.md CHANGED
@@ -1,3 +1,4 @@
1
1
  # TODO
2
2
 
3
3
  * streaming payload body
4
+ * ssl options (e.g. OpenSSL::SSL::VERIFY_NONE)
data/cool.io-http.gemspec CHANGED
@@ -2,14 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "cool.io-http"
5
- s.version = "0.2.0"
5
+ s.version = "0.2.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Lin Jen-Shin (godfat)"]
9
- s.date = "2012-01-01"
9
+ s.date = "2012-01-09"
10
10
  s.description = "Simpler HTTP for [cool.io][]\n\n[cool.io]: https://github.com/tarcieri/cool.io"
11
11
  s.email = ["godfat (XD) godfat.org"]
12
12
  s.files = [
13
+ ".gitignore",
13
14
  ".gitmodules",
14
15
  "CHANGES.md",
15
16
  "LICENSE",
@@ -21,6 +22,7 @@ Gem::Specification.new do |s|
21
22
  "lib/cool.io-http/version.rb",
22
23
  "lib/cool.io/http.rb",
23
24
  "lib/cool.io/http/payload.rb",
25
+ "lib/cool.io/http/ssl.rb",
24
26
  "lib/cool.io/http_fiber.rb",
25
27
  "task/.git",
26
28
  "task/.gitignore",
@@ -28,7 +30,7 @@ Gem::Specification.new do |s|
28
30
  "test/test_http.rb"]
29
31
  s.homepage = "https://github.com/godfat/cool.io-http"
30
32
  s.require_paths = ["lib"]
31
- s.rubygems_version = "1.8.13"
33
+ s.rubygems_version = "1.8.15"
32
34
  s.summary = "Simpler HTTP for [cool.io][]"
33
35
  s.test_files = ["test/test_http.rb"]
34
36
 
@@ -0,0 +1,105 @@
1
+
2
+ module Coolio
3
+ module SSL
4
+ def ssl?
5
+ true
6
+ end
7
+
8
+ def ssl_socket
9
+ @ssl_scoket ||= begin
10
+ s = OpenSSL::SSL::SSLSocket.new(@_io, ssl_context)
11
+ s.sync_close = true
12
+ s
13
+ end
14
+ end
15
+
16
+ def ssl_context
17
+ @ssl_context ||= begin
18
+ c = OpenSSL::SSL::SSLContext.new
19
+ # c.verify_mode = OpenSSL::SSL::VERIFY_NONE
20
+ c
21
+ end
22
+ end
23
+
24
+ def ssl_completed?
25
+ !!!@ssl_method
26
+ end
27
+
28
+ def ssl_client_start
29
+ @ssl_method = :connect_nonblock
30
+ ssl_init
31
+ end
32
+
33
+ def ssl_server_start
34
+ @ssl_method = :accept_nonblock
35
+ ssl_init
36
+ end
37
+
38
+ #########
39
+ protected
40
+ #########
41
+
42
+ def ssl_init
43
+ ssl_socket.__send__(@ssl_method)
44
+ ssl_init_complete
45
+ rescue ::IO::WaitReadable
46
+ enable unless enabled?
47
+ rescue ::IO::WaitWritable
48
+ enable_write_watcher
49
+ rescue Errno::ECONNRESET, Errno::EPIPE
50
+ close
51
+ rescue => e
52
+ if respond_to?(:on_ssl_error)
53
+ on_ssl_error(e)
54
+ else
55
+ raise e
56
+ end
57
+ end
58
+
59
+ def ssl_init_complete
60
+ @ssl_method = nil
61
+ enable unless enabled?
62
+ on_peer_cert(ssl_socket.peer_cert) if respond_to?(:on_peer_cert)
63
+ on_ssl_connect if respond_to?(:on_ssl_connect)
64
+ end
65
+
66
+ def on_readable
67
+ unless ssl_completed?
68
+ disable
69
+ ssl_init
70
+ return
71
+ end
72
+
73
+ begin
74
+ on_read(ssl_socket.read_nonblock(Coolio::IO::INPUT_SIZE))
75
+ rescue Errno::EAGAIN, ::IO::WaitReadable
76
+ rescue Errno::ECONNRESET, EOFError
77
+ close
78
+ end
79
+ end
80
+
81
+ def on_writable
82
+ unless ssl_completed?
83
+ # disable_write_watcher
84
+ ssl_init
85
+ return
86
+ end
87
+
88
+ begin
89
+ nbytes = ssl_socket.write_nonblock(@_write_buffer.to_str)
90
+ rescue Errno::EAGAIN, ::IO::WaitWritable
91
+ return
92
+ rescue Errno::EPIPE, Errno::ECONNRESET
93
+ close
94
+ return
95
+ end
96
+
97
+ @_write_buffer.read(nbytes)
98
+
99
+ if @_write_buffer.empty?
100
+ disable_write_watcher
101
+ on_write_complete
102
+ end
103
+ end
104
+ end
105
+ end
data/lib/cool.io/http.rb CHANGED
@@ -2,9 +2,11 @@
2
2
  require 'uri'
3
3
  require 'cool.io'
4
4
  require 'cool.io/http/payload'
5
+ require 'cool.io/http/ssl'
5
6
 
6
7
  module Coolio
7
8
  autoload :HttpFiber, 'cool.io/http_fiber'
9
+ autoload :SSL , 'cool.io/http/ssl'
8
10
  end
9
11
 
10
12
  class Coolio::Http < Coolio::HttpClient
@@ -24,12 +26,22 @@ class Coolio::Http < Coolio::HttpClient
24
26
  r}.merge(query.inject({}){ |r, (k, v)| r[k.to_s] = v.to_s; r })
25
27
  p = Payload.generate(payload)
26
28
 
27
- connect(uri.host, uri.port).attach(loop).
29
+ connect(uri.host, uri.port, uri.scheme.downcase == 'https').attach(loop).
28
30
  request(method.to_s.upcase, path, :query => q,
29
31
  :head => p.headers.merge(headers),
30
32
  :body => p.read, &block)
31
33
  end
32
34
 
35
+ def self.connect host, port, ssl
36
+ http = super(host, port)
37
+ http.extend(Coolio::SSL) if ssl
38
+ http
39
+ end
40
+
41
+ def ssl?
42
+ false
43
+ end
44
+
33
45
  def initialize socket
34
46
  super
35
47
  @http_data = []
@@ -52,4 +64,9 @@ class Coolio::Http < Coolio::HttpClient
52
64
  super
53
65
  @http_callback.call(@http_data.join, @http_response_header)
54
66
  end
67
+
68
+ def on_connect
69
+ ssl_client_start if respond_to?(:ssl_socket)
70
+ super
71
+ end
55
72
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module CoolioHttp
3
- VERSION = '0.2.0'
3
+ VERSION = '0.2.1'
4
4
  end
data/test/test_http.rb CHANGED
@@ -1,21 +1,32 @@
1
1
 
2
2
  require 'cool.io/http'
3
3
 
4
- def request klass
5
- klass.request(:url => 'http://example.com'){ |response, headers|
4
+ def request klass, url
5
+ klass.request(:url => url){ |response, headers|
6
6
  puts "Response: #{response}"
7
7
  puts
8
8
  puts " Headers: #{headers}"
9
9
  }
10
10
  end
11
11
 
12
- request(Coolio::Http)
12
+ request(Coolio::Http, 'http://google.com')
13
13
  Coolio::Loop.default.run
14
14
  puts
15
15
 
16
16
  Fiber.new{
17
- request(Coolio::HttpFiber)
17
+ request(Coolio::HttpFiber, 'https://google.com')
18
18
  puts "DONE"
19
19
  }.resume
20
20
  puts "GO"
21
21
  Coolio::Loop.default.run
22
+
23
+ describe 'ssl' do
24
+ should 'respect ssl?' do
25
+ port = rand(30000) + 1024
26
+ serv = TCPServer.new('localhost', port)
27
+ sock = TCPSocket.new('localhost', port)
28
+ Coolio::Http.new(sock) .ssl?.should == false
29
+ Coolio::Http.new(sock).extend(Coolio::SSL).ssl?.should == true
30
+ serv.close
31
+ end
32
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cool.io-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-01 00:00:00.000000000 Z
12
+ date: 2012-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cool.io
16
- requirement: &2168638220 !ruby/object:Gem::Requirement
16
+ requirement: &2153258440 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2168638220
24
+ version_requirements: *2153258440
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mime-types
27
- requirement: &2168637040 !ruby/object:Gem::Requirement
27
+ requirement: &2153274020 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2168637040
35
+ version_requirements: *2153274020
36
36
  description: ! 'Simpler HTTP for [cool.io][]
37
37
 
38
38
 
@@ -43,6 +43,7 @@ executables: []
43
43
  extensions: []
44
44
  extra_rdoc_files: []
45
45
  files:
46
+ - .gitignore
46
47
  - .gitmodules
47
48
  - CHANGES.md
48
49
  - LICENSE
@@ -54,6 +55,7 @@ files:
54
55
  - lib/cool.io-http/version.rb
55
56
  - lib/cool.io/http.rb
56
57
  - lib/cool.io/http/payload.rb
58
+ - lib/cool.io/http/ssl.rb
57
59
  - lib/cool.io/http_fiber.rb
58
60
  - task/.git
59
61
  - task/.gitignore
@@ -79,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
81
  version: '0'
80
82
  requirements: []
81
83
  rubyforge_project:
82
- rubygems_version: 1.8.13
84
+ rubygems_version: 1.8.15
83
85
  signing_key:
84
86
  specification_version: 3
85
87
  summary: Simpler HTTP for [cool.io][]