ruby-requests 0.0.1.a1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.gitlab-ci.yml +37 -0
- data/.rubocop-disables.yml +96 -0
- data/.rubocop.yml +9 -0
- data/Gemfile +9 -0
- data/LICENSE +21 -0
- data/Makefile +17 -0
- data/README.md +151 -0
- data/lib/requests.rb +95 -0
- data/lib/requests/adapters.rb +124 -0
- data/lib/requests/cookies.rb +98 -0
- data/lib/requests/exceptions.rb +32 -0
- data/lib/requests/http_methods.rb +36 -0
- data/lib/requests/logger.rb +37 -0
- data/lib/requests/request.rb +94 -0
- data/lib/requests/response.rb +93 -0
- data/lib/requests/session.rb +120 -0
- data/lib/requests/utils.rb +162 -0
- data/lib/requests/version.rb +4 -0
- data/ruby-requests.gemspec +23 -0
- data/spec/docker-compose.yml +23 -0
- data/spec/docker_test_entrypoint.sh +12 -0
- data/spec/docker_tests.sh +6 -0
- data/spec/functional/proxies/proxies_spec.rb +84 -0
- data/spec/functional/proxies/squid_conf/passwords +2 -0
- data/spec/functional/proxies/squid_conf/squid.conf +11 -0
- data/spec/functional/requests_spec.rb +326 -0
- data/spec/functional/session_spec.rb +111 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/unit/api_spec.rb +42 -0
- data/spec/unit/utils_spec.rb +112 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6ed706002d82efed614dedca3e5d708a261247b975640f5e10f7b2dcd7dbe85b
|
4
|
+
data.tar.gz: bd706bdf0120e49d7ca6c59853100e760b61e214a19b06095a7047681ffdf2bd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ea6171cbf6ac26301ebc4eb17d3bd13edac08dd9da6595fd66c53d68f2369fadcb47590c6018100cfea2253d21f48d52466a3220c44d0f28c20663edca1d877f
|
7
|
+
data.tar.gz: 9030bf43b7fef5c86e736dd1ee75eb9e7d69cb572f94f759ac353c875e100b75c22aa036a376071092166cc7eb915482c3bb1d9db85ef9116303180e25c92ebf
|
data/.gitignore
ADDED
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
stages:
|
2
|
+
- test
|
3
|
+
- lint
|
4
|
+
|
5
|
+
before_script:
|
6
|
+
- gem install -g Gemfile
|
7
|
+
|
8
|
+
lint:
|
9
|
+
stage: lint
|
10
|
+
image: ruby
|
11
|
+
allow_failure: true
|
12
|
+
script:
|
13
|
+
- rubocop
|
14
|
+
|
15
|
+
test-ruby-2.3.0:
|
16
|
+
stage: test
|
17
|
+
image: ruby:2.3.0
|
18
|
+
script:
|
19
|
+
- rspec
|
20
|
+
|
21
|
+
test-ruby-2.4.0:
|
22
|
+
stage: test
|
23
|
+
image: ruby:2.4.0
|
24
|
+
script:
|
25
|
+
- rspec
|
26
|
+
|
27
|
+
# This will test with the current Ruby docker image:
|
28
|
+
test-in-docker-compose:
|
29
|
+
stage: test
|
30
|
+
image: tmaier/docker-compose
|
31
|
+
services:
|
32
|
+
- docker:dind
|
33
|
+
before_script:
|
34
|
+
- docker info
|
35
|
+
- docker-compose --version
|
36
|
+
script:
|
37
|
+
- docker-compose -f spec/docker-compose.yml up --exit-code-from ruby
|
@@ -0,0 +1,96 @@
|
|
1
|
+
---
|
2
|
+
Layout/AlignHash:
|
3
|
+
Enabled: false
|
4
|
+
|
5
|
+
Layout/EmptyLines:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Layout/IndentHash:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Layout/SpaceInsideHashLiteralBraces:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Metrics/AbcSize:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Metrics/BlockLength:
|
21
|
+
Exclude:
|
22
|
+
- "spec/*/*_spec.rb"
|
23
|
+
- "spec/*/*/*_spec.rb"
|
24
|
+
|
25
|
+
Metrics/MethodLength:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Metrics/ParameterLists:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Naming:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Performance/RedundantMerge:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/BlockDelimiters:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/BracesAroundHashParameters:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Style/ConditionalAssignment:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/Documentation:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/FormatString:
|
50
|
+
Enabled: False
|
51
|
+
|
52
|
+
Style/FormatStringToken:
|
53
|
+
Enabled: False
|
54
|
+
|
55
|
+
Style/FrozenStringLiteralComment:
|
56
|
+
Enabled: False
|
57
|
+
|
58
|
+
Style/GlobalVars:
|
59
|
+
Exclude:
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
|
62
|
+
Style/GuardClause:
|
63
|
+
Enabled: False
|
64
|
+
|
65
|
+
Style/HashSyntax:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
Style/MutableConstant:
|
69
|
+
Enabled: False
|
70
|
+
|
71
|
+
Style/NegatedIf:
|
72
|
+
Enabled: False
|
73
|
+
|
74
|
+
Style/NumericLiterals:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
Style/RegexpLiteral:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
Style/SafeNavigation:
|
81
|
+
Enabled: false
|
82
|
+
|
83
|
+
Style/SelfAssignment:
|
84
|
+
Enabled: False
|
85
|
+
|
86
|
+
Style/StringLiterals:
|
87
|
+
Enabled: false
|
88
|
+
|
89
|
+
Style/TrailingCommaInArrayLiteral:
|
90
|
+
Enabled: false
|
91
|
+
|
92
|
+
Style/TrailingCommaInHashLiteral:
|
93
|
+
Enabled: false
|
94
|
+
|
95
|
+
Style/WordArray:
|
96
|
+
Enabled: False
|
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) [2018] [Daniel Hones]
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
data/Makefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
RUBY_VERSIONS := 2.3.0 2.4.0 2.5.0
|
2
|
+
|
3
|
+
.PHONY: test-all-versions
|
4
|
+
test-all-versions:
|
5
|
+
@$(foreach version, $(RUBY_VERSIONS), \
|
6
|
+
echo "Running tests in Ruby $(version)"; \
|
7
|
+
rvm $(version) do rspec; \
|
8
|
+
)
|
9
|
+
|
10
|
+
.PHONY: setup-rvm-versions
|
11
|
+
setup-rvm-versions:
|
12
|
+
@$(foreach version, $(RUBY_VERSIONS), \
|
13
|
+
echo "Setting up $(version)"; \
|
14
|
+
rvm install $(version); \
|
15
|
+
rvm $(version) do gem install -g Gemfile; \
|
16
|
+
echo ""; \
|
17
|
+
)
|
data/README.md
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
[![pipeline status](https://gitlab.com/danielhones/ruby_requests/badges/master/pipeline.svg)](https://gitlab.com/danielhones/ruby_requests/commits/master)
|
2
|
+
[![coverage report](https://gitlab.com/danielhones/ruby_requests/badges/master/coverage.svg)](https://gitlab.com/danielhones/ruby_requests/commits/master)
|
3
|
+
|
4
|
+
|
5
|
+
# Ruby Requests
|
6
|
+
|
7
|
+
For Python programmers who just can't avoid making HTTP requests in Ruby.
|
8
|
+
|
9
|
+
This gem is a Ruby version of Kenneth Reitz's excellent [Requests](https://github.com/requests/requests) library for Python. The immediate goal for this project is to provide a useful subset of the interface and features supported by the Python library. It supports MRI Ruby 2.3.0 and up. A lot of the core functionality has been implemented already but it is still under development.
|
10
|
+
|
11
|
+
|
12
|
+
# Things that work now:
|
13
|
+
|
14
|
+
The following methods are implemented:
|
15
|
+
|
16
|
+
* `Requests.get`
|
17
|
+
* `Requests.post`
|
18
|
+
* `Requests.put`
|
19
|
+
* `Requests.head`
|
20
|
+
* `Requests.delete`
|
21
|
+
* `Requests.patch`
|
22
|
+
* `Requests.options`
|
23
|
+
|
24
|
+
Because of Ruby's handling of keyword arguments, optional parameters must be passed by keyword. For basic usage, here are some examples:
|
25
|
+
|
26
|
+
GET request with no query string params, parse the JSON response:
|
27
|
+
|
28
|
+
```
|
29
|
+
> r = Requests.get('https://httpbin.org/anything')
|
30
|
+
=> #<Requests::Response 200 OK>
|
31
|
+
> r.status_code
|
32
|
+
=> 200
|
33
|
+
> r.reason
|
34
|
+
=> "OK"
|
35
|
+
# .text returns the body of the response as text:
|
36
|
+
> puts r.text
|
37
|
+
{
|
38
|
+
"args": {},
|
39
|
+
"data": "",
|
40
|
+
"files": {},
|
41
|
+
"form": {},
|
42
|
+
"headers": {
|
43
|
+
"Accept": "*/*",
|
44
|
+
"Accept-Encoding": "gzip, deflate",
|
45
|
+
"Connection": "close",
|
46
|
+
"Host": "httpbin.org",
|
47
|
+
"User-Agent": "ruby-requests/0.0.1.a1"
|
48
|
+
},
|
49
|
+
"json": null,
|
50
|
+
"method": "GET",
|
51
|
+
"url": "https://httpbin.org/anything"
|
52
|
+
}
|
53
|
+
# the .json method parses the response body as JSON, returning a Ruby object:
|
54
|
+
> pp r.json
|
55
|
+
{"args"=>{},
|
56
|
+
"data"=>"",
|
57
|
+
"files"=>{},
|
58
|
+
"form"=>{},
|
59
|
+
"headers"=>
|
60
|
+
{"Accept"=>"*/*",
|
61
|
+
"Accept-Encoding"=>"gzip, deflate",
|
62
|
+
"Connection"=>"close",
|
63
|
+
"Host"=>"httpbin.org",
|
64
|
+
"User-Agent"=>"ruby-requests/0.0.1.a1"},
|
65
|
+
"json"=>nil,
|
66
|
+
"method"=>"GET",
|
67
|
+
"url"=>"https://httpbin.org/anything"}
|
68
|
+
```
|
69
|
+
|
70
|
+
POST request with query string params and text body:
|
71
|
+
|
72
|
+
```
|
73
|
+
> r = Requests.post('https://httpbin.org/anything',
|
74
|
+
* params: {'testkey' => 'test value', 'otherkey' => 'other value'},
|
75
|
+
* data: "sample POST body")
|
76
|
+
> r.url
|
77
|
+
=> "https://httpbin.org/anything?testkey=test+value&otherkey=other+value"
|
78
|
+
> r.json['args']
|
79
|
+
=> {"otherkey"=>"other value", "testkey"=>"test value"}
|
80
|
+
> r.json['data']
|
81
|
+
=> "sample POST body"
|
82
|
+
```
|
83
|
+
|
84
|
+
Add headers to a request;
|
85
|
+
|
86
|
+
```
|
87
|
+
> r = Requests.get('https://httpbin.org/headers', headers: {'Test-Header' => 'Example'})
|
88
|
+
=> #<Requests::Response 200 OK>
|
89
|
+
> puts r.text
|
90
|
+
{
|
91
|
+
"headers": {
|
92
|
+
"Accept": "*/*",
|
93
|
+
"Accept-Encoding": "gzip, deflate",
|
94
|
+
"Connection": "close",
|
95
|
+
"Host": "httpbin.org",
|
96
|
+
"Test-Header": "Example",
|
97
|
+
"User-Agent": "ruby-requests/0.0.1.a1"
|
98
|
+
}
|
99
|
+
}
|
100
|
+
```
|
101
|
+
|
102
|
+
|
103
|
+
Skip verification of SSL certificate (don't do this):
|
104
|
+
|
105
|
+
```
|
106
|
+
# Error by default on a self-signed cert:
|
107
|
+
> r = Requests.get('https://self-signed.badssl.com')
|
108
|
+
Traceback (most recent call last):
|
109
|
+
...
|
110
|
+
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate))
|
111
|
+
|
112
|
+
# Pass verify: false to prevent verification:
|
113
|
+
> r = Requests.get('https://self-signed.badssl.com', verify: false)
|
114
|
+
=> #<Requests::Response 200 OK>
|
115
|
+
```
|
116
|
+
|
117
|
+
Use Basic Authentication (currently the only supported auth type):
|
118
|
+
|
119
|
+
```
|
120
|
+
> r = Requests.get('https://httpbin.org/basic-auth/user/password',
|
121
|
+
* auth: ['user', 'password'])
|
122
|
+
=> #<Requests::Response 200 OK>
|
123
|
+
```
|
124
|
+
|
125
|
+
Run through a proxy:
|
126
|
+
|
127
|
+
```
|
128
|
+
> r = Requests.get('http://example.com', proxies: {'http' => 'http://172.20.9.13:3128'})
|
129
|
+
=> #<Requests::Response 200 OK>
|
130
|
+
```
|
131
|
+
|
132
|
+
|
133
|
+
# Sessions
|
134
|
+
|
135
|
+
Sessions are partially supported in the same way that they work in the Python version. Here's a list of things that work:
|
136
|
+
|
137
|
+
* Cookie persistence across requests. `Session#cookies` returns a `Requests::CookieJar` object which is a subclass of [HTTP::Cookie](https://github.com/sparklemotion/http-cookie). See documentation for that gem for its main functionality.
|
138
|
+
* Optional authentication sent with each request
|
139
|
+
* Session headers sent with each request (per-request headers take precedence if used)
|
140
|
+
* Proxies used for each request in a session
|
141
|
+
|
142
|
+
And some things that don't work yet:
|
143
|
+
|
144
|
+
* Respecting environment variables such as `http_proxy`
|
145
|
+
* Following redirects
|
146
|
+
|
147
|
+
|
148
|
+
# Features that haven't been added yet
|
149
|
+
|
150
|
+
* **Redirects:** Following redirects is one of the next things to be implemented but they currently are not followed. There is an `allow_redirects` keyword argument on the request methods that defaults to true, but at the moment it is just ignored.
|
151
|
+
* **Hooks:** There is currently no implementation of hooks or block passing to the request methods
|
data/lib/requests.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
dir = File.expand_path(__dir__)
|
2
|
+
|
3
|
+
require File.join(dir, 'requests/version')
|
4
|
+
require File.join(dir, 'requests/exceptions')
|
5
|
+
require File.join(dir, 'requests/logger')
|
6
|
+
require File.join(dir, 'requests/utils')
|
7
|
+
require File.join(dir, 'requests/cookies')
|
8
|
+
require File.join(dir, 'requests/http_methods')
|
9
|
+
require File.join(dir, 'requests/request')
|
10
|
+
require File.join(dir, 'requests/response')
|
11
|
+
require File.join(dir, 'requests/adapters')
|
12
|
+
require File.join(dir, 'requests/session')
|
13
|
+
|
14
|
+
|
15
|
+
module Requests
|
16
|
+
##
|
17
|
+
# Constructs and sends a :class:`Request <Request>`.
|
18
|
+
#
|
19
|
+
# :param method: method for the new :class:`Request` object.
|
20
|
+
# :param url: URL for the new :class:`Request` object.
|
21
|
+
# :param params: (optional) Hash be sent in the query string
|
22
|
+
# :param data: (optional) Hash, list of tuples ``[[key, value]]`, string,
|
23
|
+
# or file-like object to send in the body.
|
24
|
+
# :param json: (optional) json data to send in the body. Using this param
|
25
|
+
# will ignore any +data+ keyword param
|
26
|
+
# :param headers: (optional) Hash of HTTP Headers to send
|
27
|
+
# :param cookies: (optional) Hash or HTTP::CookieJar object to send
|
28
|
+
# :param auth: (optional) Auth tuple to enable basic auth or
|
29
|
+
# :param timeout: (optional) How many seconds to wait for the server to send
|
30
|
+
# data before giving up. Float or , or an array of Floats indicating
|
31
|
+
# (connect timeout, read timeout)
|
32
|
+
# :param allow_redirects: (optional) Boolean. Enable/disable redirection.
|
33
|
+
# Defaults to +true+.
|
34
|
+
#
|
35
|
+
# :return: :class:`Response <Response>` object
|
36
|
+
# :rtype: Requests::Response
|
37
|
+
#
|
38
|
+
# Not implemented yet:
|
39
|
+
# :param verify: (optional) Either a boolean, in which case it controls
|
40
|
+
# whether we verify the server's TLS certificate, or a string, in which
|
41
|
+
# case it must be a path to a CA bundle to use. Defaults to +true+
|
42
|
+
# :param files: (optional) Hash of +'name': file-like-objects+
|
43
|
+
# :param proxies: (optional) Dictionary mapping protocol to the URL of the
|
44
|
+
# proxy.
|
45
|
+
# :param stream: (optional) if ``False``, the response content will be
|
46
|
+
# immediately downloaded.
|
47
|
+
# :param cert: (optional) if String, path to ssl client cert file (.pem).
|
48
|
+
# If Tuple, ('cert', 'key') pair.
|
49
|
+
|
50
|
+
extend HttpMethods
|
51
|
+
|
52
|
+
def self.request(method, url, **kwargs)
|
53
|
+
session = Session.new
|
54
|
+
session.request(method, url, **kwargs)
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Logging related stuff:
|
59
|
+
|
60
|
+
DEFAULT_LOG_DEV = $stdout
|
61
|
+
DEFAULT_LOGGING_ENABLED = false
|
62
|
+
|
63
|
+
def self.default_logger
|
64
|
+
# :nocov:
|
65
|
+
Requests::Logger.new(DEFAULT_LOG_DEV, level: 'info',
|
66
|
+
enabled: DEFAULT_LOGGING_ENABLED)
|
67
|
+
# :nocov:
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.logger
|
71
|
+
@logger ||= default_logger
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.logger=(new_logger)
|
75
|
+
@logger = new_logger
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.enable_logging
|
79
|
+
logger.enabled = true if logger.respond_to?(:'enabled=')
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.disable_logging
|
83
|
+
logger.enabled = false if logger.respond_to?(:enabled)
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Shortcut to enable debug logging for development
|
88
|
+
|
89
|
+
def self.enable_dev_mode
|
90
|
+
# :nocov:
|
91
|
+
enable_logging
|
92
|
+
logger.level = 'debug'
|
93
|
+
# :nocov:
|
94
|
+
end
|
95
|
+
end
|