rack-singleshot 0.1.4 → 0.2.0

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.
Files changed (2) hide show
  1. data/lib/rack/singleshot.rb +37 -46
  2. metadata +99 -75
@@ -1,4 +1,5 @@
1
1
  require 'rack'
2
+ require 'http/parser'
2
3
 
3
4
  module Rack
4
5
  module Handler
@@ -31,70 +32,65 @@ module Rack
31
32
  end
32
33
 
33
34
  def read_request
34
- buffer, extra = drain(@stdin, CRLF * 2)
35
+ verb, path, version, headers, body = parse_request(@stdin)
35
36
 
36
- heading, buffer = buffer.split(CRLF, 2)
37
-
38
- verb, path, version = heading.split(' ')
37
+ env_for(verb, path, version, headers, body)
38
+ end
39
39
 
40
- headers = parse_headers(buffer)
40
+ def parse_request(socket, chunksize = 1024)
41
+ finished = false
42
+ body = StringIO.new('')
43
+ parser = Http::Parser.new
41
44
 
42
- if length = request_body_length(verb, headers)
43
- body = StringIO.new(extra + @stdin.read(length - extra.size))
44
- else
45
- body = StringIO.new(extra)
46
- end
45
+ body.set_encoding(Encoding::ASCII_8BIT) if body.respond_to?(:set_encoding)
47
46
 
48
- env_for(verb, path, version, headers, body)
49
- end
47
+ parser.on_message_complete = lambda { finished = true }
48
+ parser.on_body = lambda {|data| body << data }
50
49
 
51
- def write_response(status, headers, body)
52
- @stdout.write(['HTTP/1.1', status, Rack::Utils::HTTP_STATUS_CODES[status.to_i]].join(' ') << CRLF)
50
+ while(chunk = socket.readpartial(chunksize))
51
+ parser << chunk
53
52
 
54
- headers.each do |key, values|
55
- values.split("\n").each do |value|
56
- @stdout.write([key, value].join(": ") << CRLF)
57
- end
53
+ break if finished
58
54
  end
59
55
 
60
- @stdout.write(CRLF)
56
+ return request_parts_from(parser) << body
57
+ rescue EOFError
58
+ return request_parts_from(parser) << body
59
+ end
61
60
 
62
- body.each do |chunk|
63
- @stdout.write(chunk)
64
- end
61
+ def request_parts_from(parser)
62
+ [parser.http_method,
63
+ parser.request_path,
64
+ parser.http_version.join('.'),
65
+ parse_headers(parser.headers)]
65
66
  end
66
67
 
67
68
  def parse_headers(raw_headers)
68
- raw_headers.split(CRLF).inject({}) do |h, pair|
69
- key, value = pair.split(": ")
69
+ raw_headers.inject({}) do |h, (key,value)|
70
70
  h.update(header_key(key) => value)
71
71
  end
72
72
  end
73
73
 
74
- def request_body_length(verb, headers)
75
- return if %w[ POST PUT ].include?(verb.upcase)
74
+ def header_key(key)
75
+ key = key.upcase.gsub('-', '_')
76
76
 
77
- if length = headers['CONTENT_LENGTH']
78
- length.to_i
79
- end
77
+ %w[CONTENT_TYPE CONTENT_LENGTH SERVER_NAME].include?(key) ? key : "HTTP_#{key}"
80
78
  end
81
79
 
82
- def drain(socket, stop_at, chunksize = 1024)
83
- buffer = ''
80
+ def write_response(status, headers, body)
81
+ @stdout.write(['HTTP/1.1', status, Rack::Utils::HTTP_STATUS_CODES[status.to_i]].join(' ') << CRLF)
84
82
 
85
- while(chunk = socket.readpartial(chunksize))
86
- buffer << chunk
83
+ headers.each do |key, values|
84
+ values.split("\n").each do |value|
85
+ @stdout.write([key, value].join(": ") << CRLF)
86
+ end
87
+ end
87
88
 
