fetch-api 0.2.0 → 0.3.0

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: 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
  - - ">="