httparty 0.13.7 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.editorconfig +18 -0
- data/.github/workflows/ci.yml +26 -0
- data/.gitignore +3 -0
- data/.rubocop_todo.yml +1 -1
- data/{History → Changelog.md} +226 -59
- data/Gemfile +10 -3
- data/Guardfile +3 -2
- data/README.md +8 -7
- data/bin/httparty +3 -1
- data/docs/README.md +191 -0
- data/examples/README.md +34 -12
- data/examples/aaws.rb +7 -3
- data/examples/body_stream.rb +14 -0
- data/examples/crack.rb +1 -1
- data/examples/custom_parsers.rb +5 -1
- data/examples/delicious.rb +4 -4
- data/examples/headers_and_user_agents.rb +7 -3
- data/examples/idn.rb +10 -0
- data/examples/logging.rb +4 -4
- data/examples/microsoft_graph.rb +52 -0
- data/examples/multipart.rb +22 -0
- data/examples/peer_cert.rb +9 -0
- data/examples/stackexchange.rb +1 -1
- data/examples/stream_download.rb +26 -0
- data/examples/tripit_sign_in.rb +17 -6
- data/examples/twitter.rb +2 -2
- data/examples/whoismyrep.rb +1 -1
- data/httparty.gemspec +7 -5
- data/lib/httparty/connection_adapter.rb +86 -20
- data/lib/httparty/cookie_hash.rb +10 -8
- data/lib/httparty/decompressor.rb +102 -0
- data/lib/httparty/exceptions.rb +8 -2
- data/lib/httparty/hash_conversions.rb +30 -8
- data/lib/httparty/headers_processor.rb +32 -0
- data/lib/httparty/logger/apache_formatter.rb +31 -6
- data/lib/httparty/logger/curl_formatter.rb +68 -23
- data/lib/httparty/logger/logger.rb +5 -1
- data/lib/httparty/logger/logstash_formatter.rb +61 -0
- data/lib/httparty/module_inheritable_attributes.rb +6 -4
- data/lib/httparty/net_digest_auth.rb +23 -21
- data/lib/httparty/parser.rb +25 -14
- data/lib/httparty/request/body.rb +105 -0
- data/lib/httparty/request/multipart_boundary.rb +13 -0
- data/lib/httparty/request.rb +160 -106
- data/lib/httparty/response/headers.rb +23 -19
- data/lib/httparty/response.rb +92 -13
- data/lib/httparty/response_fragment.rb +21 -0
- data/lib/httparty/text_encoder.rb +72 -0
- data/lib/httparty/utils.rb +13 -0
- data/lib/httparty/version.rb +3 -1
- data/lib/httparty.rb +98 -35
- data/website/css/common.css +1 -1
- metadata +34 -114
- data/.simplecov +0 -1
- data/.travis.yml +0 -7
- data/features/basic_authentication.feature +0 -20
- data/features/command_line.feature +0 -95
- data/features/deals_with_http_error_codes.feature +0 -26
- data/features/digest_authentication.feature +0 -30
- data/features/handles_compressed_responses.feature +0 -27
- data/features/handles_multiple_formats.feature +0 -57
- data/features/steps/env.rb +0 -27
- data/features/steps/httparty_response_steps.rb +0 -52
- data/features/steps/httparty_steps.rb +0 -43
- data/features/steps/mongrel_helper.rb +0 -127
- data/features/steps/remote_service_steps.rb +0 -90
- data/features/supports_read_timeout_option.feature +0 -13
- data/features/supports_redirection.feature +0 -22
- data/features/supports_timeout_option.feature +0 -13
- data/spec/fixtures/delicious.xml +0 -23
- data/spec/fixtures/empty.xml +0 -0
- data/spec/fixtures/google.html +0 -3
- data/spec/fixtures/ssl/generate.sh +0 -29
- data/spec/fixtures/ssl/generated/1fe462c2.0 +0 -16
- data/spec/fixtures/ssl/generated/bogushost.crt +0 -13
- data/spec/fixtures/ssl/generated/ca.crt +0 -16
- data/spec/fixtures/ssl/generated/ca.key +0 -15
- data/spec/fixtures/ssl/generated/selfsigned.crt +0 -14
- data/spec/fixtures/ssl/generated/server.crt +0 -13
- data/spec/fixtures/ssl/generated/server.key +0 -15
- data/spec/fixtures/ssl/openssl-exts.cnf +0 -9
- data/spec/fixtures/twitter.csv +0 -2
- data/spec/fixtures/twitter.json +0 -1
- data/spec/fixtures/twitter.xml +0 -403
- data/spec/fixtures/undefined_method_add_node_for_nil.xml +0 -2
- data/spec/httparty/connection_adapter_spec.rb +0 -468
- data/spec/httparty/cookie_hash_spec.rb +0 -83
- data/spec/httparty/exception_spec.rb +0 -38
- data/spec/httparty/hash_conversions_spec.rb +0 -41
- data/spec/httparty/logger/apache_formatter_spec.rb +0 -41
- data/spec/httparty/logger/curl_formatter_spec.rb +0 -18
- data/spec/httparty/logger/logger_spec.rb +0 -38
- data/spec/httparty/net_digest_auth_spec.rb +0 -230
- data/spec/httparty/parser_spec.rb +0 -173
- data/spec/httparty/request_spec.rb +0 -1073
- data/spec/httparty/response_spec.rb +0 -241
- data/spec/httparty/ssl_spec.rb +0 -74
- data/spec/httparty_spec.rb +0 -850
- data/spec/spec_helper.rb +0 -59
- data/spec/support/ssl_test_helper.rb +0 -47
- data/spec/support/ssl_test_server.rb +0 -80
- data/spec/support/stub_response.rb +0 -49
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# httparty
|
2
2
|
|
3
|
-
|
3
|
+
[![CI](https://github.com/jnunemaker/httparty/actions/workflows/ci.yml/badge.svg)](https://github.com/jnunemaker/httparty/actions/workflows/ci.yml)
|
4
|
+
|
5
|
+
Makes http fun again! Ain't no party like a httparty, because a httparty don't stop.
|
4
6
|
|
5
7
|
## Install
|
6
8
|
|
@@ -10,7 +12,7 @@ gem install httparty
|
|
10
12
|
|
11
13
|
## Requirements
|
12
14
|
|
13
|
-
* Ruby
|
15
|
+
* Ruby 2.3.0 or higher
|
14
16
|
* multi_xml
|
15
17
|
* You like to party!
|
16
18
|
|
@@ -28,7 +30,7 @@ class StackExchange
|
|
28
30
|
base_uri 'api.stackexchange.com'
|
29
31
|
|
30
32
|
def initialize(service, page)
|
31
|
-
@options = { query: {site: service, page: page} }
|
33
|
+
@options = { query: { site: service, page: page } }
|
32
34
|
end
|
33
35
|
|
34
36
|
def questions
|
@@ -46,7 +48,6 @@ puts stack_exchange.users
|
|
46
48
|
```
|
47
49
|
|
48
50
|
See the [examples directory](http://github.com/jnunemaker/httparty/tree/master/examples) for even more goodies.
|
49
|
-
|
50
51
|
## Command Line Interface
|
51
52
|
|
52
53
|
httparty also includes the executable `httparty` which can be
|
@@ -62,9 +63,9 @@ httparty "https://api.stackexchange.com/2.2/questions?site=stackoverflow"
|
|
62
63
|
|
63
64
|
## Help and Docs
|
64
65
|
|
65
|
-
* https://
|
66
|
-
*
|
67
|
-
*
|
66
|
+
* [Docs](https://github.com/jnunemaker/httparty/tree/master/docs)
|
67
|
+
* https://github.com/jnunemaker/httparty/discussions
|
68
|
+
* https://www.rubydoc.info/github/jnunemaker/httparty
|
68
69
|
|
69
70
|
## Contributing
|
70
71
|
|
data/bin/httparty
CHANGED
@@ -103,9 +103,11 @@ else
|
|
103
103
|
when :json
|
104
104
|
begin
|
105
105
|
require 'json'
|
106
|
-
puts JSON.pretty_generate(response)
|
106
|
+
puts JSON.pretty_generate(response.parsed_response)
|
107
107
|
rescue LoadError
|
108
108
|
puts YAML.dump(response)
|
109
|
+
rescue JSON::JSONError
|
110
|
+
puts response.inspect
|
109
111
|
end
|
110
112
|
when :xml
|
111
113
|
require 'rexml/document'
|
data/docs/README.md
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
# httparty
|
2
|
+
|
3
|
+
Makes http fun again!
|
4
|
+
|
5
|
+
## Table of contents
|
6
|
+
- [Parsing JSON](#parsing-json)
|
7
|
+
- [Working with SSL](#working-with-ssl)
|
8
|
+
|
9
|
+
## Parsing JSON
|
10
|
+
If the response Content Type is `application/json`, HTTParty will parse the response and return Ruby objects such as a hash or array. The default behavior for parsing JSON will return keys as strings. This can be supressed with the `format` option. To get hash keys as symbols:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
response = HTTParty.get('http://example.com', format: :plain)
|
14
|
+
JSON.parse response, symbolize_names: true
|
15
|
+
```
|
16
|
+
|
17
|
+
## Posting JSON
|
18
|
+
When using Content Type `application/json` with `POST`, `PUT` or `PATCH` requests, the body should be a string of valid JSON:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# With written JSON
|
22
|
+
HTTParty.post('http://example.com', body: "{\"foo\":\"bar\"}", headers: { 'Content-Type' => 'application/json' })
|
23
|
+
|
24
|
+
# Using JSON.generate
|
25
|
+
HTTParty.post('http://example.com', body: JSON.generate({ foo: 'bar' }), headers: { 'Content-Type' => 'application/json' })
|
26
|
+
|
27
|
+
# Using object.to_json
|
28
|
+
HTTParty.post('http://example.com', body: { foo: 'bar' }.to_json, headers: { 'Content-Type' => 'application/json' })
|
29
|
+
```
|
30
|
+
|
31
|
+
## Working with SSL
|
32
|
+
|
33
|
+
You can use this guide to work with SSL certificates.
|
34
|
+
|
35
|
+
#### Using `pem` option
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
# Use this example if you are using a pem file
|
39
|
+
|
40
|
+
class Client
|
41
|
+
include HTTParty
|
42
|
+
|
43
|
+
base_uri "https://example.com"
|
44
|
+
pem File.read("#{File.expand_path('.')}/path/to/certs/cert.pem"), "123456"
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
#### Using `pkcs12` option
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
# Use this example if you are using a pkcs12 file
|
52
|
+
|
53
|
+
class Client
|
54
|
+
include HTTParty
|
55
|
+
|
56
|
+
base_uri "https://example.com"
|
57
|
+
pkcs12 File.read("#{File.expand_path('.')}/path/to/certs/cert.p12"), "123456"
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
#### Using `ssl_ca_file` option
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
# Use this example if you are using a pkcs12 file
|
65
|
+
|
66
|
+
class Client
|
67
|
+
include HTTParty
|
68
|
+
|
69
|
+
base_uri "https://example.com"
|
70
|
+
ssl_ca_file "#{File.expand_path('.')}/path/to/certs/cert.pem"
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
#### Using `ssl_ca_path` option
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
# Use this example if you are using a pkcs12 file
|
78
|
+
|
79
|
+
class Client
|
80
|
+
include HTTParty
|
81
|
+
|
82
|
+
base_uri "https://example.com"
|
83
|
+
ssl_ca_path '/path/to/certs'
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
You can also include all of these options with the call:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
class Client
|
91
|
+
include HTTParty
|
92
|
+
|
93
|
+
base_uri "https://example.com"
|
94
|
+
|
95
|
+
def self.fetch
|
96
|
+
get("/resources", pem: File.read("#{File.expand_path('.')}/path/to/certs/cert.pem"), pem_password: "123456")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
### Avoid SSL verification
|
102
|
+
|
103
|
+
In some cases you may want to skip SSL verification, because the entity that issued the certificate is not a valid one, but you still want to work with it. You can achieve this through:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
# Skips SSL certificate verification
|
107
|
+
|
108
|
+
class Client
|
109
|
+
include HTTParty
|
110
|
+
|
111
|
+
base_uri "https://example.com"
|
112
|
+
pem File.read("#{File.expand_path('.')}/path/to/certs/cert.pem"), "123456"
|
113
|
+
|
114
|
+
def self.fetch
|
115
|
+
get("/resources", verify: false)
|
116
|
+
# You can also use something like:
|
117
|
+
# get("resources", verify_peer: false)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
### HTTP Compression
|
123
|
+
|
124
|
+
The `Accept-Encoding` request header and `Content-Encoding` response header
|
125
|
+
are used to control compression (gzip, etc.) over the wire. Refer to
|
126
|
+
[RFC-2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html) for details.
|
127
|
+
(For clarity: these headers are **not** used for character encoding i.e. `utf-8`
|
128
|
+
which is specified in the `Accept` and `Content-Type` headers.)
|
129
|
+
|
130
|
+
Unless you have specific requirements otherwise, we recommend to **not** set
|
131
|
+
set the `Accept-Encoding` header on HTTParty requests. In this case, `Net::HTTP`
|
132
|
+
will set a sensible default compression scheme and automatically decompress the response.
|
133
|
+
|
134
|
+
If you explicitly set `Accept-Encoding`, there be dragons:
|
135
|
+
|
136
|
+
* If the HTTP response `Content-Encoding` received on the wire is `gzip` or `deflate`,
|
137
|
+
`Net::HTTP` will automatically decompress it, and will omit `Content-Encoding`
|
138
|
+
from your `HTTParty::Response` headers.
|
139
|
+
|
140
|
+
* For the following encodings, HTTParty will automatically decompress them if you include
|
141
|
+
the required gem into your project. Similar to above, if decompression succeeds,
|
142
|
+
`Content-Encoding` will be omitted from your `HTTParty::Response` headers.
|
143
|
+
**Warning:** Support for these encodings is experimental and not fully battle-tested.
|
144
|
+
|
145
|
+
| Content-Encoding | Required Gem |
|
146
|
+
| --- | --- |
|
147
|
+
| `br` (Brotli) | [brotli](https://rubygems.org/gems/brotli) |
|
148
|
+
| `compress` (LZW) | [ruby-lzws](https://rubygems.org/gems/ruby-lzws) |
|
149
|
+
| `zstd` (Zstandard) | [zstd-ruby](https://rubygems.org/gems/zstd-ruby) |
|
150
|
+
|
151
|
+
* For other encodings, `HTTParty::Response#body` will return the raw uncompressed byte string,
|
152
|
+
and you'll need to inspect the `Content-Encoding` response header and decompress it yourself.
|
153
|
+
In this case, `HTTParty::Response#parsed_response` will be `nil`.
|
154
|
+
|
155
|
+
* Lastly, you may use the `skip_decompression` option to disable all automatic decompression
|
156
|
+
and always get `HTTParty::Response#body` in its raw form along with the `Content-Encoding` header.
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
# Accept-Encoding=gzip,deflate can be safely assumed to be auto-decompressed
|
160
|
+
|
161
|
+
res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => 'gzip,deflate,identity' })
|
162
|
+
JSON.parse(res.body) # safe
|
163
|
+
|
164
|
+
|
165
|
+
# Accept-Encoding=br,compress requires third-party gems
|
166
|
+
|
167
|
+
require 'brotli'
|
168
|
+
require 'lzws'
|
169
|
+
require 'zstd-ruby'
|
170
|
+
res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => 'br,compress,zstd' })
|
171
|
+
JSON.parse(res.body)
|
172
|
+
|
173
|
+
|
174
|
+
# Accept-Encoding=* may return unhandled Content-Encoding
|
175
|
+
|
176
|
+
res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => '*' })
|
177
|
+
encoding = res.headers['Content-Encoding']
|
178
|
+
if encoding
|
179
|
+
JSON.parse(your_decompression_handling(res.body, encoding))
|
180
|
+
else
|
181
|
+
# Content-Encoding not present implies decompressed
|
182
|
+
JSON.parse(res.body)
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
# Gimme the raw data!
|
187
|
+
|
188
|
+
res = HTTParty.get('https://example.com/test.json', skip_decompression: true)
|
189
|
+
encoding = res.headers['Content-Encoding']
|
190
|
+
JSON.parse(your_decompression_handling(res.body, encoding))
|
191
|
+
```
|
data/examples/README.md
CHANGED
@@ -13,22 +13,22 @@
|
|
13
13
|
* Creates a custom parser for XML using crack gem
|
14
14
|
* Uses `get` request
|
15
15
|
|
16
|
-
* [Create HTML Nokogiri parser](nokogiri_html_parser.rb)
|
16
|
+
* [Create HTML Nokogiri parser](nokogiri_html_parser.rb)
|
17
17
|
* Adds Html as a format
|
18
18
|
* passed the body of request to Nokogiri
|
19
|
-
|
19
|
+
|
20
20
|
* [More Custom Parsers](custom_parsers.rb)
|
21
21
|
* Create an additional parser for atom or make it the ONLY parser
|
22
|
-
|
22
|
+
|
23
23
|
* [Basic Auth, Delicious](delicious.rb)
|
24
24
|
* Basic Auth, shows how to merge those into options
|
25
25
|
* Uses `get` requests
|
26
|
-
|
26
|
+
|
27
27
|
* [Passing Headers, User Agent](headers_and_user_agents.rb)
|
28
28
|
* Use the class method of Httparty
|
29
29
|
* Pass the User-Agent in the headers
|
30
30
|
* Uses `get` requests
|
31
|
-
|
31
|
+
|
32
32
|
* [Basic Post Request](basic.rb)
|
33
33
|
* Httparty included into poro class
|
34
34
|
* Uses `post` requests
|
@@ -36,7 +36,7 @@
|
|
36
36
|
* [Access Rubyurl Shortener](rubyurl.rb)
|
37
37
|
* Httparty included into poro class
|
38
38
|
* Uses `post` requests
|
39
|
-
|
39
|
+
|
40
40
|
* [Add a custom log file](logging.rb)
|
41
41
|
* create a log file and have httparty log requests
|
42
42
|
|
@@ -44,24 +44,46 @@
|
|
44
44
|
* Httparty included into poro class
|
45
45
|
* Creates methods for different endpoints
|
46
46
|
* Uses `get` requests
|
47
|
-
|
47
|
+
|
48
48
|
* [Accessing Tripit](tripit_sign_in.rb)
|
49
49
|
* Httparty included into poro class
|
50
50
|
* Example of using `debug_output` to see headers/urls passed
|
51
51
|
* Getting and using Cookies
|
52
52
|
* Uses `get` requests
|
53
|
-
|
53
|
+
|
54
54
|
* [Accessing Twitter](twitter.rb)
|
55
55
|
* Httparty included into poro class
|
56
56
|
* Basic Auth
|
57
|
-
* Loads settings from a config file
|
57
|
+
* Loads settings from a config file
|
58
58
|
* Uses `get` requests
|
59
59
|
* Uses `post` requests
|
60
|
-
|
60
|
+
|
61
61
|
* [Accessing WhoIsMyRep](whoismyrep.rb)
|
62
62
|
* Httparty included into poro class
|
63
|
-
* Uses `get` requests
|
63
|
+
* Uses `get` requests
|
64
64
|
* Two ways to pass params to get, inline on the url or in query hash
|
65
65
|
|
66
66
|
* [Rescue Json Error](rescue_json.rb)
|
67
|
-
* Rescue errors due to parsing response
|
67
|
+
* Rescue errors due to parsing response
|
68
|
+
|
69
|
+
* [Download file using stream mode](stream_download.rb)
|
70
|
+
* Uses `get` requests
|
71
|
+
* Uses `stream_body` mode
|
72
|
+
* Download file without using the memory
|
73
|
+
|
74
|
+
* [Microsoft graph](microsoft_graph.rb)
|
75
|
+
* Basic Auth
|
76
|
+
* Uses `post` requests
|
77
|
+
* Uses multipart
|
78
|
+
|
79
|
+
* [Multipart](multipart.rb)
|
80
|
+
* Multipart data upload _(with and without file)_
|
81
|
+
|
82
|
+
* [Uploading File](body_stream.rb)
|
83
|
+
* Uses `body_stream` to upload file
|
84
|
+
|
85
|
+
* [Accessing x509 Peer Certificate](peer_cert.rb)
|
86
|
+
* Provides access to the server's TLS certificate
|
87
|
+
|
88
|
+
* [Accessing IDNs](idn.rb)
|
89
|
+
* Uses a `get` request with an International domain names, which are Urls with emojis and non-ASCII characters such as accented letters.
|
data/examples/aaws.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'active_support'
|
3
|
+
require 'active_support/core_ext/hash'
|
4
|
+
require 'active_support/core_ext/string'
|
3
5
|
|
4
6
|
dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
7
|
require File.join(dir, 'httparty')
|
@@ -13,14 +15,16 @@ module AAWS
|
|
13
15
|
default_params Service: 'AWSECommerceService', Operation: 'ItemSearch', SearchIndex: 'Books'
|
14
16
|
|
15
17
|
def initialize(key)
|
16
|
-
|
18
|
+
@auth = { AWSAccessKeyId: key }
|
17
19
|
end
|
18
20
|
|
19
21
|
def search(options = {})
|
20
22
|
raise ArgumentError, 'You must search for something' if options[:query].blank?
|
21
23
|
|
22
24
|
# amazon uses nasty camelized query params
|
23
|
-
options[:query] = options[:query]
|
25
|
+
options[:query] = options[:query]
|
26
|
+
.reverse_merge(@auth)
|
27
|
+
.transform_keys { |k| k.to_s.camelize }
|
24
28
|
|
25
29
|
# make a request and return the items (NOTE: this doesn't handle errors at this point)
|
26
30
|
self.class.get('/onca/xml', options)['ItemSearchResponse']['Items']
|
@@ -29,4 +33,4 @@ module AAWS
|
|
29
33
|
end
|
30
34
|
|
31
35
|
aaws = AAWS::Book.new(config[:access_key])
|
32
|
-
pp aaws.search(query: {title: 'Ruby On Rails'})
|
36
|
+
pp aaws.search(query: { title: 'Ruby On Rails' })
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# To upload file to a server use :body_stream
|
2
|
+
|
3
|
+
HTTParty.put(
|
4
|
+
'http://localhost:3000/train',
|
5
|
+
body_stream: File.open('sample_configs/config_train_server_md.yml', 'r')
|
6
|
+
)
|
7
|
+
|
8
|
+
|
9
|
+
# Actually, it works with any IO object
|
10
|
+
|
11
|
+
HTTParty.put(
|
12
|
+
'http://localhost:3000/train',
|
13
|
+
body_stream: StringIO.new('foo')
|
14
|
+
)
|
data/examples/crack.rb
CHANGED
@@ -16,4 +16,4 @@ class Rep
|
|
16
16
|
end
|
17
17
|
|
18
18
|
pp Rep.get('http://whoismyrepresentative.com/getall_mems.php?zip=46544')
|
19
|
-
pp Rep.get('http://whoismyrepresentative.com/getall_mems.php', query: {zip: 46544})
|
19
|
+
pp Rep.get('http://whoismyrepresentative.com/getall_mems.php', query: { zip: 46544 })
|
data/examples/custom_parsers.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require File.join(dir, 'httparty')
|
3
|
+
require 'pp'
|
4
|
+
|
1
5
|
class ParseAtom
|
2
6
|
include HTTParty
|
3
7
|
|
@@ -21,7 +25,7 @@ class OnlyParseAtom
|
|
21
25
|
|
22
26
|
# Only support Atom
|
23
27
|
class Parser::OnlyAtom < HTTParty::Parser
|
24
|
-
SupportedFormats = {"application/atom+xml" => :atom}
|
28
|
+
SupportedFormats = { "application/atom+xml" => :atom }
|
25
29
|
|
26
30
|
protected
|
27
31
|
|
data/examples/delicious.rb
CHANGED
@@ -8,7 +8,7 @@ class Delicious
|
|
8
8
|
base_uri 'https://api.del.icio.us/v1'
|
9
9
|
|
10
10
|
def initialize(u, p)
|
11
|
-
@auth = {username: u, password: p}
|
11
|
+
@auth = { username: u, password: p }
|
12
12
|
end
|
13
13
|
|
14
14
|
# query params that filter the posts are:
|
@@ -17,7 +17,7 @@ class Delicious
|
|
17
17
|
# url (optional). Filter by this url.
|
18
18
|
# ie: posts(query: {tag: 'ruby'})
|
19
19
|
def posts(options = {})
|
20
|
-
options.merge!({basic_auth: @auth})
|
20
|
+
options.merge!({ basic_auth: @auth })
|
21
21
|
self.class.get('/posts/get', options)
|
22
22
|
end
|
23
23
|
|
@@ -25,13 +25,13 @@ class Delicious
|
|
25
25
|
# tag (optional). Filter by this tag.
|
26
26
|
# count (optional). Number of items to retrieve (Default:15, Maximum:100).
|
27
27
|
def recent(options = {})
|
28
|
-
options.merge!({basic_auth: @auth})
|
28
|
+
options.merge!({ basic_auth: @auth })
|
29
29
|
self.class.get('/posts/recent', options)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
delicious = Delicious.new(config['username'], config['password'])
|
34
|
-
pp delicious.posts(query: {tag: 'ruby'})
|
34
|
+
pp delicious.posts(query: { tag: 'ruby' })
|
35
35
|
pp delicious.recent
|
36
36
|
|
37
37
|
delicious.recent['posts']['post'].each { |post| puts post['href'] }
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# To send custom user agents to identify your application to a web service (or mask as a specific browser for testing), send "User-Agent" as a hash to headers as shown below.
|
2
2
|
|
3
|
-
|
3
|
+
dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
require File.join(dir, 'httparty')
|
5
|
+
require 'pp'
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
response = HTTParty.get('http://example.com', {
|
8
|
+
headers: {"User-Agent" => "Httparty"},
|
9
|
+
debug_output: STDOUT, # To show that User-Agent is Httparty
|
10
|
+
})
|
data/examples/idn.rb
ADDED
data/examples/logging.rb
CHANGED
@@ -3,7 +3,7 @@ require File.join(dir, 'httparty')
|
|
3
3
|
require 'logger'
|
4
4
|
require 'pp'
|
5
5
|
|
6
|
-
my_logger = Logger.new
|
6
|
+
my_logger = Logger.new STDOUT
|
7
7
|
|
8
8
|
my_logger.info "Logging can be used on the main HTTParty class. It logs redirects too."
|
9
9
|
HTTParty.get "http://google.com", logger: my_logger
|
@@ -14,7 +14,7 @@ my_logger.info "It can be used also on a custom class."
|
|
14
14
|
|
15
15
|
class Google
|
16
16
|
include HTTParty
|
17
|
-
logger ::Logger.new
|
17
|
+
logger ::Logger.new STDOUT
|
18
18
|
end
|
19
19
|
|
20
20
|
Google.get "http://google.com"
|
@@ -22,7 +22,7 @@ Google.get "http://google.com"
|
|
22
22
|
my_logger.info '*' * 70
|
23
23
|
|
24
24
|
my_logger.info "The default formatter is :apache. The :curl formatter can also be used."
|
25
|
-
my_logger.info "You can tell
|
25
|
+
my_logger.info "You can tell which method to call on the logger too. It is info by default."
|
26
26
|
HTTParty.get "http://google.com", logger: my_logger, log_level: :debug, log_format: :curl
|
27
27
|
|
28
28
|
my_logger.info '*' * 70
|
@@ -30,7 +30,7 @@ my_logger.info '*' * 70
|
|
30
30
|
my_logger.info "These configs are also available on custom classes."
|
31
31
|
class Google
|
32
32
|
include HTTParty
|
33
|
-
logger ::Logger.new(
|
33
|
+
logger ::Logger.new(STDOUT), :debug, :curl
|
34
34
|
end
|
35
35
|
|
36
36
|
Google.get "http://google.com"
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
class MicrosoftGraph
|
4
|
+
MS_BASE_URL = "https://login.microsoftonline.com".freeze
|
5
|
+
TOKEN_REQUEST_PATH = "oauth2/v2.0/token".freeze
|
6
|
+
|
7
|
+
def initialize(tenant_id)
|
8
|
+
@tenant_id = tenant_id
|
9
|
+
end
|
10
|
+
|
11
|
+
# Make a request to the Microsoft Graph API, for instance https://graph.microsoft.com/v1.0/users
|
12
|
+
def request(url)
|
13
|
+
return false unless (token = bearer_token)
|
14
|
+
|
15
|
+
response = HTTParty.get(
|
16
|
+
url,
|
17
|
+
headers: {
|
18
|
+
Authorization: "Bearer #{token}"
|
19
|
+
}
|
20
|
+
)
|
21
|
+
|
22
|
+
return false unless response.code == 200
|
23
|
+
|
24
|
+
return JSON.parse(response.body)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# A post to the Microsoft Graph to get a bearer token for the specified tenant. In this example
|
30
|
+
# our Rails application has already been given permission to request these tokens by the admin of
|
31
|
+
# the specified tenant_id.
|
32
|
+
#
|
33
|
+
# See here for more information https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
|
34
|
+
#
|
35
|
+
# This request also makes use of the multipart/form-data post body.
|
36
|
+
def bearer_token
|
37
|
+
response = HTTParty.post(
|
38
|
+
"#{MS_BASE_URL}/#{@tenant_id}/#{TOKEN_REQUEST_PATH}",
|
39
|
+
multipart: true,
|
40
|
+
body: {
|
41
|
+
client_id: Rails.application.credentials[Rails.env.to_sym][:microsoft_client_id],
|
42
|
+
client_secret: Rails.application.credentials[Rails.env.to_sym][:microsoft_client_secret],
|
43
|
+
scope: 'https://graph.microsoft.com/.default',
|
44
|
+
grant_type: 'client_credentials'
|
45
|
+
}
|
46
|
+
)
|
47
|
+
|
48
|
+
return false unless response.code == 200
|
49
|
+
|
50
|
+
JSON.parse(response.body)['access_token']
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# If you are uploading file in params, multipart will used as content-type automatically
|
2
|
+
|
3
|
+
HTTParty.post(
|
4
|
+
'http://localhost:3000/user',
|
5
|
+
body: {
|
6
|
+
name: 'Foo Bar',
|
7
|
+
email: 'example@email.com',
|
8
|
+
avatar: File.open('/full/path/to/avatar.jpg')
|
9
|
+
}
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
# However, you can force it yourself
|
14
|
+
|
15
|
+
HTTParty.post(
|
16
|
+
'http://localhost:3000/user',
|
17
|
+
multipart: true,
|
18
|
+
body: {
|
19
|
+
name: 'Foo Bar',
|
20
|
+
email: 'example@email.com'
|
21
|
+
}
|
22
|
+
)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require File.join(dir, 'httparty')
|
3
|
+
|
4
|
+
peer_cert = nil
|
5
|
+
HTTParty.get("https://www.example.com") do |fragment|
|
6
|
+
peer_cert ||= fragment.connection.peer_cert
|
7
|
+
end
|
8
|
+
|
9
|
+
puts "The server's certificate expires #{peer_cert.not_after}"
|
data/examples/stackexchange.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require File.join(dir, 'httparty')
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
# download file linux-4.6.4.tar.xz without using the memory
|
6
|
+
response = nil
|
7
|
+
filename = "linux-4.6.4.tar.xz"
|
8
|
+
url = "https://cdn.kernel.org/pub/linux/kernel/v4.x/#{filename}"
|
9
|
+
|
10
|
+
File.open(filename, "w") do |file|
|
11
|
+
response = HTTParty.get(url, stream_body: true) do |fragment|
|
12
|
+
if [301, 302].include?(fragment.code)
|
13
|
+
print "skip writing for redirect"
|
14
|
+
elsif fragment.code == 200
|
15
|
+
print "."
|
16
|
+
file.write(fragment)
|
17
|
+
else
|
18
|
+
raise StandardError, "Non-success status code while streaming #{fragment.code}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
puts
|
23
|
+
|
24
|
+
pp "Success: #{response.success?}"
|
25
|
+
pp File.stat(filename).inspect
|
26
|
+
File.unlink(filename)
|