ruby-requests 0.0.1.a1
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 +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
|
+
[](https://gitlab.com/danielhones/ruby_requests/commits/master)
|
2
|
+
[](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
|