88
- if buffer.include?(stop_at)
89
- buffer, extra = buffer.split(stop_at, 2)
89
+ @stdout.write(CRLF)
90
90
 
91
- return buffer, extra
92
- end
91
+ body.each do |chunk|
92
+ @stdout.write(chunk)
93
93
  end
94
-
95
- return buffer, ''
96
- rescue EOFError
97
- return buffer, ''
98
94
  end
99
95
 
100
96
  def env_for(verb, path, version, headers, body)
@@ -123,11 +119,6 @@ module Rack
123
119
  env
124
120
  end
125
121
 
126
- def header_key(key)
127
- key = key.upcase.gsub('-', '_')
128
-
129
- %w[CONTENT_TYPE CONTENT_LENGTH SERVER_NAME].include?(key) ? key : "HTTP_#{key}"
130
- end
131
122
  end
132
123
 
133
124
  register 'singleshot', 'Rack::Handler::SingleShot'
metadata CHANGED
@@ -1,120 +1,144 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rack-singleshot
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.4
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Ben Burkert
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-09-19 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2013-02-19 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
15
22
  name: rack
16
- requirement: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
17
25
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
22
33
  type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: http_parser.rb
23
37
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
38
+ requirement: &id002 !ruby/object:Gem::Requirement
25
39
  none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
30
- - !ruby/object:Gem::Dependency
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
31
50
  name: rspec
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: '0'
38
- type: :development
39
51
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
52
+ requirement: &id003 !ruby/object:Gem::Requirement
41
53
  none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
46
- - !ruby/object:Gem::Dependency
47
- name: rake
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
54
61
  type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
55
65
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
63
- name: sinatra
64
- requirement: !ruby/object:Gem::Requirement
66
+ requirement: &id004 !ruby/object:Gem::Requirement
65
67
  none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
70
75
  type: :development
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: sinatra
71
79
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
80
+ requirement: &id005 !ruby/object:Gem::Requirement
73
81
  none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
- description: ! 'Handles a single request to/from STDIN/STDOUT. Exits when the response
79
-
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :development
90
+ version_requirements: *id005
91
+ description: |
92
+ Handles a single request to/from STDIN/STDOUT. Exits when the response
80
93
  has finished. Sutable for running via inetd.
81
94
 
82
- '
83
- email:
95
+ email:
84
96
  - ben@benburkert.com
85
- executables:
97
+ executables:
86
98
  - singleshot
87
99
  extensions: []
100
+
88
101
  extra_rdoc_files: []
89
- files:
102
+
103
+ files:
90
104
  - ./lib/rack/singleshot.rb
91
105
  - ./spec/singleshot_spec.rb
92
106
  - ./spec/spec_helper.rb
93
107
  - bin/singleshot
108
+ has_rdoc: true
94
109
  homepage: http://github.com/benburkert/rack-singleshot
95
110
  licenses: []
111
+
96
112
  post_install_message:
97
113
  rdoc_options: []
98
- require_paths:
114
+
115
+ require_paths:
99
116
  - lib
100
- required_ruby_version: !ruby/object:Gem::Requirement
117
+ required_ruby_version: !ruby/object:Gem::Requirement
101
118
  none: false
102
- requirements:
103
- - - ! '>='
104
- - !ruby/object:Gem::Version
105
- version: '0'
106
- required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ hash: 3
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
127
  none: false
108
- requirements:
109
- - - ! '>='
110
- - !ruby/object:Gem::Version
111
- version: '0'
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ hash: 3
132
+ segments:
133
+ - 0
134
+ version: "0"
112
135
  requirements: []
136
+
113
137
  rubyforge_project:
114
- rubygems_version: 1.8.23
138
+ rubygems_version: 1.6.2
115
139
  signing_key:
116
140
  specification_version: 3
117
141
  summary: A single-shot rack handler.
118
- test_files:
142
+ test_files:
119
143
  - ./spec/singleshot_spec.rb
120
144
  - ./spec/spec_helper.rb