fetch-api 0.2.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae66c4ee1f7d2b11e55480e6456be9eb78f5b1f6a2da0a22fb0cef1b4388328b
4
- data.tar.gz: 2995e13999494f718966a8dc3f293342593a17f88a0c003b702243ae710492e2
3
+ metadata.gz: dc8cbe5804a5286df86b5840189dbbe3c1cfc77e68bfd33b0ba3244be99af5c2
4
+ data.tar.gz: f72c409553a6b531803d084d8e862c77329ef785579e9a11b5a461fadd481ca3
5
5
  SHA512:
6
- metadata.gz: 81683853c7d4e62b19dd0e4472b343958d656c361251239e160c44504b5671ba3b32078626433fd63f0be5a5a6290564cdc232f1db0a2c8dbbf462320b2102d8
7
- data.tar.gz: ca6a9131aa1a4a3c504e74521b3c8244e89a66cc4f5e2e9bb27a7974352c910a7a869cd1ab96b531ccf694f3565e5ba93ae8de21d374006ac533ddb0f289241e
6
+ metadata.gz: 6051e1551078686b6624604b23966804684f7a764ffb76c467e79cf5bfd09e0025c8dd315803b0e7c8b1fe83874e349984c1a3fa325306fb4c09d1f855524e0c
7
+ data.tar.gz: 6340aa6ca403e46a023753fd08144081009512a3b97c12a3b035ac58aa951e49e1218e7d543a52151d9600022ed40773f00c655926eaa5d59b7fc9c3f9fc8ca3
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,50 @@
1
+ module Fetch
2
+ class Headers
3
+ include Enumerable
4
+
5
+ def initialize(init = [])
6
+ @entries = []
7
+
8
+ init.each do |k, v|
9
+ append k, v
10
+ end
11
+ end
12
+
13
+ attr_reader :entries
14
+
15
+ def append(key, value)
16
+ @entries << [key.to_s.downcase, value]
17
+ end
18
+
19
+ def delete(key)
20
+ @entries.delete_if {|k,| k == key.to_s.downcase }
21
+ end
22
+
23
+ def get(key)
24
+ @entries.select {|k,| k == key.to_s.downcase }.map(&:last).join(', ')
25
+ end
26
+
27
+ def has(key)
28
+ @entries.any? {|k,| k == key.to_s.downcase }
29
+ end
30
+
31
+ def keys
32
+ @entries.map(&:first)
33
+ end
34
+
35
+ def set(key, value)
36
+ delete key
37
+ append key, value
38
+ end
39
+
40
+ def values
41
+ @entries.map(&:last)
42
+ end
43
+
44
+ def each(&block)
45
+ return enum_for(:each) unless block_given?
46
+
47
+ @entries.each(&block)
48
+ end
49
+ end
50
+ 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.0'
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.0
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
  - - ">="