Skip to content

Instantly share code, notes, and snippets.

@pjb3
Created October 12, 2008 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjb3/16463 to your computer and use it in GitHub Desktop.
Save pjb3/16463 to your computer and use it in GitHub Desktop.
require 'uri'
module Http
DEFAULT_TIMEOUT = 30
class Request
attr_accessor :method, :uri, :headers, :body
def initialize(_method, _uri, options={}, &block)
self.method = _method
self.uri = _uri
options.each do |k,v|
send("#{k}=", v)
end
block.call(self) if block
end
def execute(timeout, options={}, &block)
handle_params
new HTTP::RequestHandler(self)
end
def method=(m)
@method = m.to_s
end
def uri=(u)
@uri = (URI === u) ? u.clone : URI.parse(u.to_s)
end
#If you set the body, then params are tacked on to the url as querystring params
#Otherwise the body is set to the url encoded params
def params
@params ||= {}
end
def params=(p)
@params = p
end
private
def handle_params
return if params.empty?
param_str = params.map{|k,v| "#{k}=#{Http.escape(v)}" }.join("&")
if body || method.to_s.downcase == "get"
self.uri.query = case self.uri.query
when nil: param_str
when /&$/: "#{self.uri.query}#{param_str}"
else "#{self.uri.query}&#{param_str}"
end
else
self.body = param_str
end
end
end
class Response
end
class RequestHandler
end
def self.escape(v)
URI.escape(v.to_s, /[^\w]/)
end
def self.get(uri, options={}, &block)
Request.new("GET", uri, option, &block).execute(DEFAULT_TIMEOUT, :sync => true)
end
def self.post(uri, options={}, &block)
Request.new("POST", uri, option, &block).execute(DEFAULT_TIMEOUT, :sync => true)
end
def self.put(uri, options={}, &block)
Request.new("PUT", uri, option, &block).execute(DEFAULT_TIMEOUT, :sync => true)
end
end
# Http.get("http://www.google.com/foo/1", :body => "asdasdas", :params => {"page => 1"}, :headers => {"Content-Type" => "text/html"})
#
# Http.get("http://www.google.com/foo/1") do |get|
# get.params["page"] = 1
# get.headers["Content-Type"] = "text/html"
# end
#
# Http.post("http://www.google.com/foo/1", :params => {"page => 1"}, :headers => {"Content-Type" => "text/html"})
#
# Http.get("http://www.google.com/foo/1", {"page" => "1"}, "Content-Type" => "text/html") do |get|
# get.params = {}
# end
#
#
# Http::Request.new("GET", "http://www.google.com/foo/1")
# Http::Request.new("POST", "http://www.google.com/foo/1")
#
# puts Http.get.inspect
#
# get = Http::Request.new
# get.method = "GET"
# get.uri = "http://google.com"
# get.headers = {"Content-Type" => "text/html"}
# response = get.execute(:async => true)
# response.body # implicitly waits
# future = get.execute
# future.callback do
# # ...
# end
# future.callback do
# # more stuff
# end
# future.errback do
# # OMGWTFBBQ
# end
#
# get.execute do |response|
#
# end
#
# future = get.execute
# future.wait
#
# post = Http::Request.new
# post.method = "GET"
# post.uri = "http://google.com"
# post.headers = {"Content-Type" => "text/html"}
# post.body = "asdasdasd"
#
#
#
require "#{File.dirname(__FILE__)}/spec_helper"
require 'http'
describe Http::Request do
before do
@request = Http::Request.new("GET", "http://example.com")
end
describe "#handle_params" do
describe "with no body or params" do
it "should not set the body" do
@request.send(:handle_params)
@request.body.should be_nil
end
end
describe "a non-get with no body with some params" do
before do
@request.method = "POST"
@request.params["foo"] = "bar"
@request.params["xyz"] = 8
@request.send(:handle_params)
end
it "should not set the body" do
@request.body.should =~ /\A(foo=bar&xyz=8|xyz=8&foo=bar)\Z/
end
it "should not set the body" do
@request.uri.query.should be_nil
end
end
describe "a get with no body with some params" do
before do
@request.method = "GET"
@request.params["foo"] = "bar"
@request.params["xyz"] = 8
@request.send(:handle_params)
end
it "should not set the body" do
@request.body.should be_nil
end
it "should append the params to the query" do
@request.uri.query.should =~ /\A(foo=bar&xyz=8|xyz=8&foo=bar)\Z/
end
end
describe "a post with a body and some params" do
before do
@request.method = "POST"
@request.params["foo"] = "bar"
@request.params["xyz"] = 8
@request.body = "something"
@request.send(:handle_params)
end
it "should not change the body" do
@request.body.should == "something"
end
it "should append the params to the query" do
@request.uri.query.should =~ /\A(foo=bar&xyz=8|xyz=8&foo=bar)\Z/
end
end
describe "a get with some params" do
before do
@request.uri = "http://example.com?foo=1"
@request.params["foo"] = "bar"
@request.params["xyz"] = 8
@request.send(:handle_params)
end
it "should append the params to the query" do
@request.uri.query.should =~ /\Afoo=1&(foo=bar&xyz=8|xyz=8&foo=bar)\Z/
end
end
describe "a get and & at the end of the query and some params" do
before do
@request.uri = "http://example.com?foo=1&"
@request.params["foo"] = "bar"
@request.params["xyz"] = 8
@request.send(:handle_params)
end
it "should append the params to the query" do
@request.uri.query.should =~ /\Afoo=1&(foo=bar&xyz=8|xyz=8&foo=bar)\Z/
end
end
end
describe "#escape" do
it "should encode &" do
Http.escape("&").should == "%26"
end
it "should encode spaces" do
Http.escape("foo bar").should == "foo%20bar"
end
it "should encode non-strings" do
Http.escape(42).should == "42"
end
end
end
require 'rubygems'
require 'spec'
$:.unshift("#{File.dirname(__FILE__)}/../lib/")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment