fetch-api 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae66c4ee1f7d2b11e55480e6456be9eb78f5b1f6a2da0a22fb0cef1b4388328b
4
- data.tar.gz: 2995e13999494f718966a8dc3f293342593a17f88a0c003b702243ae710492e2
3
+ metadata.gz: 4686aace90255f6eceef759fe22002292101a0cb5cac4db2be0cbdf21cf398fa
4
+ data.tar.gz: 6dda2ecd4cde88807c27261f3d4eb866387b6e913e824cc0797e09618383284d
5
5
  SHA512:
6
- metadata.gz: 81683853c7d4e62b19dd0e4472b343958d656c361251239e160c44504b5671ba3b32078626433fd63f0be5a5a6290564cdc232f1db0a2c8dbbf462320b2102d8
7
- data.tar.gz: ca6a9131aa1a4a3c504e74521b3c8244e89a66cc4f5e2e9bb27a7974352c910a7a869cd1ab96b531ccf694f3565e5ba93ae8de21d374006ac533ddb0f289241e
6
+ metadata.gz: f5f6ba84be5732b1784ee0f67b4ea3b2e35a7e6b34d04c0b5808587f0d71bfc253f408bd3c7596cad79b2eddb7dbb6b794dfcf5adc34df77491a152c7a15120d
7
+ data.tar.gz: 41a3bab80a11cc7f0fc432504cc73d996e1d3b4dfad72b33ccd957bf77acff5bc0bfc00f50145d2dc561366f50b61885ae976650965a1aa408f5e748009aaec2
data/README.md CHANGED
@@ -29,8 +29,8 @@ require 'fetch-api'
29
29
 
30
30
  res = Fetch::API.fetch('https://example.com')
31
31
 
32
- # res is a Rack::Response object
33
- puts res.body.first
32
+ # res is a Fetch::Response object
33
+ puts res.body
34
34
  ```
35
35
 
36
36
  or
@@ -43,13 +43,24 @@ include Fetch::API
43
43
  res = fetch('https://example.com')
44
44
  ```
45
45
 
46
- Supported options are as follows:
46
+ Options for `fetch` method:
47
47
 
48
48
  - `method`: HTTP method (default: `'GET'`)
49
49
  - `headers`: Request headers (default: `{}`)
50
50
  - `body`: Request body (default: `nil`)
51
51
  - `redirect`: Follow redirects (one of `follow`, `error`, `manual`, default: `follow`)
52
52
 
53
+ Methods of `Fetch::Response` object:
54
+
55
+ - `body`: Response body (String)
56
+ - `headers`: Response headers
57
+ - `ok`: Whether the response was successful or not (status code is in the range 200-299)
58
+ - `redirected`: Whether the response is the result of a redirect
59
+ - `status`: Status code (e.g. `200`, `404`)
60
+ - `status_text`: Status text (e.g. `'OK'`, `'Not Found'`)
61
+ - `url`: Response URL
62
+ - `json(**args)`: An object that parses the response body as JSON. The arguments are passed to `JSON.parse`
63
+
53
64
  ### Post JSON
54
65
 
