req 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.
@@ -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