ruby-ajp 0.1.5 → 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.
- data/Rakefile +1 -1
- data/example/dump-server.rb +2 -2
- data/lib/net/ajp13/ajp13cgi.rb +187 -0
- data/lib/net/{ajp13client.rb → ajp13/client.rb} +0 -0
- data/lib/net/{ajp13server.rb → ajp13/server.rb} +25 -19
- data/lib/net/ajp13.rb +8 -8
- data/ruby-ajp.gemspec +2 -3
- data/test/net/test_ajp13cgi.rb +104 -0
- data/test/net/test_ajp13client.rb +1 -1
- data/test/net/test_ajp13request.rb +2 -2
- data/test/net/test_ajp13server.rb +2 -2
- metadata +7 -4
data/Rakefile
CHANGED
data/example/dump-server.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
|
-
require 'net/
|
2
|
+
require 'net/ajp13/server'
|
3
3
|
require 'erb'
|
4
4
|
|
5
5
|
class DumpServer < Net::AJP13::Server
|
@@ -58,7 +58,7 @@ __END__
|
|
58
58
|
<% if req.body_stream %>
|
59
59
|
<% body = req.body_stream.read %>
|
60
60
|
<% if %r(\Atext/) =~ req['content-type'] or
|
61
|
-
req['content-type'] == 'application/x-form-
|
61
|
+
req['content-type'] == 'application/x-www-form-urlencoded' %>
|
62
62
|
<pre><%=h body %></pre>
|
63
63
|
<% else %>
|
64
64
|
<pre><%=[body].pack('m')%></pre>
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'net/ajp13'
|
2
|
+
require 'cgi'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
# The adapter to adapt Net::AJP13::Request and Net::AJP13::Response into
|
6
|
+
# CGI's interface.
|
7
|
+
class Net::AJP13::AJP13CGI
|
8
|
+
include ::CGI::QueryExtension
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def initialize(req)
|
12
|
+
@req = req
|
13
|
+
if req.method == "POST" and
|
14
|
+
%r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(req['content-type']) then
|
15
|
+
boundary = $1.dup
|
16
|
+
@multipart = true
|
17
|
+
@params = read_multipart(boundary, req.content_length)
|
18
|
+
elsif req.body_stream and
|
19
|
+
req['content-type'] == 'application/x-www-form-urlencoded'
|
20
|
+
@multipart = false
|
21
|
+
@params = CGI::parse(req.body = req.body_stream.read)
|
22
|
+
req.body_stream = nil
|
23
|
+
elsif qs = query_string
|
24
|
+
@multipart = false
|
25
|
+
@params = CGI::parse(qs)
|
26
|
+
else
|
27
|
+
@multipart = false
|
28
|
+
@params = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
@env_table = self.method(:env)
|
32
|
+
class << @env_table
|
33
|
+
def include?(key)
|
34
|
+
call(key).nil?
|
35
|
+
end
|
36
|
+
alias :key? :include?
|
37
|
+
end
|
38
|
+
@cookies = CGI::Cookie::parse(req['cookie'])
|
39
|
+
end
|
40
|
+
|
41
|
+
# Created AJP13::Response object.
|
42
|
+
attr_reader :response
|
43
|
+
|
44
|
+
MESSAGE_TO_STATUS = {
|
45
|
+
:OK => [200, "OK"],
|
46
|
+
:PARTIAL_CONTENT => [206, "Partial Content"],
|
47
|
+
:MULTIPLE_CHOICES => [300, "Multiple Choices"],
|
48
|
+
:MOVED => [301, "Moved Permanently"],
|
49
|
+
:REDIRECT => [302, "Found"],
|
50
|
+
:NOT_MODIFIED => [304, "Not Modified"],
|
51
|
+
:BAD_REQUEST => [400, "Bad Request"],
|
52
|
+
:AUTH_REQUIRED => [401, "Authorization Required"],
|
53
|
+
:FORBIDDEN => [403, "Forbidden"],
|
54
|
+
:NOT_FOUND => [404, "Not Found"],
|
55
|
+
:METHOD_NOT_ALLOWED => [405, "Method Not Allowed"],
|
56
|
+
:NOT_ACCEPTABLE => [406, "Not Acceptable"],
|
57
|
+
:LENGTH_REQUIRED => [411, "Length Required"],
|
58
|
+
:PRECONDITION_FAILED => [412, "Rrecondition Failed"],
|
59
|
+
:SERVER_ERROR => [500, "Internal Server Error"],
|
60
|
+
:NOT_IMPLEMENTED => [501, "Method Not Implemented"],
|
61
|
+
:BAD_GATEWAY => [502, "Bad Gateway"],
|
62
|
+
:VARIANT_ALSO_VARIES => [506, "Variant Also Negotiates"],
|
63
|
+
}.freeze
|
64
|
+
|
65
|
+
def header(arg = "text/html")
|
66
|
+
if arg.kind_of? String
|
67
|
+
@response = Net::AJP13::Response.new(200)
|
68
|
+
@response['content-type'] = arg
|
69
|
+
elsif arg.respond_to?(:each) and arg.respond_to?(:[])
|
70
|
+
if status = arg['status']
|
71
|
+
raise ArgumentError, "Unrecognized status line format: #{status}" unless /\A(?:([0-9]{3}) )?(\w+)\Z/ =~ status
|
72
|
+
status_line = $1 ? [$1.to_i, $2] : MESSAGE_TO_STATUS[$2.to_sym]
|
73
|
+
raise ArgumentError, "Unrecognized status line: #{status}" unless status_line
|
74
|
+
@response = Net::AJP13::Response.new(status_line[0], :reason_phrase => status_line[1])
|
75
|
+
else
|
76
|
+
@response = Net::AJP13::Response.new(200)
|
77
|
+
end
|
78
|
+
type = nil; charset = nil
|
79
|
+
arg.each do |name, value|
|
80
|
+
case name.downcase
|
81
|
+
when 'nph', 'status'
|
82
|
+
# do nothing
|
83
|
+
when "type"
|
84
|
+
type = value
|
85
|
+
when "charset"
|
86
|
+
charset = value
|
87
|
+
when 'length'
|
88
|
+
@response['content-length'] = value.to_s
|
89
|
+
when 'language'
|
90
|
+
@response['content-language'] = value
|
91
|
+
when 'cookie'
|
92
|
+
case value
|
93
|
+
when String
|
94
|
+
@respose.add_header('set-cookie', value)
|
95
|
+
when Array, Hash
|
96
|
+
value.each {|val| @response.add_header('set-cookie', val.to_s) }
|
97
|
+
end
|
98
|
+
else
|
99
|
+
@response[name] = value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
type = 'text/html' unless type
|
103
|
+
@response['content-type'] = charset ? ("%s; charset=%s" % [type, charset]) : type
|
104
|
+
else
|
105
|
+
raise ArgumentError, "argument is not a String nor Hash"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def output(arg = 'text/html')
|
111
|
+
content = yield
|
112
|
+
header(arg)
|
113
|
+
@response['content-length'] ||= content.length
|
114
|
+
unless content.nil? or @request.method == 'HEAD'
|
115
|
+
@response.body = content
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Method object that contains #env
|
120
|
+
attr_reader :env_table
|
121
|
+
|
122
|
+
# Simulates environment variable table that Common Gateway Interface defines.
|
123
|
+
def env(name)
|
124
|
+
name = name.downcase
|
125
|
+
key = name.to_sym
|
126
|
+
if [
|
127
|
+
:auth_type, :content_length, :content_type, :gateway_interface,
|
128
|
+
:path_info, :path_translated, :query_string, :remote_addr, :remote_host,
|
129
|
+
:remote_ident, :remote_user, :request_method, :request_url, :script_name,
|
130
|
+
:server_name, :server_port, :server_protocol, :server_software
|
131
|
+
].include?(key) then
|
132
|
+
return __send__(key)
|
133
|
+
elsif /\Ahttp_(\w+)\Z/ =~ name
|
134
|
+
return @req[$1.tr('_', '-')]
|
135
|
+
else
|
136
|
+
return nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
private :env
|
140
|
+
|
141
|
+
def_delegators :@req,
|
142
|
+
:content_length, :remote_addr, :remote_host, :server_name, :server_port
|
143
|
+
|
144
|
+
[
|
145
|
+
:auth_type,
|
146
|
+
# :path_info,
|
147
|
+
:path_translated,
|
148
|
+
:remote_ident, :remote_user,
|
149
|
+
:script_name, :server_software
|
150
|
+
].each do |attr_name|
|
151
|
+
define_method(attr_name) do
|
152
|
+
val = @req.get_attributes(attr_name.to_s)
|
153
|
+
val and val[0]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def content_type
|
158
|
+
@req['content-type']
|
159
|
+
end
|
160
|
+
|
161
|
+
def gateway_interface
|
162
|
+
'AJP/1.3'
|
163
|
+
end
|
164
|
+
|
165
|
+
def path_info
|
166
|
+
#val = @req.get_attributes('path_info')
|
167
|
+
#val && val[0] or @req.path
|
168
|
+
@req.path
|
169
|
+
end
|
170
|
+
|
171
|
+
def query_string
|
172
|
+
qs = @req.get_attributes('query_string')
|
173
|
+
qs and qs.join('&')
|
174
|
+
end
|
175
|
+
|
176
|
+
def request_method
|
177
|
+
@req.method
|
178
|
+
end
|
179
|
+
|
180
|
+
def request_url
|
181
|
+
@req.path
|
182
|
+
end
|
183
|
+
|
184
|
+
def server_protocol
|
185
|
+
@req.protocol
|
186
|
+
end
|
187
|
+
end
|
File without changes
|
@@ -83,7 +83,6 @@ class Net::AJP13::Server
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def start(sock = nil)
|
86
|
-
logger.info("Starting #{self.class}")
|
87
86
|
if sock
|
88
87
|
@sock = sock
|
89
88
|
else
|
@@ -96,13 +95,12 @@ class Net::AJP13::Server
|
|
96
95
|
accepted = @sock.accept
|
97
96
|
Thread.new {
|
98
97
|
begin
|
99
|
-
|
100
|
-
|
101
|
-
end
|
98
|
+
accepted.sync = false
|
99
|
+
process(accepted)
|
102
100
|
rescue StandardError => err
|
103
|
-
logger.error("#{err.message} from #{err.backtrace("\n")}")
|
101
|
+
logger.error("#{err.message} from #{err.backtrace.join("\n")}")
|
104
102
|
rescue Object => err
|
105
|
-
logger.fatal("#{err.message} from #{err.backtrace("\n")}")
|
103
|
+
logger.fatal("#{err.message} from #{err.backtrace.join("\n")}")
|
106
104
|
else
|
107
105
|
logger.debug("closed")
|
108
106
|
ensure
|
@@ -133,18 +131,23 @@ class Net::AJP13::Server
|
|
133
131
|
|
134
132
|
# +conn+:: Accepted connection. +conn+ is an IO object or something like it.
|
135
133
|
def process(conn)
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
134
|
+
loop do
|
135
|
+
break unless c = conn.getc
|
136
|
+
conn.ungetc c
|
137
|
+
|
138
|
+
packet = Net::AJP13::Packet.from_io(conn)
|
139
|
+
case packet.message_type
|
140
|
+
when FORWARD_REQUEST
|
141
|
+
process_forward_request(packet, conn)
|
142
|
+
when SHUTDOWN
|
143
|
+
process_shutdown(packet, conn)
|
144
|
+
when PING
|
145
|
+
process_ping(packet, conn)
|
146
|
+
when CPING
|
147
|
+
process_cping(packet, conn)
|
148
|
+
else
|
149
|
+
raise AJPPacketError, "Unrecognized packet type #{packet.message_type}"
|
150
|
+
end
|
148
151
|
end
|
149
152
|
end
|
150
153
|
|
@@ -178,6 +181,7 @@ class Net::AJP13::Server
|
|
178
181
|
conn.write "\x41\x42#{[message.length + 4].pack('n')}\x03#{[message.length].pack('n')}#{message}\x00"
|
179
182
|
else
|
180
183
|
# SEND_HEADERS packet
|
184
|
+
res ||= Net::AJP13::Response.new(500)
|
181
185
|
res['content-length'] ||= res.body.length.to_s if res.body
|
182
186
|
res.send_to conn
|
183
187
|
|
@@ -241,6 +245,7 @@ class Net::AJP13::Server
|
|
241
245
|
@sock = sock
|
242
246
|
@packet = Net::AJP13::Packet.from_io(sock)
|
243
247
|
@length = length
|
248
|
+
packet_content_length = @packet.read_integer
|
244
249
|
@read_length = 0
|
245
250
|
end
|
246
251
|
|
@@ -346,7 +351,8 @@ class Net::AJP13::Server
|
|
346
351
|
# this means eof
|
347
352
|
break
|
348
353
|
else
|
349
|
-
|
354
|
+
packet_content_length = @packet.read_integer
|
355
|
+
chunk = @packet.read_bytes([length - written_length, packet_content_length].min)
|
350
356
|
buf[written_length, chunk.length] = chunk
|
351
357
|
written_length += chunk.length
|
352
358
|
@read_length += chunk.length
|
data/lib/net/ajp13.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# = Ruby/AJP
|
2
|
-
#
|
2
|
+
# Ruby/AJP is an implementation of AJP(Apache Jserv Protocol) 1.3 in Ruby,
|
3
3
|
# based on http://tomcat.apache.org/connectors-doc/common/ajpv13a.html.
|
4
4
|
#
|
5
5
|
# [Net::AJP13::Client] provides high-level API to implement AJP clients.
|
6
|
-
# The interface of
|
6
|
+
# The interface of this client-side library is similar to
|
7
7
|
# net/http.
|
8
8
|
# see ajp13client.rb[link:files/lib/net/ajp13client_rb.html]
|
9
9
|
# for more detail.
|
@@ -33,9 +33,8 @@
|
|
33
33
|
|
34
34
|
require 'net/http'
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
# :startdoc:
|
36
|
+
module Net #:nodoc:
|
37
|
+
end
|
39
38
|
|
40
39
|
module Net::AJP13
|
41
40
|
module Constants
|
@@ -93,7 +92,7 @@ class Net::AJP13::Request
|
|
93
92
|
}.freeze
|
94
93
|
SC_REQ_HEADER_NAMES.each_key {|k| k.freeze}
|
95
94
|
|
96
|
-
SC_A_REQ_ATTRIBUTE =
|
95
|
+
SC_A_REQ_ATTRIBUTE = 0x0A
|
97
96
|
# Maps request attribute names into their codes
|
98
97
|
SC_A_NAMES = {
|
99
98
|
:context => 0x01,
|
@@ -194,7 +193,7 @@ class Net::AJP13::Request
|
|
194
193
|
else
|
195
194
|
header_name = packet.read_string
|
196
195
|
end
|
197
|
-
req
|
196
|
+
req.add_field(header_name, packet.read_string)
|
198
197
|
end
|
199
198
|
loop do
|
200
199
|
case attr_name = packet.read_byte
|
@@ -252,6 +251,7 @@ class Net::AJP13::Request
|
|
252
251
|
# HTTP-side connection is over SSL or not.
|
253
252
|
attr_accessor :is_ssl
|
254
253
|
alias :is_ssl? :is_ssl
|
254
|
+
alias :ssl? :is_ssl
|
255
255
|
def is_ssl=(value) #:nodoc:
|
256
256
|
@is_ssl = !!value
|
257
257
|
end
|
@@ -562,7 +562,7 @@ end
|
|
562
562
|
class Net::AJP13::AJPPacketError < IOError
|
563
563
|
end
|
564
564
|
|
565
|
-
# :
|
565
|
+
# :enddoc:
|
566
566
|
# Represents AJP1.3 Packet
|
567
567
|
class Net::AJP13::Packet
|
568
568
|
include Net::AJP13::Constants
|
data/ruby-ajp.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "ruby-ajp"
|
3
|
-
spec.version = "0.
|
3
|
+
spec.version = "0.2.0"
|
4
4
|
spec.required_ruby_version = ">= 1.8.3"
|
5
5
|
spec.summary = "An implementation of Apache Jserv Protocol 1.3 in Ruby"
|
6
6
|
spec.author = "Yugui"
|
@@ -20,8 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
"COPYING"
|
21
21
|
spec.files.reject! {|fn| fn.include?('.svn') }
|
22
22
|
spec.test_files = [
|
23
|
-
'packet', 'request',
|
24
|
-
'response', 'client'
|
23
|
+
'packet', 'request', 'response', 'client', 'server'
|
25
24
|
].map{|x| "test/net/test_ajp13#{x}.rb"}
|
26
25
|
spec.has_rdoc = true
|
27
26
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'stringio'
|
3
|
+
require File.dirname(__FILE__) + "/../../lib/net/ajp13/ajp13cgi.rb"
|
4
|
+
|
5
|
+
class Net::AJP13::AJP13CGITest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@encoded_body =
|
8
|
+
"test%5Bfirst%5Fname%5D=foo" +
|
9
|
+
"&test%5blast%5Fname%5D=bar+hoge" +
|
10
|
+
"&test%5Bemail%5D=foo%2Dbar%40yet%2Eanother%2Edomain%2Etest" +
|
11
|
+
"&key+with+SP=huga" +
|
12
|
+
"&nanika=unyuu" +
|
13
|
+
"&last=%5Ce" +
|
14
|
+
""
|
15
|
+
@encoded_body.freeze
|
16
|
+
@qs = "last=%5Cufin.%5Ce"
|
17
|
+
|
18
|
+
req = Net::AJP13::PostRequest.new('/path/to/resource')
|
19
|
+
req.server_name = 'www.domain.test'
|
20
|
+
req.server_port = 8181
|
21
|
+
req.is_ssl = true
|
22
|
+
req.body_stream = StringIO.new(@encoded_body)
|
23
|
+
req['Host'] = 'www.domain.test'
|
24
|
+
req['Content-Length'] = @encoded_body.length.to_s
|
25
|
+
req['Content-Type'] = 'application/x-www-form-urlencoded'
|
26
|
+
req['Content-Language'] = 'ja-JP'
|
27
|
+
req['User-Agent'] = @ua = "testcase #{__FILE__}:#{__LINE__}"
|
28
|
+
req.set_attribute('QUERY_STRING', @qs)
|
29
|
+
|
30
|
+
@cgi = Net::AJP13::AJP13CGI.new(req)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_at
|
34
|
+
assert_equal 'foo', @cgi['test[first_name]']
|
35
|
+
assert_equal 'bar hoge', @cgi['test[last_name]']
|
36
|
+
assert_equal 'foo-bar@yet.another.domain.test', @cgi['test[email]']
|
37
|
+
assert_equal 'huga', @cgi['key with SP']
|
38
|
+
assert_equal 'unyuu', @cgi['nanika']
|
39
|
+
assert_equal '\e', @cgi['last']
|
40
|
+
assert_equal '', @cgi['test[invalid_key]']
|
41
|
+
assert_equal '', @cgi['']
|
42
|
+
|
43
|
+
assert_equal '', @cgi['Test[first_name]'] # case sensitive
|
44
|
+
assert_equal '', @cgi['test[Last_name]'] # case sensitive
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_has_key?
|
48
|
+
assert @cgi.has_key?('test[first_name]')
|
49
|
+
assert @cgi.has_key?('test[last_name]')
|
50
|
+
assert @cgi.has_key?('test[email]')
|
51
|
+
assert @cgi.has_key?('key with SP')
|
52
|
+
assert !@cgi.has_key?('test[invalid_key]')
|
53
|
+
assert !@cgi.has_key?('')
|
54
|
+
|
55
|
+
assert !@cgi.has_key?('Test[first_name]')
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_env_table
|
59
|
+
assert_equal @encoded_body.length, @cgi.env_table['CONTENT_LENGTH']
|
60
|
+
assert_equal 8181, @cgi.env_table['SERVER_PORT']
|
61
|
+
assert_equal 'www.domain.test', @cgi.env_table['HTTP_HOST']
|
62
|
+
assert_equal @qs, @cgi.env_table['Query_String']
|
63
|
+
assert_equal 'application/x-www-form-urlencoded', @cgi.env_table['content_type']
|
64
|
+
assert_equal 'AJP/1.3', @cgi.env_table['gateway_interface']
|
65
|
+
assert_equal @ua, @cgi.env_table['HTTP_USER_AGENT']
|
66
|
+
assert_equal 'ja-JP', @cgi.env_table['HTTP_CONTENT_LANGUAGE']
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_params
|
70
|
+
assert_equal ['foo'], @cgi.params['test[first_name]']
|
71
|
+
assert_equal ['bar hoge'], @cgi.params['test[last_name]']
|
72
|
+
assert_equal ['foo-bar@yet.another.domain.test'], @cgi.params['test[email]']
|
73
|
+
assert_equal ['huga'], @cgi.params['key with SP']
|
74
|
+
assert_equal ['unyuu'], @cgi.params['nanika']
|
75
|
+
assert_equal ['\e'], @cgi.params['last']
|
76
|
+
assert_equal [], @cgi.params['test[invalid_key]']
|
77
|
+
assert_equal [], @cgi.params['']
|
78
|
+
|
79
|
+
assert_equal [], @cgi.params['Test[first_name]'] # case sensitive
|
80
|
+
assert_equal [], @cgi.params['test[Last_name]'] # case sensitive
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_header_0
|
84
|
+
assert_nil @cgi.response
|
85
|
+
@cgi.header
|
86
|
+
assert_equal 'text/html', @cgi.response['Content-Type']
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_header_1
|
90
|
+
assert_nil @cgi.response
|
91
|
+
@cgi.header('text/plain')
|
92
|
+
assert_equal 'text/plain', @cgi.response['Content-Type']
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_header
|
96
|
+
assert_nil @cgi.response
|
97
|
+
@cgi.header(
|
98
|
+
"status" => "200 OK",
|
99
|
+
"charset" => "EUC-KR"
|
100
|
+
)
|
101
|
+
assert_equal 'text/html; charset=EUC-KR', @cgi.response['Content-Type']
|
102
|
+
assert_equal 'OK', @cgi.response.message
|
103
|
+
end
|
104
|
+
end
|
@@ -159,8 +159,8 @@ class Net::AJP13::RequestTest < Test::Unit::TestCase
|
|
159
159
|
assert_equal "deflate, gzip, x-gzip, identity, *;q=0", value
|
160
160
|
when 'cookie'
|
161
161
|
assert_block {
|
162
|
-
"JSESSIONID=
|
163
|
-
|
162
|
+
"JSESSIONID=54104A3A775650CEF8967D263F1A7193, $Version=1" == value or
|
163
|
+
"$Version=1, JSESSIONID=54104A3A775650CEF8967D263F1A7193" == value
|
164
164
|
}
|
165
165
|
when 'cache-control'
|
166
166
|
assert_equal "no-cache", value
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'stringio'
|
3
|
-
require File.dirname(__FILE__) + '/../../lib/net/
|
3
|
+
require File.dirname(__FILE__) + '/../../lib/net/ajp13/server'
|
4
4
|
|
5
5
|
class Net::AJP13::Server
|
6
6
|
unless method_defined?(:fcall)
|
@@ -26,7 +26,7 @@ class Net::AJP13::Server::BodyInputTest < Test::Unit::TestCase
|
|
26
26
|
class MockSocket
|
27
27
|
def initialize(contents)
|
28
28
|
@bodies = (
|
29
|
-
contents.map{|c|
|
29
|
+
contents.map{|c|"\x12\x34#{[c.length+2, c.length].pack('nn')}" + c } <<
|
30
30
|
"\x12\x34\x00\x00"
|
31
31
|
).map {|str| StringIO.new(str)}
|
32
32
|
@write_buf = ''
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-ajp
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-01-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2006-01-24 00:00:00 +09:00
|
8
8
|
summary: An implementation of Apache Jserv Protocol 1.3 in Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -28,9 +28,11 @@ cert_chain:
|
|
28
28
|
authors:
|
29
29
|
- Yugui
|
30
30
|
files:
|
31
|
-
- lib/net/ajp13server.rb
|
32
31
|
- lib/net/ajp13.rb
|
33
|
-
- lib/net/
|
32
|
+
- lib/net/ajp13/server.rb
|
33
|
+
- lib/net/ajp13/ajp13cgi.rb
|
34
|
+
- lib/net/ajp13/client.rb
|
35
|
+
- test/net/test_ajp13cgi.rb
|
34
36
|
- test/net/test_ajp13request.rb
|
35
37
|
- test/net/test_ajp13server.rb
|
36
38
|
- test/net/test_ajp13response.rb
|
@@ -59,6 +61,7 @@ test_files:
|
|
59
61
|
- test/net/test_ajp13request.rb
|
60
62
|
- test/net/test_ajp13response.rb
|
61
63
|
- test/net/test_ajp13client.rb
|
64
|
+
- test/net/test_ajp13server.rb
|
62
65
|
rdoc_options: []
|
63
66
|
|
64
67
|
extra_rdoc_files: []
|