req 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzlmZDE1M2FiNzMwN2U3YzRkNTg0YjFmMGIxZTk0ODg5YjU5MzE3ZQ==
5
+ data.tar.gz: !binary |-
6
+ OTk0NzIxZmYxNTUyYTVmZGUwYzgyYjI5ZjMyMmM4YmFiMjMxMzk2Mg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZmQ4MDllNTBmMGMzNjc3NGNjYzAxODY2NjY4ZDFhMTE4ZTI3OTE3NDY4OWRk
10
+ ZTMwZDg3MGYyZDYyYmQzNDY1MzM3NzExOWY0ODQ4NmEyMzE5MmI1YzI3ZjEz
11
+ MzhkMGNmM2M0YzU3ZTllZTk3ZDgzODNmNTI4YzliYmJiZjkzNmM=
12
+ data.tar.gz: !binary |-
13
+ MjhmMzNlZDA2MzM0OWEyYjAzMjk5M2U1YzYyYzA4Y2FjZTJiNDA0OTY1ZWRk
14
+ OTA2NTFmZGViM2RiMjMzZjhmOWVjNjE4NDI2ZGU0ZjM0NmJlYzE1ZTA2OGUz
15
+ YjdjYjMxZjA0ZTE5MGZlZDcwN2ZmZGE0M2QyMTQ5N2FiMjk2YzE=
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in request.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 wenjun.yan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,72 @@
1
+ # Req
2
+ MAKE SIMPLE REQUEST SIMPLE.
3
+
4
+ A simple http/net wrapper to make http request easy.
5
+
6
+ Inspired by request.js
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'req'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install req
21
+
22
+ ## Usage
23
+
24
+ > How to fork it?
25
+
26
+ ```ruby
27
+ Req["https://api.github.com/repo/v2e4lisp/req/forks"].auth("user", "pass").post
28
+ ```
29
+
30
+ > Send data(get).
31
+
32
+ ```ruby
33
+ Req[url].send(a: 1, b: 2).get
34
+ ```
35
+
36
+ > Post json
37
+
38
+ ```ruby
39
+ Req[url].send(a: 1, b: 2).send(c: 3).type(:json).post
40
+ ```
41
+
42
+ > Post form
43
+
44
+ ```ruby
45
+ Req[url].send(field1: "username").send(field2: "password").type(:form).post
46
+ ```
47
+
48
+ > Post form with file(multipart form)
49
+
50
+ ```ruby
51
+ Req[url].send(field1: "username").send("file", csv_file, "optional-filename").post
52
+ ```
53
+
54
+ > some other simple API
55
+
56
+ * write(string): write to body
57
+ * header(hash) : write to header
58
+ * reset : reset body and header
59
+ * get(n) : get with redirection limit default is 4
60
+ * use_ssl(bool): turn on/off ssl. It will be auto turned on when scheme is "https"
61
+ * mulit(bool) : multipart form header. Auto turned on when files detected
62
+ * type() : specify content-type (:text,:json,:html,:xml,:form)
63
+
64
+
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Req
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,16 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'base64'
4
+ require 'mime/types'
5
+ require "req/version"
6
+ require "req/query"
7
+ require "req/part"
8
+ require "req/client"
9
+
10
+ module Req
11
+ class << self
12
+ def [](url)
13
+ Client.new(url)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,167 @@
1
+ module Req
2
+ TYPE = {json: 'application/json',
3
+ form: 'application/x-www-form-urlencoded',
4
+ text: 'text/plain',
5
+ html: 'text/html',
6
+ xml: 'application/xml'}
7
+
8
+ class Client
9
+ attr_accessor :data, :files, :body, :headers
10
+ attr_reader :client, :url
11
+
12
+ def initialize(url)
13
+ self.url = url
14
+ @data = {}
15
+ @headers = {}
16
+ @files = []
17
+ @body = ''
18
+ @client = Net::HTTP.new(uri.hostname, uri.port)
19
+ use_ssl if uri.scheme == "https"
20
+ end
21
+
22
+ def get limit=4
23
+ update_uri
24
+ res = client.get(uri.request_uri, headers)
25
+ limit.times do
26
+ break unless res.is_a? Net::HTTPRedirection
27
+ # reset url and http client in case of the url scheme changed
28
+ # if no location found, Invalid response! CRUSH DOWN.
29
+ self.url = res['location']
30
+ @client = Net::HTTP.new(uri.hostname, uri.port)
31
+ use_ssl if uri.scheme == "https"
32
+ res = client.get(res['location'], headers)
33
+ end
34
+ block_given? ? yield(res) : res
35
+ end
36
+
37
+ # http verbs
38
+ [:head, :delete, :options].each do |method|
39
+ define_method method do |&block|
40
+ update_uri
41
+ res = client.send(method, uri.request_uri, headers)
42
+ block ? block.call(res) : res
43
+ end
44
+ end
45
+
46
+ [:post, :put, :patch].each do |method|
47
+ define_method method do |&block|
48
+ build
49
+ res = client.send(method, uri.request_uri, body, headers)
50
+ block ? block.call(res) : res
51
+ end
52
+ end
53
+
54
+ def use_ssl use=true
55
+ client.use_ssl = use
56
+ self
57
+ end
58
+
59
+ # basic authentication
60
+ def auth user, pass
61
+ set "Authorization" => "Basic #{Base64.encode64(user + ":" + pass).chop}"
62
+ end
63
+
64
+ def send name, file=nil, filename=nil
65
+ if file
66
+ upload name, file, filename
67
+ else
68
+ query name
69
+ end
70
+ end
71
+
72
+ def upload field, file, filename = nil
73
+ file = File.open(file)
74
+ @files << [field, file, filename || file.path]
75
+ self
76
+ end
77
+ alias_method :attach, :upload
78
+
79
+ def query option
80
+ data.merge! option
81
+ self
82
+ end
83
+
84
+ def header option
85
+ headers.merge! option
86
+ self
87
+ end
88
+ alias_method :set, :header
89
+
90
+ def write body
91
+ @body << body
92
+ self
93
+ end
94
+
95
+ def type t
96
+ # Set `Content-Type` header
97
+ tp = t.to_sym
98
+ t = TYPE[tp] if TYPE[tp]
99
+ set "Content-Type" => t
100
+ end
101
+
102
+ def multi on=true
103
+ @multi = on
104
+ self
105
+ end
106
+
107
+ def clear
108
+ @data = {}
109
+ @headers = {}
110
+ @files = []
111
+ @body = ''
112
+ self
113
+ end
114
+ alias_method :reset, :clear
115
+
116
+ private
117
+
118
+ def build
119
+ if not files.empty? or @multi
120
+ build_multipart
121
+ else
122
+ build_body
123
+ end
124
+ build_header
125
+ end
126
+
127
+ def build_header
128
+ return if headers['Content-Length']
129
+ headers['Content-Length'] = body.bytesize.to_s
130
+ end
131
+
132
+ def build_body
133
+ case headers['Content-Type']
134
+ when nil, TYPE[:form] then write data.to_query
135
+ when TYPE[:json] then write data.to_json
136
+ end
137
+ end
138
+
139
+ def build_multipart
140
+ m = Multipart.create(files, data)
141
+ write m.body
142
+ header m.header
143
+ end
144
+
145
+ def update_uri
146
+ unless data.empty?
147
+ url << "?" unless url["?"]
148
+ url << data.to_query
149
+ @uri = nil
150
+ end
151
+ end
152
+
153
+ def uri
154
+ @uri ||= URI(url).tap do |u|
155
+ # If the url is something like this: http://user:password@localhost",
156
+ # we setup the basic authorization header.
157
+ auth(u.user, u.password) if u.user and u.password
158
+ end
159
+ end
160
+
161
+ # if not schema is given, default is `http`
162
+ def url= url
163
+ @uri = nil
164
+ @url = (url['://'] ? '' : 'http://') << url
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,53 @@
1
+ module Req
2
+ module Multipart
3
+ BOUNDARY = "--ruby-request--"
4
+ DEFAULT_MIME = "application/octet-stream"
5
+
6
+ def self.create files, data
7
+ Fields.new(files, data)
8
+ end
9
+
10
+ class Fields
11
+ def initialize files, data
12
+ @files = files || []
13
+ @params = data || []
14
+ end
15
+
16
+ def body
17
+ @body ||= '' << @files.inject("") { |acc, file|
18
+ acc << Attachment.new(*file).part
19
+ } << @params.inject("") { |acc, param|
20
+ acc << Param.new(*param).part
21
+ } << "--#{BOUNDARY}--\r\n\r\n"
22
+ end
23
+
24
+ def header
25
+ @header ||= {"Content-Length" => @body.bytesize.to_s,
26
+ "Content-Type" => "multipart/form-data; boundary=#{BOUNDARY}"}
27
+ end
28
+ end
29
+
30
+ class Attachment < Struct.new(:field, :file, :filename)
31
+ def part
32
+ return @part if @part
33
+ type = ::MIME::Types.type_for(filename).first || DEFAULT_MIME
34
+ @part = ''
35
+ @part << "--#{BOUNDARY}\r\n"
36
+ @part << "Content-Disposition: form-data; name=\"#{field}\"; filename=\"#{filename}\"\r\n"
37
+ @part << "Content-Type: #{type}\r\n\r\n"
38
+ @part << "#{file.read}\r\n"
39
+ end
40
+ end
41
+
42
+ class Param < Struct.new(:field, :value)
43
+ def part
44
+ return @part if @part
45
+ @part = ''
46
+ @part << "--#{BOUNDARY}\r\n"
47
+ @part << "Content-Disposition: form-data; name=\"#{field}\"\r\n"
48
+ @part << "\r\n"
49
+ @part << "#{value}\r\n"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,75 @@
1
+ # FOLLOWING CODE IS FROM `rails/activesupport'
2
+ class Object
3
+ # Alias of <tt>to_s</tt>.
4
+ def to_param
5
+ to_s
6
+ end
7
+
8
+ # Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
9
+ # param name.
10
+ #
11
+ # Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
12
+ def to_query(key)
13
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
14
+ "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
15
+ end
16
+ end
17
+
18
+ class NilClass
19
+ def to_param
20
+ self
21
+ end
22
+ end
23
+
24
+ class TrueClass
25
+ def to_param
26
+ self
27
+ end
28
+ end
29
+
30
+ class FalseClass
31
+ def to_param
32
+ self
33
+ end
34
+ end
35
+
36
+ class Array
37
+ # Calls <tt>to_param</tt> on all its elements and joins the result with
38
+ # slashes. This is used by <tt>url_for</tt> in Action Pack.
39
+ def to_param
40
+ collect { |e| e.to_param }.join '/'
41
+ end
42
+
43
+ # Converts an array into a string suitable for use as a URL query string,
44
+ # using the given +key+ as the param name.
45
+ #
46
+ # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
47
+ def to_query(key)
48
+ prefix = "#{key}[]"
49
+ collect { |value| value.to_query(prefix) }.join '&'
50
+ end
51
+ end
52
+
53
+ class Hash
54
+ # Returns a string representation of the receiver suitable for use as a URL
55
+ # query string:
56
+ #
57
+ # {:name => 'David', :nationality => 'Danish'}.to_param
58
+ # # => "name=David&nationality=Danish"
59
+ #
60
+ # An optional namespace can be passed to enclose the param names:
61
+ #
62
+ # {:name => 'David', :nationality => 'Danish'}.to_param('user')
63
+ # # => "user[name]=David&user[nationality]=Danish"
64
+ #
65
+ # The string pairs "key=value" that conform the query string
66
+ # are sorted lexicographically in ascending order.
67
+ #
68
+ # This method is also aliased as +to_query+.
69
+ def to_param(namespace = nil)
70
+ collect do |key, value|
71
+ value.to_query(namespace ? "#{namespace}[#{key}]" : key)
72
+ end.sort * '&'
73
+ end
74
+ alias_method :to_query, :to_param
75
+ end
@@ -0,0 +1,3 @@
1
+ module Req
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'req/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "req"
8
+ spec.version = Req::VERSION
9
+ spec.authors = ["wenjun.yan"]
10
+ spec.email = ["mylastnameisyan@gmail.com"]
11
+ spec.description = %q{an easy way to deal with simple http request}
12
+ spec.summary = %q{FORK ME => Req["https://api.github.com/repo/v2e4lisp/req/forks"].auth("user", "pass").post }
13
+ spec.homepage = "https://github.com/v2e4lisp/req"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "mime-types"
22
+ spec.add_dependency "json"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ spec.add_development_dependency 'sinatra'
29
+ spec.add_development_dependency 'sinatra-contrib'
30
+ end
@@ -0,0 +1,108 @@
1
+ require 'sinatra'
2
+ require "sinatra/multi_route"
3
+ require "sinatra/cookies"
4
+ require 'json'
5
+
6
+ def header_titleize header
7
+ header.split("_").map {|w| w.capitalize }.join "-"
8
+ end
9
+
10
+ class Httpbin < Sinatra::Base
11
+ register Sinatra::MultiRoute
12
+ helpers Sinatra::Cookies
13
+ include FileUtils::Verbose
14
+
15
+ def authorized? user="test", pass="test"
16
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
17
+ @auth.provided? &&
18
+ @auth.basic? &&
19
+ @auth.credentials &&
20
+ @auth.credentials == [user, pass]
21
+ end
22
+
23
+ def echo
24
+ request.env.inject({}) { |acc, item|
25
+ acc.tap do |result|
26
+ if item[0]["HTTP_"]
27
+ result[header_titleize(item[0].gsub(/^HTTP_/, ""))] = item[1]
28
+ end
29
+ end
30
+ }.tap {|header|
31
+ header["Content-Type"] = env["CONTENT_TYPE"] if env["CONTENT_TYPE"]
32
+ }.to_json
33
+ end
34
+
35
+ def data
36
+ if request.env["CONTENT_TYPE"] == "application/json"
37
+ request.body
38
+ else
39
+ params.to_json
40
+ end
41
+ end
42
+
43
+ def render_cookies
44
+ cookies.to_hash.to_json
45
+ end
46
+
47
+ before '/auth*' do
48
+ path = params[:splat].first
49
+ user, pass = path["/"] ? path[1..-1].split("/") : ["test", "test"]
50
+ unless authorized? user, pass
51
+ response['WWW-Authenticate'] = %(Basic realm="Restricted Area")
52
+ throw(:halt, [401, "Oops... we need your login name & password\n"])
53
+ end
54
+ end
55
+
56
+ get "/cookie" do
57
+ render_cookies
58
+ end
59
+
60
+ get "/cookie/delete/:name" do
61
+ #response.delete_cookie params[:name]
62
+ response.set_cookie(params[:name],
63
+ value: "",
64
+ path: "/cookie",
65
+ :expires => Time.now - 3600*24)
66
+ params[:name]
67
+ end
68
+
69
+ get "/cookie/:name/:value" do
70
+ response.set_cookie(params[:name],
71
+ value: params[:value],
72
+ path: "/cookie")
73
+ render_cookies
74
+ end
75
+
76
+ get "/upload" do
77
+ <<-FORM
78
+ <form action='/upload' enctype="multipart/form-data" method='post'>
79
+ <input name="file" type="file" />
80
+ <input name="var" type="text" />
81
+ <input type="submit" value="Upload" />
82
+ </form>
83
+ FORM
84
+ end
85
+
86
+ route :post, :put, "/upload" do
87
+ params[:file][:tempfile].read
88
+ # request.body
89
+ end
90
+
91
+ route :get, :post, :put, :patch, :delete, "/auth" do
92
+ data
93
+ end
94
+
95
+ route :get, :post, :put, :patch, :delete, "/auth/:user/:pass" do
96
+ data
97
+ end
98
+
99
+ route :get, :post, :put, :patch, :delete, "/headers" do
100
+ echo
101
+ end
102
+
103
+ route :get, :post, :put, :patch, :delete, "/" do
104
+ data
105
+ end
106
+ end
107
+
108
+ Httpbin.run!
@@ -0,0 +1,32 @@
1
+ require "./spec_helper"
2
+ include Helpers
3
+
4
+ describe "basic auth" do
5
+ describe "using auth method for basic authentication" do
6
+ url = base + "/auth"
7
+ it "should return ok" do
8
+ req = request(url).auth("test", "test")
9
+ request(url).auth("test", "test").get.body.should eq("{}")
10
+ end
11
+
12
+ it "should fail when no user or password" do
13
+ request(url).get.should respond_status(401)
14
+ end
15
+
16
+ it "should fail when invalid user and password" do
17
+ request(url).auth("fake", "test").get.should respond_status(401)
18
+ end
19
+ end
20
+
21
+ describe "using url for basic authentication" do
22
+ it "should return ok" do
23
+ url = "http://test:test@localhost:4567/auth"
24
+ request(url).get.body.should eq("{}")
25
+ end
26
+
27
+ it "should fail when invalid user and password" do
28
+ url = "http://fake:test@localhost:4567/auth"
29
+ request(url).get.should respond_status(401)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ require "./spec_helper"
2
+
3
+ describe "Get from localhost:4567" do
4
+ url = base
5
+ it "should success" do
6
+ request(url).get.should respond_status(200)
7
+ end
8
+
9
+ it "should return the query data" do
10
+ query = "x=1"
11
+ request("#{url}?#{query}").get.body.from_json.should eq({"x" => "1"})
12
+ end
13
+
14
+ describe "Using query or send to set query data" do
15
+ it "Set data in one query" do
16
+ request(url).send(hello: "x", world: 1).get.body.from_json
17
+ .should eq({"hello" => "x", "world" => "1"})
18
+ end
19
+
20
+ it "Multiple query call will merge the data" do
21
+ request(url).send(hello: "x").send(world: 1).get.body.from_json
22
+ .should eq({"hello" => "x", "world" => "1"})
23
+ request(url).query(hello: "x").query(world: 1).get.body.from_json
24
+ .should eq({"hello" => "x", "world" => "1"})
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ require "./spec_helper"
2
+ include Helpers
3
+
4
+ describe "Request.header" do
5
+ url = base + "/headers"
6
+
7
+ it "set multiple header" do
8
+ request(url).header("X-1" => "x1").header("X-2" => "x2").get
9
+ .should send_header("X-1" => "x1","X-2" => "x2")
10
+ end
11
+
12
+ describe "Content-Type" do
13
+ describe "#header" do
14
+ it "set to application/json" do
15
+ request(url).header("Content-Type" => "xxx").post
16
+ .should send_header("content-type" => "xxx")
17
+ end
18
+ end
19
+
20
+ describe "#type" do
21
+ it "set Content-Type to customized type" do
22
+ request(url).type("xxx").post
23
+ .should send_header("content-type" => "xxx")
24
+ end
25
+
26
+ it "set Content-Type to text/html" do
27
+ request(url).type(:html).post
28
+ .should send_header("content-type" => "text/html")
29
+ end
30
+
31
+ it "set Content-Type to application/json" do
32
+ request(url).type(:json).post
33
+ .should send_header("content-type" => "application/json")
34
+ end
35
+
36
+ it "set Content-Type to application/x-www-form-urlencoded" do
37
+ request(url).type(:form).post
38
+ .should send_header("content-type" =>
39
+ "application/x-www-form-urlencoded")
40
+ end
41
+
42
+ it "set Content-Type to application/xml" do
43
+ request(url).type(:xml).post
44
+ .should send_header("content-type" => "application/xml")
45
+ end
46
+
47
+ it "set Content-Type to text/plain" do
48
+ request(url).type(:text).post
49
+ .should send_header("content-type" => "text/plain")
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ require "./spec_helper"
2
+
3
+ describe "Post to localhost:4567" do
4
+ url = base
5
+ query = {"x" => 1}
6
+
7
+ it "should success" do
8
+ request(url).post.should respond_status(200)
9
+ end
10
+
11
+ describe "Post form" do
12
+ context "with param" do
13
+ it "should return the same query data" do
14
+ request(url).query(query).post.body.from_json.should eq({"x" => "1"})
15
+ end
16
+ end
17
+ context "with file" do
18
+ it "should return the same text in the uploaded file" do
19
+ text = "uploading"
20
+ tmpfile = "./tmp.txt"
21
+ File.open(tmpfile, "w") { |f| f << text }
22
+ request(url + "/upload").upload("file", tmpfile)
23
+ .post.body.should eq(text)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "Post json" do
29
+ it "should reutrn the same json data" do
30
+ request(url).query(query).type(:json).post.body.from_json.should eq(query)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ require "./spec_helper"
2
+
3
+ describe "schema" do
4
+ describe "without a schema defualt is http" do
5
+ it "should be ok" do
6
+ request("localhost:4567").get.should respond_status(200)
7
+ end
8
+ end
9
+
10
+ describe "https and ssl" do
11
+ # todo
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ require '../lib/req.rb'
2
+ require "json"
3
+
4
+ class String
5
+ def from_json
6
+ JSON.parse self
7
+ end
8
+ end
9
+
10
+ def base
11
+ "http://localhost:4567"
12
+ end
13
+
14
+ # API
15
+ def request url
16
+ Req::Client.new(url)
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ end
21
+
22
+ module Helpers
23
+ extend RSpec::Matchers::DSL
24
+ matcher :respond_status do |code|
25
+ match do |actual|
26
+ actual.code.to_i == code.to_i
27
+ end
28
+ end
29
+
30
+ matcher :send_header do |header|
31
+ match do |actual|
32
+ actual_header = actual.body.from_json
33
+ header.inject(true) do |acc, item|
34
+ key = item.first.split("-").map {|w| w.capitalize }.join "-"
35
+ acc and (actual_header[key] == item.last)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1 @@
1
+ uploading
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: req
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - wenjun.yan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mime-types
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: json
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: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
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: rake
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: rspec
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: sinatra
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: sinatra-contrib
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
+ description: an easy way to deal with simple http request
126
+ email:
127
+ - mylastnameisyan@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - .gitignore
133
+ - Gemfile
134
+ - LICENSE.txt
135
+ - README.md
136
+ - Rakefile
137
+ - lib/req.rb
138
+ - lib/req/client.rb
139
+ - lib/req/part.rb
140
+ - lib/req/query.rb
141
+ - lib/req/version.rb
142
+ - req.gemspec
143
+ - server.rb
144
+ - spec/auth_spec.rb
145
+ - spec/get_spec.rb
146
+ - spec/header_spec.rb
147
+ - spec/post_spec.rb
148
+ - spec/schema_spec.rb
149
+ - spec/spec_helper.rb
150
+ - spec/tmp.txt
151
+ homepage: https://github.com/v2e4lisp/req
152
+ licenses:
153
+ - MIT
154
+ metadata: {}
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ! '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubyforge_project:
171
+ rubygems_version: 2.0.5
172
+ signing_key:
173
+ specification_version: 4
174
+ summary: FORK ME => Req["https://api.github.com/repo/v2e4lisp/req/forks"].auth("user",
175
+ "pass").post
176
+ test_files:
177
+ - spec/auth_spec.rb
178
+ - spec/get_spec.rb
179
+ - spec/header_spec.rb
180
+ - spec/post_spec.rb
181
+ - spec/schema_spec.rb
182
+ - spec/spec_helper.rb
183
+ - spec/tmp.txt