simple-http 0.3.4 → 0.3.5

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: af4c48df122f1e2d75e2646e7175e8356b3d29ed29090b7b2d50e5b045ac4c67
4
- data.tar.gz: 377058a3745909a67b4cf51307fcc87743bf5e054e681541e72b668473a07933
3
+ metadata.gz: 1cb6ffe1146cced4e3a576fcb776e13143be9a51e04352b421bec43eb18ca495
4
+ data.tar.gz: d071d8653cc3b7ad160a3e556a045d4441b425a1830b1c60ddef64703feab641
5
5
  SHA512:
6
- metadata.gz: 3bb65d9e2a2fe14e197fcab613fe587523fb932cd1f45b2648d2a160defe25762490223d66a338d342095abb83fafc3c564a6d3bd525c0dc5033728dad33dde8
7
- data.tar.gz: 910e7c3e08cd98361067e79082496b972cb24e0b3bc64365807d058119696e23758a3ac2e166ebdbe1dd678c8a0c4b10dcfaeeaf1c5b105cb7613fe8dd6765da
6
+ metadata.gz: fa509ffb0416b20cbb3cde6820d69a4daa6560f741ce69088dda99ed55b61394ec6964608a7a3156fb8cd17cdae7fc48b5d3d912efb5981f6658ddfc429faedb
7
+ data.tar.gz: 4c1b2ce423984fe8c5c043360fd40196bc9e79007182b6b6d2fce605948ac2e166b8ef9d4a6028e7687044164b323a397f02573d3c6885e8b226e4c2e708d04f
@@ -0,0 +1,81 @@
1
+ # The code in this module was originally taken from rack/media_type.rb
2
+ # and modified. We don't include a rack dependency here, since we don't
3
+ # want to use a server library in a client tool.
4
+
5
+ # parses content_type to return media_type and charset.
6
+ class Simple::HTTP::ContentTypeParser
7
+ SPLIT_PATTERN = %r{\s*[;,]\s*}
8
+
9
+ # The content_type value as being passed in.
10
+ attr_reader :content_type
11
+
12
+ # The media type (type/subtype) portion of the CONTENT_TYPE header
13
+ # without any media type parameters. e.g., when CONTENT_TYPE is
14
+ # "text/plain;charset=utf-8", the media-type is "text/plain".
15
+ #
16
+ # For more information on the use of media types in HTTP, see:
17
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
18
+ attr_reader :media_type
19
+
20
+ # The charset as embedded on the Content-Type header
21
+ attr_reader :charset
22
+
23
+ def initialize(content_type)
24
+ @content_type = content_type
25
+ @media_type = content_type.split(SPLIT_PATTERN, 2).first.downcase if content_type
26
+ @charset = extract_charset_from_content_type if content_type
27
+ end
28
+
29
+ # returns the encoding the body is supposed to be encoded as.
30
+ def encoding
31
+ resolve_encoding_name(charset || guess_encoding_name)
32
+ end
33
+
34
+ def reencode!(body)
35
+ body.force_encoding(encoding)
36
+ unless body.valid_encoding?
37
+ raise "Invalid payload: body is encoded invalid; encoding is #{content_type_parser.encoding.name}"
38
+ end
39
+
40
+ body
41
+ end
42
+
43
+ private
44
+
45
+ def resolve_encoding_name(str)
46
+ ::Encoding.find(str)
47
+ rescue ArgumentName
48
+ raise "Cannot resolve encoding name #{encoding_name.inspect} from Content-Type: #{content_type.inspect}"
49
+ end
50
+
51
+ # This method is being called when there is no charset value in the content_type header.
52
+ def guess_encoding_name
53
+ case media_type
54
+ when /^application\/json/, /^application\/xml/, /^text\// then "UTF-8"
55
+ else "ASCII-8BIT"
56
+ end
57
+ end
58
+
59
+ CHARSET_PARAMETER_NAME = "charset"
60
+
61
+ # The media type parameters provided in CONTENT_TYPE as a Hash, or
62
+ # an empty Hash if no CONTENT_TYPE or media-type parameters were
63
+ # provided. e.g., when the CONTENT_TYPE is "text/plain;charset=utf-8",
64
+ # this method responds with the following Hash:
65
+ # { 'charset' => 'utf-8' }
66
+ def extract_charset_from_content_type
67
+ content_type.split(SPLIT_PATTERN)[1..-1].each do |s|
68
+ k, v = s.split("=", 2)
69
+ next unless k.downcase == CHARSET_PARAMETER_NAME
70
+
71
+ return strip_double_quotes(v)
72
+ end
73
+
74
+ nil
75
+ end
76
+
77
+ def strip_double_quotes(str)
78
+ str = str[1..-2] if str[0] == '"' && str[-1] == '"'
79
+ str
80
+ end
81
+ end
@@ -1,4 +1,4 @@
1
- require_relative "./body_builder"
1
+ require_relative "./content_type_parser"
2
2
 
3
3
  class Simple::HTTP::Response
4
4
  class << self
@@ -18,48 +18,35 @@ class Simple::HTTP::Response
18
18
  end
19
19
  end
20
20
 
21
- BodyBuilder = Simple::HTTP::BodyBuilder
21
+ ContentTypeParser = Simple::HTTP::ContentTypeParser
22
22
 
23
23
  attr_reader :request
24
24
  attr_reader :status
25
25
  attr_reader :message
26
26
  attr_reader :headers
27
- attr_reader :original_body
27
+ attr_reader :body
28
+
29
+ # e.g "text/plain"
30
+ attr_reader :media_type
28
31
 
29
32
  private
30
33
 
31
34
  def initialize(request, body, headers, status, message)
32
35
  @request = request
33
36
  @headers = headers
34
- @status = status
37
+ @status = status
35
38
  @message = message
36
- @original_body = body
37
-
38
- # adjust encoding on original_body
39
- @body_builder = BodyBuilder.new(headers["Content-Type"])
40
39
 
41
- if @original_body && (charset = @body_builder.charset)
42
- @original_body.force_encoding(charset)
43
- end
40
+ # evaluate content type header, set media_type and set body encoding.
41
+ ctp = ContentTypeParser.new(headers["Content-Type"])
42
+ @media_type = ctp.media_type
43
+ @body = ctp.reencode!(body) if body
44
44
  end
45
45
 
46
46
  public
47
47
 
48
- # e.g "text/plain"
49
- def media_type
50
- @body_builder.media_type
51
- end
52
-
53
- # returns the body
54
- #
55
- # This method reencodes the text body into UTF-8. Non-text bodies should be
56
- # encoded as ASCII-8BIT (a.k.a. "BINARY")
57
- def body
58
- @body ||= @body_builder.reencode(@original_body)
59
- end
60
-
61
48
  def bytes
62
- @original_body&.bytesize || 0
49
+ @body ? @body.bytesize : 0
63
50
  end
64
51
 
65
52
  def to_s
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - radiospiel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-25 00:00:00.000000000 Z
11
+ date: 2020-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: expectation
@@ -39,9 +39,9 @@ files:
39
39
  - README.md
40
40
  - lib/simple-http.rb
41
41
  - lib/simple/http.rb
42
- - lib/simple/http/body_builder.rb
43
42
  - lib/simple/http/caching.rb
44
43
  - lib/simple/http/checked_response.rb
44
+ - lib/simple/http/content_type_parser.rb
45
45
  - lib/simple/http/driver/default.rb
46
46
  - lib/simple/http/driver/faraday.rb
47
47
  - lib/simple/http/errors.rb
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  - !ruby/object:Gem::Version
79
79
  version: '0'
80
80
  requirements: []
81
- rubygems_version: 3.0.6
81
+ rubygems_version: 3.0.4
82
82
  signing_key:
83
83
  specification_version: 4
84
84
  summary: Simple code for simple HTTP requests
@@ -1,71 +0,0 @@
1
- # This module originally was taken from rack/media_type.rb and modified:
2
- # we don't want to have a rack (which is a server toolset) dependency
3
- # in simple-http, which is a client after all.
4
-
5
- # parses content_type to return media_type and charset, and can reencode bodies.
6
- class Simple::HTTP::BodyBuilder
7
- SPLIT_PATTERN = %r{\s*[;,]\s*}
8
-
9
- def initialize(content_type)
10
- @media_type = content_type.split(SPLIT_PATTERN, 2).first.downcase if content_type
11
- @charset = fetch_content_type_param(content_type, "charset", default: nil)
12
- end
13
-
14
- # The media type (type/subtype) portion of the CONTENT_TYPE header
15
- # without any media type parameters. e.g., when CONTENT_TYPE is
16
- # "text/plain;charset=utf-8", the media-type is "text/plain".
17
- #
18
- # For more information on the use of media types in HTTP, see:
19
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
20
- attr_reader :media_type
21
-
22
- # The charset as embedded on the Content-Type header
23
- attr_reader :charset
24
-
25
- # returns the body
26
- #
27
- # This method reencodes the text body into UTF-8. Non-text bodies should be
28
- # encoded as ASCII-8BIT (a.k.a. "BINARY")
29
- def reencode(body)
30
- body&.encode(best_encoding)
31
- end
32
-
33
- private
34
-
35
- BINARY = ::Encoding.find "ASCII-8BIT"
36
- UTF8 = ::Encoding.find "UTF-8"
37
-
38
- # returns the encoding we want for the body.
39
- #
40
- # This method makes sure to reencode text bodies into UTF-8, and non-text
41
- # bodies as ASCII-8BIT (a.k.a. "BINARY")
42
- def best_encoding
43
- case media_type
44
- when /^application\/json/, /^application\/xml/, /^text\// then UTF8
45
- else BINARY
46
- end
47
- end
48
-
49
- # The media type parameters provided in CONTENT_TYPE as a Hash, or
50
- # an empty Hash if no CONTENT_TYPE or media-type parameters were
51
- # provided. e.g., when the CONTENT_TYPE is "text/plain;charset=utf-8",
52
- # this method responds with the following Hash:
53
- # { 'charset' => 'utf-8' }
54
- def fetch_content_type_param(content_type, parameter_name, default:)
55
- return default if content_type.nil?
56
-
57
- parameter_name = parameter_name.downcase
58
-
59
- content_type.split(SPLIT_PATTERN)[1..-1]
60
- .each do |s|
61
- k, v = s.split("=", 2)
62
- return strip_doublequotes(v) if k.downcase == parameter_name
63
- end
64
-
65
- default
66
- end
67
-
68
- def strip_doublequotes(str)
69
- str[0] == '"' && str[-1] == '"' ? str[1..-2] : str
70
- end
71
- end