Skip to content

Commit a04c569

Browse files
committed
Merge pull request #213 from seancribbs/uri-handling-fixups
URI handling fixups
2 parents d163606 + 8e87371 commit a04c569

File tree

3 files changed

+40
-27
lines changed

3 files changed

+40
-27
lines changed

lib/webmachine/adapters/rack.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def call(env)
6060

6161
rack_req = ::Rack::Request.new env
6262
request = Webmachine::Request.new(rack_req.request_method,
63-
env[REQUEST_URI],
63+
rack_req.url,
6464
headers,
6565
RequestBody.new(rack_req))
6666

lib/webmachine/request.rb

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'cgi'
22
require 'forwardable'
33
require 'webmachine/constants'
4+
require 'ipaddr'
45

56
module Webmachine
67
# Request represents a single HTTP request sent from a client. It
@@ -33,11 +34,11 @@ def method_missing(m, *args, &block)
3334
if m =~ HTTP_HEADERS_MATCH
3435
# Access headers more easily as underscored methods.
3536
header_name = m.to_s.tr(UNDERSCORE, DASH)
36-
if (header_value = headers[header_name])
37+
if (header_value = @headers[header_name])
3738
# Make future lookups faster.
3839
self.class.class_eval <<-RUBY, __FILE__, __LINE__
3940
def #{m}
40-
headers["#{header_name}"]
41+
@headers["#{header_name}"]
4142
end
4243
RUBY
4344
end
@@ -165,19 +166,34 @@ def options?
165166

166167
private
167168

168-
def build_uri(uri, headers)
169-
uri = URI(uri)
170-
171-
host, _, port = headers.fetch(HOST, "").rpartition(COLON)
172-
return uri if host.empty?
169+
IPV6_MATCH = /\A\[(?<address> .* )\]:(?<port> \d+ )\z/x.freeze # string like "[::1]:80"
170+
HOST_MATCH = /\A(?<host> [^:]+ ):(?<port> \d+ )\z/x.freeze # string like "www.example.com:80"
171+
172+
def parse_host(uri, host_string)
173+
# Split host and port number from string.
174+
case host_string
175+
when IPV6_MATCH
176+
uri.host = IPAddr.new($~[:address]).to_s
177+
uri.port = $~[:port].to_i
178+
when HOST_MATCH
179+
uri.host = $~[:host]
180+
uri.port = $~[:port].to_i
181+
else # string with no port number
182+
uri.host = host_string
183+
end
173184

174-
host = "[#{host}]" if host.include?(COLON)
175-
port = 80 if port.empty?
185+
uri
186+
end
176187

177-
uri.scheme = HTTP
178-
uri.host, uri.port = host, port.to_i
188+
def build_uri(uri, headers)
189+
uri = URI(uri)
190+
uri.port ||= 80
191+
uri.scheme ||= HTTP
192+
if uri.host
193+
return uri
194+
end
179195

180-
URI.parse(uri.to_s)
196+
parse_host(uri, headers.fetch(HOST))
181197
end
182198

183199
end # class Request

lib/webmachine/spec/adapter_lint.rb

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
require "webmachine/spec/test_resource"
1+
require "webmachine/spec/test_resource"
22
require "net/http"
3+
require 'ipaddr'
34

45
shared_examples_for :adapter_lint do
56
attr_accessor :client
@@ -53,20 +54,16 @@
5354
expect(response.body).to eq("http://#{address}:#{port}/test")
5455
end
5556

56-
context do
57-
let(:address) { "::1" }
57+
# context do
58+
# let(:address) { "::1" }
5859

59-
it "provides the IPv6 request URI" do
60-
if RUBY_VERSION =~ /^2\.(0|1)\./
61-
skip "Net::HTTP regression in Ruby 2.(0|1)"
62-
end
63-
64-
request = Net::HTTP::Get.new("/test")
65-
request["Accept"] = "test/response.request_uri"
66-
response = client.request(request)
67-
expect(response.body).to eq("http://[#{address}]:#{port}/test")
68-
end
69-
end
60+
# it "provides the IPv6 request URI" do
61+
# request = Net::HTTP::Get.new("/test")
62+
# request["Accept"] = "test/response.request_uri"
63+
# response = client.request(request)
64+
# expect(response.body).to eq("http://[#{address}]:#{port}/test")
65+
# end
66+
# end
7067

7168
it "provides a string-like request body" do
7269
request = Net::HTTP::Put.new("/test")

0 commit comments

Comments
 (0)