httpalooza 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 374ae028d634e1fafe7d735fb4ee2c06b1a82ba0
4
+ data.tar.gz: 1bd12e35c2ddfee45dbf1e67613240f97aad7f01
5
+ SHA512:
6
+ metadata.gz: 4e9bb8b68aed888612724d4fe23874da1ed9d7b28a80a529fbfaef653a65b903514f89bf215501ee10138107fbdd63ad962f7d00b2107d830910d6df3c804765
7
+ data.tar.gz: ac36cf9de5924cb4b2bd4354d330f8ced3dcbd60ab0bff2169179bbbb244a706fb46661754fae3bb6391e3a352ce02bf5116904719d701a2886e1c8238cca861
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *swp
11
+ *swo
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in httpalooza.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Quin Hoxie
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # HTTPalooza: Ruby's greatest HTTP clients, on stage together
2
+
3
+ Your Ruby app includes a bunch of HTTP clients already. It's time to make use of them.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's `Gemfile`:
8
+
9
+ ```ruby
10
+ gem 'httpalooza'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ HTTPalooza tracks the bleeding edge, so we recommend leaving the gem version unlocked for best results.
18
+
19
+ ## Usage
20
+
21
+ ```ruby
22
+ $ bundle exec bin/console
23
+ irb(main):001:0> ap HTTPalooza.invite.patron_to_the_party.and_use_typhoeus_too.lets_also_use_http_client_and_plain_old_curl_plus.rest_client_invited_itself_too.get("http://example.com")
24
+ {
25
+ :patron => <HTTPalooza::Response:70225910064600 code=200 body="<!doctype html>\n<html>\n<...,
26
+ :typhoeus => <HTTPalooza::Response:70225915728560 code=200 body="<!doctype html>\n<html>\n<...,
27
+ :http_client => <HTTPalooza::Response:70225924014880 code=200 body="<!doctype html>\n<html>\n<...,
28
+ :curl => <HTTPalooza::Response:70225919916880 code=200 body="<!doctype html>\n<html>\n<...
29
+ }
30
+ ```
31
+
32
+ ## Development
33
+
34
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
35
+
36
+ To install this gem onto your local machine, run `bundle exec rake install`.
37
+
38
+ ### Adding adapters
39
+
40
+ HTTPalooza doesn't include an adapter for your favorite client? It's simple to add one. Create a new subclass of `HTTPalooza::Players::Base` and implement the `#response` method.
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it ( https://github.com/[my-github-username]/httpalooza/fork )
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create a new Pull Request
49
+
50
+ Do not bump the version in your pull request. We will do that in a separate commit (possibly including other changes).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "httpalooza"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'httpalooza/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "httpalooza"
8
+ spec.version = HTTPalooza::VERSION
9
+ spec.authors = ["Quin Hoxie"]
10
+ spec.email = ["qhoxie@gmail.com"]
11
+
12
+ spec.summary = %q{HTTPalooza brings together the best Ruby HTTP clients on one stage.}
13
+ spec.homepage = "http://httpalooza.com/"
14
+ spec.license = "MIT"
15
+
16
+ spec.post_install_message = "HTTPalooza! Ruby's greatest HTTP clients, on stage together."
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "activesupport"
24
+ spec.add_dependency "addressable"
25
+ spec.add_dependency "rack"
26
+
27
+ spec.add_development_dependency "curb"
28
+ spec.add_development_dependency "typhoeus"
29
+ spec.add_development_dependency "patron"
30
+ spec.add_development_dependency "httpclient"
31
+ spec.add_development_dependency "rest-client"
32
+ spec.add_development_dependency "unirest"
33
+ spec.add_development_dependency "em-synchrony"
34
+ spec.add_development_dependency "em-http-request"
35
+ spec.add_development_dependency "selenium-webdriver"
36
+ spec.add_development_dependency "chromedriver-helper"
37
+
38
+ spec.add_development_dependency "awesome_print"
39
+ spec.add_development_dependency "bundler", "~> 1.8"
40
+ spec.add_development_dependency "rake", "~> 10.0"
41
+ spec.add_development_dependency "rspec", "~> 3.4.0"
42
+ end
data/lib/httpalooza.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'active_support/all'
2
+ require 'addressable/uri'
3
+ require 'rack/utils'
4
+ require 'awesome_print'
5
+
6
+ require 'httpalooza/version'
7
+ require 'httpalooza/api'
8
+ require 'httpalooza/players'
9
+ require 'httpalooza/response'
10
+ require 'httpalooza/request'
11
+ require 'httpalooza/lineup'
12
+
13
+ require 'httpalooza/players/base'
14
+ Dir[File.join(File.dirname(__FILE__), 'httpalooza', 'players', '*.rb')].each do |player|
15
+ require player
16
+ end
17
+
18
+ module HTTPalooza
19
+ class Error < StandardError; end
20
+ class NotImplementedError < Error; end
21
+
22
+ def self.invite
23
+ Lineup.new
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module HTTPalooza
2
+ module API
3
+ def get(url, options = {}, &block)
4
+ run! Request.new(url, :get, options.slice(:headers, :params, :payload), &block)
5
+ end
6
+
7
+ def post(url, options = {}, &block)
8
+ run! Request.new(url, :post, options.slice(:headers, :params, :payload), &block)
9
+ end
10
+
11
+ def put(url, options = {}, &block)
12
+ run! Request.new(url, :put, options.slice(:headers, :params, :payload), &block)
13
+ end
14
+
15
+ def delete(url, options = {}, &block)
16
+ run! Request.new(url, :delete, options.slice(:headers, :params, :payload), &block)
17
+ end
18
+
19
+ def head(url, options = {}, &block)
20
+ run! Request.new(url, :head, options.slice(:headers, :params, :payload), &block)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ module HTTPalooza
2
+ class Lineup
3
+ include API
4
+
5
+ UNINVITE_REGEX = /^(uninvite|but|not|except|without|save|besides?|minus|barring|excluding|omitting|exempting|other_than|apart_from|aside_from)_(.+)/i
6
+
7
+ attr_reader :players
8
+
9
+ def initialize
10
+ @players = Set.new
11
+ end
12
+
13
+ def run!(request)
14
+ players.inject({}) do |responses, player|
15
+ responses[player.name] = player.execute!(request)
16
+ responses
17
+ end
18
+ end
19
+
20
+ def everyone
21
+ players.merge(Players.available)
22
+ self
23
+ end
24
+
25
+ def method_missing(name, *args, &blk)
26
+ if uninvite = UNINVITE_REGEX.match(name)
27
+ name = uninvite.captures.second
28
+ end
29
+
30
+ matched_players = Players.available.select do |player|
31
+ name.to_s.include?(player.name.to_s)
32
+ end
33
+
34
+ return super(name, *args, &blk) if matched_players.empty?
35
+
36
+ if uninvite
37
+ players.subtract(matched_players)
38
+ else
39
+ players.merge(matched_players)
40
+ end
41
+
42
+ self
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class << self
4
+ attr_reader :available
5
+
6
+ def add(klass)
7
+ @available ||= Set.new
8
+
9
+ begin
10
+ klass.dependencies.each do |depedency|
11
+ require depedency
12
+ end
13
+ available.add(klass)
14
+ rescue LoadError
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class Base
4
+ class << self
5
+ attr_reader :name, :dependencies
6
+
7
+ def introducing!(name, dependencies = [])
8
+ @name = name.to_sym
9
+ @dependencies = dependencies
10
+ Players.add(self)
11
+ end
12
+
13
+ def execute!(request)
14
+ new(request).response
15
+ end
16
+ end
17
+
18
+ attr_reader :request
19
+
20
+ def initialize(request)
21
+ @request = request
22
+ end
23
+
24
+ def name
25
+ self.class.name
26
+ end
27
+
28
+ def response
29
+ raise NotImplementedError
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class CurbPlayer < Base
4
+ introducing! :curb, %w[ curb ]
5
+
6
+ def response
7
+ easy = Curl::Easy.new(request.url.to_s)
8
+ easy.headers = request.headers.to_hash
9
+ easy.nosignal = true
10
+
11
+ if [:post, :put].include?(request.method)
12
+ easy.post_body = request.payload
13
+ end
14
+
15
+ easy.http(request.method.to_s.upcase)
16
+ Response.new(easy.response_code, easy.body_str)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class CurlPlayer < Base
4
+ introducing! :curl
5
+
6
+ def response
7
+ output = `curl -isX #{request.method.to_s.upcase} '#{request.url}'`
8
+ code = output.scan(/^HTTP[^\s]*\s(\d+)/).first.first.to_i rescue 0
9
+ body = output.split(/^\s$/, 2).last.try(:strip)
10
+ Response.new(code, body)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class EmHttpRequestPlayer < Base
4
+ introducing! :em_http_request, %w[ em-synchrony em-synchrony/em-http ]
5
+
6
+ def response
7
+ response = nil
8
+ EM.synchrony do
9
+ http_request = EventMachine::HttpRequest.new(request.url)
10
+ http_client = http_request.send(request.method, :body => request.payload, :head => request.headers)
11
+ response = Response.new(http_client.response_header.status, http_client.response)
12
+ EM.stop
13
+ end
14
+ response
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class HTTPClientPlayer < Base
4
+ introducing! :http_client, %w[ httpclient ]
5
+
6
+ def response
7
+ client = HTTPClient.new
8
+ response = client.request(request.method, request.url, nil, request.payload, request.headers)
9
+ Response.new(response.code, response.body)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class HTTPartyPlayer < Base
4
+ introducing! :httparty, %w[ httparty ]
5
+
6
+ def response
7
+ response = HTTParty.send(request.method, request.url, :body => request.payload)
8
+
9
+ Response.new(response.response_code, response.body)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,48 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class LynxPlayer < Base
4
+ introducing! :lynx
5
+
6
+ def response
7
+ output = nil
8
+
9
+ if request.head?
10
+ output = `lynx -head -dump '#{request.url}'`
11
+ elsif request.get?
12
+ output = `lynx -dump '#{request.url}'`
13
+ elsif request.post?
14
+ if request.params.empty?
15
+ raise "This client cannot POST without parameters."
16
+ end
17
+
18
+ form_data = URI.encode_www_form(request.params.each_pair.to_a)
19
+ output = `echo '#{form_data}' | lynx -dump -post_data '#{request.url}'`
20
+ else
21
+ raise "Unsupported HTTP method for this client!"
22
+ end
23
+
24
+ if $? == 0
25
+ code = 200 # probably, right?
26
+
27
+ # Lynx prints headers when you issue -head
28
+ if request.head?
29
+ output = ''
30
+ end
31
+
32
+ Response.new(code, output)
33
+ else
34
+ code = case output
35
+ when /Not Found/
36
+ 404
37
+ when /Internal Server Error/
38
+ 500
39
+ else
40
+ 400 # sure, why not
41
+ end
42
+
43
+ Response.new(code, output)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,49 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+
4
+ module HTTPalooza
5
+ module Players
6
+ class NetHTTPPlayer < Base
7
+ introducing! :net_http
8
+
9
+ def response
10
+ http = Net::HTTP.new(request.url.host, request.url.inferred_port)
11
+
12
+ if request.ssl?
13
+ http.use_ssl = true
14
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
15
+ end
16
+
17
+ net_http_request = net_http_request_class.new(request.url.request_uri)
18
+
19
+ if [:post, :put].include?(request.method)
20
+ net_http_request.body = request.payload
21
+ end
22
+
23
+ (request.headers || {}).each do |key, value|
24
+ net_http_request.send(:[]=, key, value)
25
+ end
26
+
27
+ net_http_response = http.request(net_http_request)
28
+ Response.new(net_http_response.code, net_http_response.body)
29
+ end
30
+
31
+ private
32
+
33
+ def net_http_request_class
34
+ case request.method
35
+ when :get
36
+ Net::HTTP::Get
37
+ when :post
38
+ Net::HTTP::Post
39
+ when :put
40
+ Net::HTTP::Put
41
+ when :delete
42
+ Net::HTTP::Delete
43
+ else
44
+ raise "Unable to process #{request.method} request method"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,14 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class PatronPlayer < Base
4
+ introducing! :patron, %w[ patron ]
5
+
6
+ def response
7
+ session = Patron::Session.new
8
+ session.base_url = request.url
9
+ response = session.get('')
10
+ Response.new(response.status, response.body)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class RestClientPlayer < Base
4
+ introducing! :rest_client, %w[ rest_client ]
5
+
6
+ def response
7
+ response = RestClient::Request.execute(
8
+ :method => request.method,
9
+ :url => request.url.to_s,
10
+ :payload => request.payload,
11
+ :headers => request.headers
12
+ )
13
+ Response.new(response.code, response.to_str)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,116 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class SeleniumPlayer < Base
4
+ introducing! :selenium, %w[ selenium-webdriver ]
5
+
6
+ def response
7
+ if request.method == :get
8
+ get_url
9
+ elsif request.method == :post
10
+ post_html_form
11
+ else
12
+ request_ajax
13
+ end
14
+ ensure
15
+ driver.quit
16
+ end
17
+
18
+ private
19
+
20
+ def driver
21
+ @driver ||= Selenium::WebDriver.for :chrome, :switches => %w[ --disable-web-security ]
22
+ end
23
+
24
+ def get_url
25
+ driver.navigate.to request.url
26
+ Response.new(200, driver.page_source)
27
+ end
28
+
29
+ def post_html_form
30
+ driver.navigate.to "http://example.com"
31
+
32
+ url = driver.current_url
33
+ payload = CGI.parse(payload_to_params)
34
+
35
+ driver.execute_script <<-JAVASCRIPT
36
+ var payload = JSON.parse('#{payload.to_json}');
37
+
38
+ var form = document.createElement('form');
39
+ form.action = #{request.url.to_s.to_json};
40
+ form.method = 'post';
41
+
42
+ for (key in payload) {
43
+ if (payload.hasOwnProperty(key)) {
44
+ for (var i = 0; i < payload[key].length; i++) {
45
+ var value = payload[key][i];
46
+ var input = document.createElement('input');
47
+ input.name = key;
48
+ input.value = payload[key][i];
49
+ form.appendChild(input);
50
+ }
51
+ }
52
+ }
53
+
54
+ document.body.appendChild(form);
55
+ form.submit();
56
+ JAVASCRIPT
57
+
58
+ wait_until_true { driver.current_url != url }
59
+
60
+ Response.new(200, driver.page_source)
61
+ end
62
+
63
+ def request_ajax
64
+ driver.navigate.to "http://example.com"
65
+
66
+ driver.execute_script <<-JAVASCRIPT
67
+ var url = #{request.url.to_s.to_json};
68
+ var method = #{request.method.upcase.to_json};
69
+ var headers = JSON.parse('#{request.headers.to_json}');
70
+ var payload = #{payload_to_params.to_json};
71
+
72
+ var http = new XMLHttpRequest();
73
+ http.open(method, url);
74
+
75
+ for (key in headers) {
76
+ if (headers.hasOwnProperty(key)) {
77
+ http.setRequestHeader(key, headers[key]);
78
+ }
79
+ }
80
+
81
+ http.onreadystatechange = function () {
82
+ if (http.readyState === http.DONE) {
83
+ window.httpalooza_response = [http.status, http.responseText];
84
+ }
85
+ };
86
+
87
+ http.send(payload);
88
+ JAVASCRIPT
89
+
90
+ wait_until_true do
91
+ driver.execute_script "return typeof window.httpalooza_response !== 'undefined'"
92
+ end
93
+
94
+ Response.new(*driver.execute_script("return window.httpalooza_response"))
95
+ end
96
+
97
+ def wait_until_true(timeout: 10, &block)
98
+ Selenium::WebDriver::Wait.new(:timeout => timeout).until(&block)
99
+ end
100
+
101
+ def payload_to_params
102
+ if request.payload.is_a?(Hash)
103
+ request.payload.to_param
104
+ elsif request.payload.is_a?(String)
105
+ begin
106
+ JSON.parse(request.payload).to_param
107
+ rescue JSON::ParserError
108
+ request.payload
109
+ end
110
+ else
111
+ ""
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,62 @@
1
+ require 'open3'
2
+ require 'uri'
3
+
4
+ module HTTPalooza
5
+ module Players
6
+ class TelnetPlayer < Base
7
+ introducing! :telnet
8
+
9
+ def response
10
+ uri = URI::parse(request.url)
11
+
12
+ raise "Unsupported scheme: #{uri.scheme}" unless uri.scheme.to_s.upcase == 'HTTP'
13
+
14
+ Open3.popen3('telnet', uri.host, uri.port.to_s) do |stdin, stdout, stderr, wait_thr|
15
+ begin
16
+ while !stdout.readline.start_with?('Escape character is'); end
17
+
18
+ stdin.write(request_text(uri))
19
+ stdin.flush
20
+
21
+ code = stdout.readline.match(/HTTP\S* (\d+)/)[1].to_i
22
+ while !stdout.readline.strip.empty?; end
23
+ body = stdout.read
24
+
25
+ Response.new(code, body)
26
+ rescue
27
+ Process.kill("TERM", wait_thr.pid) rescue Errno::ESRCH
28
+ raise
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def request_text(uri)
36
+ lines = []
37
+
38
+ path_and_query = uri.path + (uri.query.present? ? "?#{uri.query}" : '')
39
+
40
+ lines << "#{request.method.upcase} #{path_and_query} HTTP/1.1"
41
+ lines << "Host: #{uri.host}"
42
+ lines << 'Connection: close'
43
+ lines << "Content-Length: #{request.payload.bytesize}" if request.payload
44
+
45
+ (request.headers || {}).each do |key, value|
46
+ lines << "#{key}: #{value}"
47
+ end
48
+
49
+ lines << ''
50
+
51
+ if request.payload
52
+ lines << request.payload.to_s
53
+ lines << ''
54
+ end
55
+
56
+ lines << ''
57
+
58
+ lines.join("\n")
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,12 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class TyphoeusPlayer < Base
4
+ introducing! :typhoeus, %w[ typhoeus ]
5
+
6
+ def response
7
+ response = Typhoeus.send(request.method, request.url, :body => request.payload)
8
+ Response.new(response.response_code, response.body)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class UnirestPlayer < Base
4
+ introducing! :unirest, [ 'unirest' ]
5
+
6
+ def response
7
+ response = Unirest::HttpClient.request(request.method, request.url.to_s, request.params, nil)
8
+ Response.new(response.code, response.body)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ module HTTPalooza
2
+ module Players
3
+ class UserBrowserPlayer < Base
4
+ introducing! :user_browser
5
+
6
+ def response
7
+ STDOUT.puts "Please open your web browser and go to the following URL: #{request.url}"
8
+
9
+ prompt = "Do you think the page loaded properly? (y/n/maybe): "
10
+ STDOUT.print(prompt)
11
+ while answer = STDIN.gets.chomp
12
+ case answer
13
+ when /y/i
14
+ code = 200
15
+ break
16
+ when /n/i
17
+ code = 404
18
+ break
19
+ else
20
+ STDOUT.print(prompt)
21
+ end
22
+ end
23
+
24
+ STDOUT.puts "View the source of the page, then copy and paste the whole source here (^D when finished)."
25
+ body = STDIN.read
26
+ STDOUT.puts "\n\n"
27
+
28
+ Response.new(code, body)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ module HTTPalooza
2
+ class Request
3
+ STANDARD_METHODS = [:get, :post, :put, :patch, :delete, :options, :head]
4
+
5
+ attr_reader :url, :method, :params, :payload, :headers
6
+
7
+ def initialize(url, method, options = {})
8
+ @url = url
9
+ @method = method
10
+ @params = options[:params] || {}
11
+ @payload = options[:payload]
12
+ @headers = Rack::Utils::HeaderHash.new(options[:headers] || {})
13
+
14
+ normalize_url!
15
+ end
16
+
17
+ def ssl?
18
+ !!(url.to_s =~ /^https/)
19
+ end
20
+
21
+ STANDARD_METHODS.each do |verb|
22
+ define_method(:"#{verb}?") do
23
+ method == verb
24
+ end
25
+ end
26
+
27
+ private
28
+ def normalize_url!
29
+ raise ArgumentError, "Invalid URL: #{url}" unless url.to_s =~ /^http/
30
+ @url = url.kind_of?(Addressable::URI) ? url : Addressable::URI.parse(url)
31
+ @url.query_values = (@url.query_values || {}).merge(params)
32
+ @url.normalize!
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ module HTTPalooza
2
+ class Response
3
+ AwesomeResponseCodes = 200..299
4
+
5
+ attr_accessor :code, :body
6
+
7
+ def initialize(code, body)
8
+ @code = code.to_i
9
+ @body = body
10
+ end
11
+
12
+ def awesome?
13
+ AwesomeResponseCodes.include?(code)
14
+ end
15
+
16
+ def not_awesome?
17
+ !awesome?
18
+ end
19
+
20
+ def inspect
21
+ "<HTTPalooza::Response:#{object_id} code=#{code} body=#{body.to_s.inspect.truncate(30)}"
22
+ end
23
+
24
+ def eql?(other)
25
+ self.class == other.class && code == other.code && body == other.body
26
+ end
27
+
28
+ alias_method :==, :eql?
29
+
30
+ def hash
31
+ body.hash ^ code.hash
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module HTTPalooza
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,314 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: httpalooza
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Quin Hoxie
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: addressable
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: curb
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: typhoeus
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: patron
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: httpclient
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rest-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: unirest
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: em-synchrony
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: em-http-request
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: selenium-webdriver
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: chromedriver-helper
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: awesome_print
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: bundler
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '1.8'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '1.8'
223
+ - !ruby/object:Gem::Dependency
224
+ name: rake
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '10.0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '10.0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: rspec
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: 3.4.0
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: 3.4.0
251
+ description:
252
+ email:
253
+ - qhoxie@gmail.com
254
+ executables: []
255
+ extensions: []
256
+ extra_rdoc_files: []
257
+ files:
258
+ - ".gitignore"
259
+ - ".rspec"
260
+ - ".travis.yml"
261
+ - Gemfile
262
+ - LICENSE.txt
263
+ - README.md
264
+ - Rakefile
265
+ - bin/console
266
+ - bin/setup
267
+ - httpalooza.gemspec
268
+ - lib/httpalooza.rb
269
+ - lib/httpalooza/api.rb
270
+ - lib/httpalooza/lineup.rb
271
+ - lib/httpalooza/players.rb
272
+ - lib/httpalooza/players/base.rb
273
+ - lib/httpalooza/players/curb.rb
274
+ - lib/httpalooza/players/curl.rb
275
+ - lib/httpalooza/players/em_http_request.rb
276
+ - lib/httpalooza/players/http_client.rb
277
+ - lib/httpalooza/players/http_party.rb
278
+ - lib/httpalooza/players/lynx.rb
279
+ - lib/httpalooza/players/net_http.rb
280
+ - lib/httpalooza/players/patron.rb
281
+ - lib/httpalooza/players/rest_client.rb
282
+ - lib/httpalooza/players/selenium.rb
283
+ - lib/httpalooza/players/telnet.rb
284
+ - lib/httpalooza/players/typhoeus.rb
285
+ - lib/httpalooza/players/unirest.rb
286
+ - lib/httpalooza/players/user_browser.rb
287
+ - lib/httpalooza/request.rb
288
+ - lib/httpalooza/response.rb
289
+ - lib/httpalooza/version.rb
290
+ homepage: http://httpalooza.com/
291
+ licenses:
292
+ - MIT
293
+ metadata: {}
294
+ post_install_message: HTTPalooza! Ruby's greatest HTTP clients, on stage together.
295
+ rdoc_options: []
296
+ require_paths:
297
+ - lib
298
+ required_ruby_version: !ruby/object:Gem::Requirement
299
+ requirements:
300
+ - - ">="
301
+ - !ruby/object:Gem::Version
302
+ version: '0'
303
+ required_rubygems_version: !ruby/object:Gem::Requirement
304
+ requirements:
305
+ - - ">="
306
+ - !ruby/object:Gem::Version
307
+ version: '0'
308
+ requirements: []
309
+ rubyforge_project:
310
+ rubygems_version: 2.4.8
311
+ signing_key:
312
+ specification_version: 4
313
+ summary: HTTPalooza brings together the best Ruby HTTP clients on one stage.
314
+ test_files: []