Commit 1b40777f authored by Nitesh A Jain's avatar Nitesh A Jain

Merge tag 'upstream/0.6.2'

Upstream version 0.6.2
parents 3c0538bc c214c1f6
AllCops:
Includes:
Include:
- 'Gemfile'
- 'Rakefile'
- 'http.gemspec'
......@@ -15,7 +15,7 @@ MethodLength:
ClassLength:
CountComments: false
Max: 132 # TODO: lower to 100
Max: 100
CyclomaticComplexity:
Max: 13 # TODO: lower to 6
......@@ -99,3 +99,18 @@ PercentLiteralDelimiters:
Semicolon:
Exclude:
- 'spec/support/'
# Do not force first argument to be separated with exactly single space.
# My (ixti) personal preference is to align code in columns when it makes
# sense:
#
# module HTTP
# module MimeType
# class JSON < Adapter
# register_adapter 'application/json', JSON
# register_alias 'application/json', :json
# end
# end
# end
SingleSpaceBeforeFirstArg:
Enabled: false
before_install:
- gem update bundler
- bundle --version
- gem update --system 2.1.11
- gem --version
bundler_args: --without development
env:
global:
- JRUBY_OPTS="$JRUBY_OPTS --debug"
language: ruby
rvm:
- 1.8.7
- 1.9.2
- 1.9.3
- 2.0.0
- 2.1.0
- 2.1
- jruby-18mode
- jruby-19mode
- jruby-head
- rbx-2
- ruby-head
matrix:
include:
- rvm: jruby-18mode
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
- rvm: jruby-19mode
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
- rvm: jruby-head
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
allow_failures:
- rvm: jruby-head
- rvm: ruby-head
......
0.6.2 (2014-08-06)
------------------
* Fix default Host header value. See #150. (@ixti)
* Deprecate BearerToken authorization header. (@ixti)
* Fix handling of chunked responses without Content-Length header. (@ixti)
* Rename `HTTP.with_follow` to `HTTP.follow` and mark former one as being
deprecated (@ixti)
0.6.1 (2014-05-07)
------------------
......@@ -73,6 +82,12 @@ end
[Changes discussion](https://github.com/tarcieri/http/issues/116)
0.5.1 (2014-05-27)
------------------
* Backports redirector fixes from 0.6.0 (@ixti)
* EOL of 0.5.X branch.
0.5.0
-----
* Add query string support
......
......@@ -17,12 +17,13 @@ end
group :test do
gem 'backports'
gem 'coveralls', :require => false
gem 'coveralls'
gem 'json', '>= 1.8.1', :platforms => [:jruby, :rbx, :ruby_18, :ruby_19]
gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18]
gem 'rspec', '>= 2.14'
gem 'rubocop', '~> 0.19.0', :platforms => [:ruby_19, :ruby_20, :ruby_21]
gem 'simplecov', :require => false
gem 'rest-client', '~> 1.6.0', :platforms => [:jruby, :ruby_18]
gem 'rspec', '~> 2.14'
gem 'rubocop', '~> 0.24.0', :platforms => [:ruby_19, :ruby_20, :ruby_21]
gem 'simplecov', '>= 0.9'
gem 'yardstick'
end
......
......@@ -118,7 +118,7 @@ HTTP.get "http://example.com/resource", :params => {:foo => "bar"}
Want to POST with a specific body, JSON for instance?
```ruby
HTTP.post "http://example.com/resource", :json => { :foo => '42' })
HTTP.post "http://example.com/resource", :json => { :foo => '42' }
```
It's easy!
......@@ -206,7 +206,7 @@ class HttpFetcher
include Celluloid::IO
def fetch(url)
HTTP.get(url, socket_class: Celluloid::IO::TCPSocket).response
HTTP.get(url, socket_class: Celluloid::IO::TCPSocket)
end
end
```
......
......@@ -8,10 +8,10 @@ task :test => :spec
begin
require 'rubocop/rake_task'
Rubocop::RakeTask.new
RuboCop::RakeTask.new
rescue LoadError
task :rubocop do
$stderr.puts 'Rubocop is disabled'
$stderr.puts 'RuboCop is disabled'
end
end
......
No preview for this file type
......@@ -15,13 +15,13 @@ class HttpFetcher
def fetch(url)
# Note: For SSL support specify:
# ssl_socket_class: Celluloid::IO::SSLSocket
HTTP.get(url, :socket_class => Celluloid::IO::TCPSocket).response
HTTP.get(url, :socket_class => Celluloid::IO::TCPSocket)
end
end
fetcher = HttpFetcher.new
urls = %w[http://www.ruby-lang.org/ http://www.rubygems.org/ http://celluloid.io/]
urls = %w[http://ruby-lang.org/ http://rubygems.org/ http://celluloid.io/]
# Kick off a bunch of future calls to HttpFetcher to grab the URLs in parallel
futures = urls.map { |u| [u, fetcher.future.fetch(u)] }
......
......@@ -4,23 +4,22 @@ module HTTP
module AuthorizationHeader
# OAuth2 Bearer token authorization header builder
# @see http://tools.ietf.org/html/rfc6750
#
# @deprecated Will be remove in v0.7.0
class BearerToken
# @param [#fetch] opts
# @option opts [#to_s] :token
# @option opts [#to_s] :encode (false)
# @option opts [Boolean] :encode (false) deprecated
def initialize(opts)
@encode = opts.fetch :encode, false
@token = opts.fetch :token
end
warn "#{Kernel.caller.first}: [DEPRECATION] BearerToken deprecated."
def token
return Base64.strict_encode64 @token if @encode
@token
@token = opts.fetch :token
@token = Base64.strict_encode64 @token if opts.fetch(:encode, false)
end
# :nodoc:
def to_s
"Bearer #{token}"
"Bearer #{@token}"
end
end
......
......@@ -81,11 +81,11 @@ module URI
encode_www_form_component(k)
elsif v.respond_to?(:to_ary)
v.to_ary.map do |w|
next unless w
str = encode_www_form_component(k)
unless w.nil?
str << '='
str << encode_www_form_component(w)
end
str << '='
str << encode_www_form_component(w)
end.join('&')
else
str = encode_www_form_component(k)
......
......@@ -73,10 +73,17 @@ module HTTP
with_response(:object)
end
def with_follow(follow)
branch default_options.with_follow(follow)
# Make client follow redirects.
# @param opts (see Redirector#initialize)
# @return [HTTP::Client]
def follow(opts = true)
branch default_options.with_follow opts
end
# (see #follow)
# @deprecated
alias_method :with_follow, :follow
# Make a request with the given headers
def with_headers(headers)
branch default_options.with_headers(headers)
......
......@@ -78,7 +78,7 @@ module HTTP
finish_response if @parser.finished?
chunk
chunk.to_s
end
private
......
......@@ -70,40 +70,12 @@ module HTTP
end
end
def with_proxy(proxy_hash)
dup do |opts|
opts.proxy = proxy_hash
end
end
def with_params(params)
dup do |opts|
opts.params = params
end
end
def with_form(form)
dup do |opts|
opts.form = form
end
end
def with_json(data)
dup do |opts|
opts.json = data
end
end
def with_body(body)
dup do |opts|
opts.body = body
end
end
def with_follow(follow)
dup do |opts|
opts.follow = follow
end
%w[proxy params form json body follow].each do |method_name|
class_eval <<-RUBY, __FILE__, __LINE__
def with_#{method_name}(value)
dup { |opts| opts.#{method_name} = value }
end
RUBY
end
def [](option)
......@@ -140,7 +112,7 @@ module HTTP
:socket_class => socket_class,
:ssl_socket_class => ssl_socket_class,
:ssl_context => ssl_context
}
}
end
def dup
......
......@@ -15,6 +15,9 @@ module HTTP
# The scheme of given URI was not understood
class UnsupportedSchemeError < RequestError; end
# Default User-Agent header value
USER_AGENT = "RubyHTTPGem/#{HTTP::VERSION}".freeze
# RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1
METHODS = [:options, :get, :head, :post, :put, :delete, :trace, :connect]
......@@ -36,6 +39,14 @@ module HTTP
# Allowed schemes
SCHEMES = [:http, :https, :ws, :wss]
# Default ports of supported schemes
PORTS = {
:http => 80,
:https => 443,
:ws => 80,
:wss => 443
}
# Method is given as a lowercase symbol e.g. :get, :post
attr_reader :verb
......@@ -48,7 +59,7 @@ module HTTP
# The following method may be removed in two minor versions (0.7.0) or one
# major version (1.0.0)
def method(*args)
def method(*)
warn "#{Kernel.caller.first}: [DEPRECATION] HTTP::Request#method is deprecated. Use #verb instead. For Object#method, use #__method__."
@verb
end
......@@ -71,8 +82,8 @@ module HTTP
@headers = HTTP::Headers.coerce(headers || {})
@headers['Host'] ||= @uri.host
@headers['User-Agent'] ||= "RubyHTTPGem/#{HTTP::VERSION}"
@headers['Host'] ||= default_host
@headers['User-Agent'] ||= USER_AGENT
end
# Returns new Request with updated uri
......@@ -125,5 +136,18 @@ module HTTP
def socket_port
using_proxy? ? proxy[:proxy_port] : uri.port
end
private
# Default host (with port if needed) header value.
#
# @return [String]
def default_host
if PORTS[@scheme] == @uri.port
@uri.host
else
"#{@uri.host}:#{@uri.port}"
end
end
end
end
......@@ -4,18 +4,16 @@ module HTTP
# CRLF is the universal HTTP delimiter
CRLF = "\r\n"
# Types valid to be used as body source
VALID_BODY_TYPES = [String, NilClass, Enumerable]
def initialize(socket, body, headers, headerstart) # rubocop:disable ParameterLists
@body = body
fail(RequestError, 'body of wrong type') unless valid_body_type
@socket = socket
@headers = headers
@request_header = [headerstart]
end
def valid_body_type
valid_types = [String, NilClass, Enumerable]
checks = valid_types.map { |type| @body.is_a?(type) }
checks.any?
validate_body_type!
end
# Adds headers to the request header from the headers array
......@@ -74,6 +72,13 @@ module HTTP
@socket << '0' << CRLF * 2
end
end
private
def validate_body_type!
return if VALID_BODY_TYPES.any? { |type| @body.is_a? type }
fail RequestError, "body of wrong type: #{@body.class}"
end
end
end
end
......@@ -42,10 +42,8 @@ module HTTP
end
def chunk
if (chunk = @chunk)
@chunk = nil
chunk
end
chunk, @chunk = @chunk, nil
chunk
end
def on_message_complete
......
module HTTP
VERSION = '0.6.1'
VERSION = '0.6.2'
end
--- !ruby/object:Gem::Specification
name: http
version: !ruby/object:Gem::Version
version: 0.6.1
version: 0.6.2
platform: ruby
authors:
- Tony
......@@ -9,7 +9,7 @@ authors:
autorequire:
bindir: bin
cert_chain: []
date: 2014-05-08 00:00:00.000000000 Z
date: 2014-08-06 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: http_parser.rb
......@@ -131,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
version: '0'
requirements: []
rubyforge_project:
rubygems_version: 2.2.0
rubygems_version: 2.2.2
signing_key:
specification_version: 4
summary: HTTP should be easy
......
......@@ -133,7 +133,7 @@ describe HTTP::Client do
let(:client) { described_class.new :headers => headers }
it 'keeps `Host` header as is' do
expect(client).to receive(:perform) do |req, options|
expect(client).to receive(:perform) do |req, _|
expect(req['Host']).to eq 'another.example.com'
end
......
......@@ -9,7 +9,7 @@ describe HTTP::Request::Writer do
end
it "doesn't throw on a nil body" do
expect { construct [] }.not_to raise_error
expect { construct nil }.not_to raise_error
end
it "doesn't throw on a String body" do
......
require 'spec_helper'
describe HTTP::Request do
let(:headers) { {:accept => 'text/html'} }
let(:request_uri) { 'http://example.com/' }
subject(:request) { HTTP::Request.new(:get, request_uri, headers) }
it 'includes HTTP::Headers::Mixin' do
expect(described_class).to include HTTP::Headers::Mixin
end
......@@ -11,35 +16,57 @@ describe HTTP::Request do
end
it 'provides a #scheme accessor' do
request = HTTP::Request.new(:get, 'http://example.com/')
expect(request.scheme).to eq(:http)
end
describe 'headers' do
subject { HTTP::Request.new(:get, 'http://example.com/', :accept => 'text/html') }
it 'sets given headers' do
expect(subject['Accept']).to eq('text/html')
end
describe 'Host header' do
subject { request['Host'] }
context 'was not given' do
it { is_expected.to eq 'example.com' }
it 'sets explicit headers' do
expect(subject['Accept']).to eq('text/html')
context 'and request URI has non-standard port' do
let(:request_uri) { 'http://example.com:3000/' }
it { is_expected.to eq 'example.com:3000' }
end
end
it 'sets implicit headers' do
expect(subject['Host']).to eq('example.com')
context 'was explicitly given' do
before { headers[:host] = 'github.com' }
it { is_expected.to eq 'github.com' }
end
end
describe 'User-Agent header' do
subject { request['User-Agent'] }
it 'provides a #verb accessor' do
expect(subject.verb).to eq(:get)
context 'was not given' do
it { is_expected.to eq HTTP::Request::USER_AGENT }
end
it 'provides a #method accessor that outputs a deprecation warning and returns the verb' do
warning = capture_warning do
expect(subject.method).to eq(subject.verb)
end
expect(warning).to match(/\[DEPRECATION\] HTTP::Request#method is deprecated\. Use #verb instead\. For Object#method, use #__method__\.$/)
context 'was explicitly given' do
before { headers[:user_agent] = 'MrCrawly/123' }
it { is_expected.to eq 'MrCrawly/123' }
end
end
it 'provides a #verb accessor' do
expect(subject.verb).to eq(:get)
end
it 'provides a #__method__ method that delegates to Object#method' do
expect(subject.__method__(:verb)).to be_a(Method)
it 'provides a #method accessor that outputs a deprecation warning and returns the verb' do
warning = capture_warning do
expect(subject.method).to eq(subject.verb)
end
expect(warning).to match(/\[DEPRECATION\] HTTP::Request#method is deprecated\. Use #verb instead\. For Object#method, use #__method__\.$/)
end
it 'provides a #__method__ method that delegates to Object#method' do
expect(subject.__method__(:verb)).to be_a(Method)
end
describe '#redirect' do
......@@ -60,6 +87,20 @@ describe HTTP::Request do
expect(redirected['Host']).to eq 'blog.example.com'
end
context 'with schema-less absolute URL given' do
subject(:redirected) { request.redirect '//another.example.com/blog' }
its(:uri) { should eq URI.parse 'http://another.example.com/blog' }
its(:verb) { should eq request.verb }
its(:body) { should eq request.body }
its(:proxy) { should eq request.proxy }
it 'presets new Host header' do
expect(redirected['Host']).to eq 'another.example.com'
end
end
context 'with relative URL given' do
subject(:redirected) { request.redirect '/blog' }
......
......@@ -18,15 +18,15 @@ describe HTTP do
end
context 'with query string parameters' do
it 'should be easy' do
response = HTTP.get "#{test_endpoint}params" , :params => {:foo => 'bar'}
it 'is easy' do
response = HTTP.get "#{test_endpoint}params", :params => {:foo => 'bar'}
expect(response.to_s).to match(/Params!/)
end
end
context 'with query string parameters in the URI and opts hash' do
it 'includes both' do
response = HTTP.get "#{test_endpoint}multiple-params?foo=bar" , :params => {:baz => 'quux'}
response = HTTP.get "#{test_endpoint}multiple-params?foo=bar", :params => {:baz => 'quux'}
expect(response.to_s).to match(/More Params!/)
end
end
......
require 'simplecov'
require 'coveralls'
if RUBY_VERSION >= '1.9'
require 'simplecov'
require 'coveralls'
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
SimpleCov::Formatter::HTMLFormatter,
Coveralls::SimpleCov::Formatter
]
SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
SimpleCov.start do
add_filter '/spec/'
minimum_coverage(80)
SimpleCov.start do
add_filter '/spec/'
minimum_coverage(80)
end
end
require 'http'
......
......@@ -41,18 +41,19 @@ class ExampleService < WEBrick::HTTPServlet::AbstractServlet
end
def handle_params(request, response)
if request.query_string == 'foo=bar'
response.status = 200
response.body = 'Params!'
end
return unless request.query_string == 'foo=bar'
response.status = 200
response.body = 'Params!'
end
def handle_multiple_params(request, response)
params = CGI.parse(request.query_string)
if params == {'foo' => ['bar'], 'baz' => ['quux']}
response.status = 200
response.body = 'More Params!'
end
return unless params == {'foo' => ['bar'], 'baz' => ['quux']}
response.status = 200
response.body = 'More Params!'
end
def do_POST(request, response) # rubocop:disable MethodName
......
require 'webrick/httpproxy'
handler = proc do | req, res |
res['X-PROXIED'] = true
end
handler = proc { |_, res| res['X-PROXIED'] = true }
ProxyServer = WEBrick::HTTPProxyServer.new(
:Port => 8080,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment