dagger 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/bin/dagger +29 -0
- data/dagger.gemspec +21 -0
- data/lib/dagger.rb +126 -0
- data/lib/dagger/parsers.rb +20 -0
- data/lib/dagger/response.rb +44 -0
- data/lib/dagger/version.rb +7 -0
- data/test/requests_spec.rb +48 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0cafd73f6378598d9ce5a095b498f19239d8bf23
|
4
|
+
data.tar.gz: 11dd75fb2942eb8da1f6cdcb53f33000478157f1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 00aa7321875d852c6e7daad0312371455566630a7af8f21e35d011a7c9c8258c86e7956eab77baad47002585b34da8764a1cd700ac2d7191394cbc4953e14408
|
7
|
+
data.tar.gz: 53677a981090e05d60c13c082eaa9e4571014c24d22df7d09e6ba4d1613f21186d3a8411ef47a39c4a530391f4c0a452a5b8c2501cfa9d27a2db0f04de568743
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/Gemfile
ADDED
data/Rakefile
ADDED
data/bin/dagger
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'dagger'
|
4
|
+
|
5
|
+
method = ARGV[0] or abort "Usage: dagger [method] [url] [data]"
|
6
|
+
|
7
|
+
if ARGV[1].nil?
|
8
|
+
method = 'get'
|
9
|
+
else
|
10
|
+
method = ARGV.shift
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_data(str)
|
14
|
+
{} # not ready yet.
|
15
|
+
end
|
16
|
+
|
17
|
+
url = ARGV[0]
|
18
|
+
data = parse_data(ARGV[1])
|
19
|
+
|
20
|
+
options = {
|
21
|
+
:follow => true
|
22
|
+
}
|
23
|
+
|
24
|
+
# puts "#{method} #{url}"
|
25
|
+
resp = Dagger.send(method, url, data, options)
|
26
|
+
|
27
|
+
# puts resp.status
|
28
|
+
# puts resp.headers
|
29
|
+
puts resp.body
|
data/dagger.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/dagger/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "dagger"
|
6
|
+
s.version = Dagger::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Tomás Pollak']
|
9
|
+
s.email = ['tomas@forkhq.com']
|
10
|
+
s.homepage = "https://github.com/tomas/dagger"
|
11
|
+
s.summary = "Simplified Net::HTTP wrapper."
|
12
|
+
s.description = "Dagger.post(url, params).body"
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
s.rubyforge_project = "dagger"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
19
|
+
s.require_path = 'lib'
|
20
|
+
# s.bindir = 'bin'
|
21
|
+
end
|
data/lib/dagger.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# Dagger.
|
2
|
+
# Simple Net::HTTP wrapper (in less than 100 LOC)
|
3
|
+
# Written by Tomas Pollak
|
4
|
+
|
5
|
+
# Example Usage ---------------------------------
|
6
|
+
#
|
7
|
+
# resp, body = Dagger.get('http://google.com')
|
8
|
+
# puts body if resp.code == 200
|
9
|
+
#
|
10
|
+
# opts = { username: 'foobar', password: 'secret' }
|
11
|
+
# resp, body = Dagger.get('http://api.server.com', opts)
|
12
|
+
#
|
13
|
+
# opts = { verify_ssl: false, open_timeout: 30 }
|
14
|
+
# resp, body = Dagger.post('http://twitter.com', { foo: 'bar' }, opts)
|
15
|
+
|
16
|
+
require 'dagger/version'
|
17
|
+
require 'dagger/response'
|
18
|
+
require 'dagger/parsers'
|
19
|
+
|
20
|
+
require 'net/https'
|
21
|
+
require 'base64'
|
22
|
+
|
23
|
+
module Dagger
|
24
|
+
|
25
|
+
DEFAULT_HEADERS = {
|
26
|
+
'User-Agent' => "Dagger/#{VERSION} (Ruby Net::HTTP Wrapper, like curl)"
|
27
|
+
}
|
28
|
+
|
29
|
+
def self.get(uri, query = nil, opts = {})
|
30
|
+
raise ArgumentError.new("Empty URL!") if (uri || '').strip == ''
|
31
|
+
|
32
|
+
opts[:follow] = 10 if opts[:follow] == true
|
33
|
+
uri = parse_uri(uri)
|
34
|
+
uri.query = encode(opts[:query]) if opts[:query]
|
35
|
+
|
36
|
+
http = client(uri, opts)
|
37
|
+
request = Net::HTTP::Get.new(uri.request_uri, DEFAULT_HEADERS.merge(opts[:headers] || {}))
|
38
|
+
|
39
|
+
if opts[:username] && opts[:password]
|
40
|
+
request.basic_auth(opts.delete(:username), opts.delete(:password))
|
41
|
+
end
|
42
|
+
|
43
|
+
resp, data = http.request(request)
|
44
|
+
|
45
|
+
if [301,302].include?(resp.code.to_i) && resp['Location'] && (opts[:follow] && opts[:follow] > 0)
|
46
|
+
opts[:follow] -= 1
|
47
|
+
return get(resp['Location'], nil, opts)
|
48
|
+
end
|
49
|
+
|
50
|
+
build_response(resp, data || resp.body) # 1.8 vs 1.9 style responses
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.post(uri, params = {}, options = {})
|
54
|
+
request('post', uri, params, options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.put(uri, params = {}, options = {})
|
58
|
+
request('put', uri, params, options)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.delete(uri, params = {}, options = {})
|
62
|
+
request('delete', uri, params, options)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.request(method, url, params = {}, options = {})
|
66
|
+
return get(url, options) if method.to_s.downcase == 'get'
|
67
|
+
request(method.to_s.downcase, url, params, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def self.request(method, uri, params, opts = {})
|
73
|
+
# raise "Params should be a hash." unless params.is_a?(Hash)
|
74
|
+
uri = parse_uri(uri)
|
75
|
+
query = params.is_a?(String) ? params : encode(params)
|
76
|
+
|
77
|
+
headers = opts[:headers] || {}
|
78
|
+
|
79
|
+
if opts[:username] && opts[:password]
|
80
|
+
headers['Authorization'] = "Basic " + Base64.encode64("#{opts[:username]}:#{opts[:password]}")
|
81
|
+
end
|
82
|
+
|
83
|
+
args = [method, uri.path, query, headers]
|
84
|
+
args.delete_at(2) if method.to_s == 'delete' # Net::HTTP's delete does not accept data
|
85
|
+
|
86
|
+
resp, data = client(uri, opts).send(*args)
|
87
|
+
build_response(resp, data || resp.body) # 1.8 vs 1.9 style responses
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.build_response(resp, body)
|
91
|
+
resp.extend(Response)
|
92
|
+
resp.set_body(body) unless resp.body
|
93
|
+
resp
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.client(uri, opts = {})
|
97
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
98
|
+
http.open_timeout = opts[:open_timeout] if opts[:open_timeout]
|
99
|
+
http.read_timeout = opts[:read_timeout] if opts[:read_timeout]
|
100
|
+
http.use_ssl = true if uri.port == 443
|
101
|
+
http.verify_mode = opts[:verify_ssl] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
102
|
+
http
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.parse_uri(uri)
|
106
|
+
uri = 'http://' + uri unless uri.to_s['http']
|
107
|
+
uri = URI.parse(uri)
|
108
|
+
uri.path = '/' if uri.path == ''
|
109
|
+
uri
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.encode(value, key = nil)
|
113
|
+
case value
|
114
|
+
when Hash then value.map { |k,v| encode(v, append_key(key,k)) }.join('&')
|
115
|
+
when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
|
116
|
+
when nil then ''
|
117
|
+
else
|
118
|
+
"#{key}=#{URI.escape(value.to_s)}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.append_key(root_key, key)
|
123
|
+
root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Parsers
|
4
|
+
|
5
|
+
def initialize(response)
|
6
|
+
@body = response.body
|
7
|
+
@normalized = response.content_type.to_s.sub('/', '_')
|
8
|
+
end
|
9
|
+
|
10
|
+
def process
|
11
|
+
send(@normalized, @body) if respond_to?(@normalized)
|
12
|
+
end
|
13
|
+
|
14
|
+
def application_json(body)
|
15
|
+
JSON.parse(body)
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :text_javascript, :application_json
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Dagger
|
2
|
+
|
3
|
+
module Response
|
4
|
+
|
5
|
+
attr_reader :body
|
6
|
+
|
7
|
+
def self.extended(base)
|
8
|
+
# puts base.inspect
|
9
|
+
end
|
10
|
+
|
11
|
+
def set_body(string)
|
12
|
+
raise "Body is set!" if body
|
13
|
+
@body = string
|
14
|
+
end
|
15
|
+
|
16
|
+
def headers
|
17
|
+
to_hash # from Net::HTTPHeader module
|
18
|
+
end
|
19
|
+
|
20
|
+
def code
|
21
|
+
super.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def content_type
|
25
|
+
self['Content-Type']
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method :status, :code
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
body.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_a
|
35
|
+
[code, headers, to_s]
|
36
|
+
end
|
37
|
+
|
38
|
+
def data
|
39
|
+
@data ||= Parsers.new(self).process || body
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require './lib/dagger'
|
2
|
+
|
3
|
+
require 'rspec/mocks'
|
4
|
+
require 'rspec/expectations'
|
5
|
+
|
6
|
+
describe 'Requests' do
|
7
|
+
|
8
|
+
describe '.get' do
|
9
|
+
|
10
|
+
def send_request(url)
|
11
|
+
Dagger.get(url)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'empty url' do
|
15
|
+
|
16
|
+
it 'raises error' do
|
17
|
+
expect { send_request('') }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'invalid URL' do
|
23
|
+
|
24
|
+
it 'raises error' do
|
25
|
+
expect { send_request('asd123.rewqw') }.to raise_error(SocketError)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'nonexisting host' do
|
31
|
+
|
32
|
+
it 'raises error' do
|
33
|
+
expect { send_request('http://www.foobar1234567890foobar.com/hello') }.to raise_error(SocketError)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'valid host' do
|
39
|
+
|
40
|
+
it 'works' do
|
41
|
+
expect { send_request('http://www.google.com') }.not_to raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dagger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tomás Pollak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Dagger.post(url, params).body
|
14
|
+
email:
|
15
|
+
- tomas@forkhq.com
|
16
|
+
executables:
|
17
|
+
- dagger
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- ".gitignore"
|
22
|
+
- Gemfile
|
23
|
+
- Rakefile
|
24
|
+
- bin/dagger
|
25
|
+
- dagger.gemspec
|
26
|
+
- lib/dagger.rb
|
27
|
+
- lib/dagger/parsers.rb
|
28
|
+
- lib/dagger/response.rb
|
29
|
+
- lib/dagger/version.rb
|
30
|
+
- test/requests_spec.rb
|
31
|
+
homepage: https://github.com/tomas/dagger
|
32
|
+
licenses: []
|
33
|
+
metadata: {}
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.6
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project: dagger
|
50
|
+
rubygems_version: 2.2.0
|
51
|
+
signing_key:
|
52
|
+
specification_version: 4
|
53
|
+
summary: Simplified Net::HTTP wrapper.
|
54
|
+
test_files: []
|