simple-http 0.3.4 → 0.3.5
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 +4 -4
- data/lib/simple/http/content_type_parser.rb +81 -0
- data/lib/simple/http/response.rb +12 -25
- metadata +4 -4
- data/lib/simple/http/body_builder.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cb6ffe1146cced4e3a576fcb776e13143be9a51e04352b421bec43eb18ca495
|
4
|
+
data.tar.gz: d071d8653cc3b7ad160a3e556a045d4441b425a1830b1c60ddef64703feab641
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/simple/http/response.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative "./
|
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
|
-
|
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 :
|
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
|
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
|
-
|
42
|
-
|
43
|
-
|
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
|
-
@
|
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
|
+
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:
|
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.
|
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
|