55
66
  ``` ruby
data/lib/fetch/client.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require_relative '../fetch'
2
2
  require_relative 'form_data'
3
+ require_relative 'headers'
4
+ require_relative 'response'
3
5
  require_relative 'url_search_params'
4
6
 
5
7
  require 'marcel'
6
8
  require 'net/http'
7
- require 'rack/response'
8
9
  require 'singleton'
9
10
  require 'uri'
10
11
 
@@ -12,10 +13,12 @@ module Fetch
12
13
  class Client
13
14
  include Singleton
14
15
 
15
- def fetch(resource, method: 'GET', headers: {}, body: nil, redirect: 'follow')
16
+ def fetch(resource, method: 'GET', headers: [], body: nil, redirect: 'follow', _redirected: false)
16
17
  uri = URI.parse(resource)
17
18
  req = Net::HTTP.const_get(method.capitalize).new(uri)
18
19
 
20
+ headers = Headers.new(headers) unless headers.is_a?(Headers)
21
+
19
22
  headers.each do |k, v|
20
23
  req[k] = v
21
24
  end
@@ -49,23 +52,37 @@ module Fetch
49
52
  when Net::HTTPRedirection
50
53
  case redirect
51
54
  when 'follow'
52
- fetch(res['Location'], method:, headers:, body:, redirect:)
55
+ fetch(res['Location'], method:, headers:, body:, redirect:, _redirected: true)
53
56
  when 'error'
54
57
  raise RedirectError, "redirected to #{res['Location']}"
55
58
  when 'manual'
56
- to_rack_response(res)
59
+ to_response(resource, res, _redirected)
57
60
  else
58
61
  raise ArgumentError, "invalid redirect option: #{redirect}"
59
62
  end
60
63
  else
61
- to_rack_response(res)
64
+ to_response(resource, res, _redirected)
62
65
  end
63
66
  end
64
67
 
65
68
  private
66
69
 
67
- def to_rack_response(res)
68
- Rack::Response.new(res.body, res.code, res.to_hash)
70
+ def to_response(url, res, redirected)
71
+ headers = Headers.new
72
+
73
+ res.each do |k, vs|
74
+ vs.split(', ').each do |v|
75
+ headers.append k, v
76
+ end
77
+ end
78
+
79
+ Response.new(
80
+ url: ,
81
+ status: res.code.to_i,
82
+ headers: ,
83
+ body: res.body,
84
+ redirected:
85
+ )
69
86
  end
70
87
  end
71
88
  end
@@ -0,0 +1,51 @@
1
+ module Fetch
2
+ class Headers
3
+ include Enumerable
4
+
5
+ def initialize(init = [])
6
+ @data = {}
7
+
8
+ init.each do |k, v|
9
+ append k, v
10
+ end
11
+ end
12
+
13
+ def append(key, value)
14
+ (@data[key.to_s.downcase] ||= []) << value
15
+ end
16
+
17
+ def delete(key)
18
+ @data.delete key.to_s.downcase
19
+ end
20
+
21
+ def entries
22
+ @data.map {|k, vs| [k, vs.join(', ')] }
23
+ end
24
+
25
+ def get(key)
26
+ @data[key.to_s.downcase]&.join(', ')
27
+ end
28
+
29
+ def has(key)
30
+ @data.key?(key.to_s.downcase)
31
+ end
32
+
33
+ def keys
34
+ @data.keys
35
+ end
36
+
37
+ def set(key, value)
38
+ @data[key.to_s.downcase] = [value]
39
+ end
40
+
41
+ def values
42
+ @data.values.map { _1.join(', ') }
43
+ end
44
+
45
+ def each(&block)
46
+ return enum_for(:each) unless block_given?
47
+
48
+ entries.each(&block)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ require 'json'
2
+ require 'rack/utils'
3
+
4
+ module Fetch
5
+ Response = Data.define(:url, :status, :headers, :body, :redirected) {
6
+ def ok
7
+ status.between?(200, 299)
8
+ end
9
+
10
+ def status_text
11
+ Rack::Utils::HTTP_STATUS_CODES[status]
12
+ end
13
+
14
+ def json(**opts)
15
+ JSON.parse(body, **opts)
16
+ end
17
+ }
18
+ end
data/lib/fetch/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fetch
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fetch-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keita Urashima
@@ -94,6 +94,8 @@ files:
94
94
  - lib/fetch/api.rb
95
95
  - lib/fetch/client.rb
96
96
  - lib/fetch/form_data.rb
97
+ - lib/fetch/headers.rb
98
+ - lib/fetch/response.rb
97
99
  - lib/fetch/url_search_params.rb
98
100
  - lib/fetch/version.rb
99
101
  - sig/fetch.rbs
@@ -111,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
113
  requirements:
112
114
  - - ">="
113
115
  - !ruby/object:Gem::Version
114
- version: 3.1.0
116
+ version: 3.2.0
115
117
  required_rubygems_version: !ruby/object:Gem::Requirement
116
118
  requirements:
117
119
  - - ">="