tilia-http 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +35 -0
  5. data/.simplecov +4 -0
  6. data/.travis.yml +3 -0
  7. data/CHANGELOG.sabre.md +235 -0
  8. data/CONTRIBUTING.md +25 -0
  9. data/Gemfile +18 -0
  10. data/Gemfile.lock +69 -0
  11. data/LICENSE +27 -0
  12. data/LICENSE.sabre +27 -0
  13. data/README.md +68 -0
  14. data/Rakefile +17 -0
  15. data/examples/asyncclient.rb +45 -0
  16. data/examples/basicauth.rb +39 -0
  17. data/examples/client.rb +20 -0
  18. data/examples/reverseproxy.rb +39 -0
  19. data/examples/stringify.rb +37 -0
  20. data/lib/tilia/http/auth/abstract_auth.rb +51 -0
  21. data/lib/tilia/http/auth/aws.rb +191 -0
  22. data/lib/tilia/http/auth/basic.rb +43 -0
  23. data/lib/tilia/http/auth/bearer.rb +37 -0
  24. data/lib/tilia/http/auth/digest.rb +187 -0
  25. data/lib/tilia/http/auth.rb +12 -0
  26. data/lib/tilia/http/client.rb +452 -0
  27. data/lib/tilia/http/client_exception.rb +15 -0
  28. data/lib/tilia/http/client_http_exception.rb +37 -0
  29. data/lib/tilia/http/http_exception.rb +21 -0
  30. data/lib/tilia/http/message.rb +241 -0
  31. data/lib/tilia/http/message_decorator_trait.rb +183 -0
  32. data/lib/tilia/http/message_interface.rb +154 -0
  33. data/lib/tilia/http/request.rb +235 -0
  34. data/lib/tilia/http/request_decorator.rb +160 -0
  35. data/lib/tilia/http/request_interface.rb +126 -0
  36. data/lib/tilia/http/response.rb +164 -0
  37. data/lib/tilia/http/response_decorator.rb +58 -0
  38. data/lib/tilia/http/response_interface.rb +36 -0
  39. data/lib/tilia/http/sapi.rb +165 -0
  40. data/lib/tilia/http/url_util.rb +70 -0
  41. data/lib/tilia/http/util.rb +51 -0
  42. data/lib/tilia/http/version.rb +9 -0
  43. data/lib/tilia/http.rb +416 -0
  44. data/test/http/auth/aws_test.rb +189 -0
  45. data/test/http/auth/basic_test.rb +60 -0
  46. data/test/http/auth/bearer_test.rb +47 -0
  47. data/test/http/auth/digest_test.rb +141 -0
  48. data/test/http/client_mock.rb +101 -0
  49. data/test/http/client_test.rb +331 -0
  50. data/test/http/message_decorator_test.rb +67 -0
  51. data/test/http/message_test.rb +163 -0
  52. data/test/http/request_decorator_test.rb +87 -0
  53. data/test/http/request_test.rb +132 -0
  54. data/test/http/response_decorator_test.rb +28 -0
  55. data/test/http/response_test.rb +38 -0
  56. data/test/http/sapi_mock.rb +12 -0
  57. data/test/http/sapi_test.rb +133 -0
  58. data/test/http/url_util_test.rb +155 -0
  59. data/test/http/util_test.rb +186 -0
  60. data/test/http_test.rb +102 -0
  61. data/test/test_helper.rb +6 -0
  62. data/tilia-http.gemspec +18 -0
  63. metadata +192 -0
@@ -0,0 +1,58 @@
1
+ module Tilia
2
+ module Http
3
+ # Response Decorator
4
+ #
5
+ # This helper class allows you to easily create decorators for the Response
6
+ # object.
7
+ class ResponseDecorator
8
+ include Tilia::Http::ResponseInterface
9
+ include Tilia::Http::MessageDecoratorTrait
10
+
11
+ # Constructor.
12
+ #
13
+ # @param ResponseInterface inner
14
+ def initialize(inner)
15
+ @inner = inner
16
+ end
17
+
18
+ # Returns the current HTTP status code.
19
+ #
20
+ # @return int
21
+ def status
22
+ @inner.status
23
+ end
24
+
25
+ # Returns the human-readable status string.
26
+ #
27
+ # In the case of a 200, this may for example be 'OK'.
28
+ #
29
+ # @return [String]
30
+ def status_text
31
+ @inner.status_text
32
+ end
33
+
34
+ # Sets the HTTP status code.
35
+ #
36
+ # This can be either the full HTTP status code with human readable string,
37
+ # for example: "403 I can't let you do that, Dave".
38
+ #
39
+ # Or just the code, in which case the appropriate default message will be
40
+ # added.
41
+ #
42
+ # @param [String, Fixnum] status
43
+ # @return [void]
44
+ def status=(status)
45
+ @inner.status = status
46
+ end
47
+
48
+ # Serializes the request object as a string.
49
+ #
50
+ # This is useful for debugging purposes.
51
+ #
52
+ # @return [String]
53
+ def to_s
54
+ @inner.to_s
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,36 @@
1
+ module Tilia
2
+ module Http
3
+ # This interface represents a HTTP response.
4
+ module ResponseInterface
5
+ include Tilia::Http::MessageInterface
6
+
7
+ # Returns the current HTTP status code.
8
+ #
9
+ # @return int
10
+ def status
11
+ end
12
+
13
+ # Returns the human-readable status string.
14
+ #
15
+ # In the case of a 200, this may for example be 'OK'.
16
+ #
17
+ # @return [String]
18
+ def status_text
19
+ end
20
+
21
+ # Sets the HTTP status code.
22
+ #
23
+ # This can be either the full HTTP status code with human readable string,
24
+ # for example: "403 I can't let you do that, Dave".
25
+ #
26
+ # Or just the code, in which case the appropriate default message will be
27
+ # added.
28
+ #
29
+ # @param [String, Fixnum] status
30
+ # @throws \InvalidArgumentExeption
31
+ # @return [void]
32
+ def status=(_status)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,165 @@
1
+ require 'stringio'
2
+ require 'base64'
3
+ module Tilia
4
+ module Http
5
+ # PHP SAPI
6
+ #
7
+ # This object is responsible for:
8
+ # 1. Constructing a Request object based on the current HTTP request sent to
9
+ # the PHP process.
10
+ # 2. Sending the Response object back to the client.
11
+ #
12
+ # It could be said that this class provides a mapping between the Request and
13
+ # Response objects, and php's:
14
+ #
15
+ # * $_SERVER
16
+ # * $_POST
17
+ # * $_FILES
18
+ # * php://input
19
+ # * echo
20
+ # * header
21
+ # * php://output
22
+ #
23
+ # You can choose to either call all these methods statically, but you can also
24
+ # instantiate this as an object to allow for polymorhpism.
25
+ class Sapi
26
+ # This static method will create a new Request object, based on the
27
+ # current PHP request.
28
+ #
29
+ # @return Request
30
+ def self.request
31
+ fail NotImplementedError, 'This object method now is an instance method'
32
+ end
33
+
34
+ # Sends the HTTP response back to a HTTP client.
35
+ #
36
+ # This calls php's header function and streams the body to php://output.
37
+ #
38
+ # @param ResponseInterface response
39
+ # @return [void]
40
+ def self.send_response(response)
41
+ # RUBY: Rack does not support HTTP Version (?)
42
+ # header("HTTP/#{response.http_version} #{response.status} #{response.status_text}")
43
+
44
+ status = response.status
45
+ headers = {}
46
+ response.headers.each do |key, value|
47
+ headers[key] = value.join("\n")
48
+ end
49
+
50
+ body = response.body_as_stream
51
+ content_length = response.header('Content-Length')
52
+ if content_length
53
+ output = StringIO.new
54
+ output.write body.read(content_length.to_i)
55
+ output.rewind
56
+ body = output
57
+ end
58
+
59
+ [status, headers, body]
60
+ end
61
+
62
+ # This static method will create a new Request object, based on a PHP
63
+ # $_SERVER array.
64
+ #
65
+ # @param array server_array
66
+ # @return Request
67
+ def self.create_from_server_array(server_array)
68
+ headers = {}
69
+ method = nil
70
+ url = nil
71
+ http_version = '1.1'
72
+
73
+ protocol = 'http'
74
+ host_name = 'localhost'
75
+
76
+ server_array.each do |key, value|
77
+ case key
78
+ when 'SERVER_PROTOCOL'
79
+ http_version = '1.0' if value == 'HTTP/1.0'
80
+ when 'REQUEST_METHOD'
81
+ method = value
82
+ when 'REQUEST_URI'
83
+ url = value
84
+
85
+ # These sometimes should up without a HTTP_ prefix
86
+ when 'CONTENT_TYPE'
87
+ headers['Content-Type'] = value
88
+ when 'CONTENT_LENGTH'
89
+ headers['Content-Length'] = value
90
+
91
+ # mod_php on apache will put credentials in these variables.
92
+ # (fast)cgi does not usually do this, however.
93
+ when 'PHP_AUTH_USER'
94
+ if server_array.key? 'PHP_AUTH_PW'
95
+ headers['Authorization'] = "Basic #{Base64.strict_encode64 "#{value}:#{server_array['PHP_AUTH_PW']}"}"
96
+ end
97
+ when 'PHP_AUTH_DIGEST'
98
+ headers['Authorization'] = "Digest #{value}"
99
+
100
+ # Apache may prefix the HTTP_AUTHORIZATION header with
101
+ # REDIRECT_, if mod_rewrite was used.
102
+ when 'REDIRECT_HTTP_AUTHORIZATION'
103
+ headers['Authorization'] = value
104
+
105
+ when 'HTTP_HOST'
106
+ host_name = value
107
+ headers['Host'] = value
108
+
109
+ when 'HTTPS'
110
+ protocol = 'https' if value && value != 'off'
111
+
112
+ # RUBY
113
+ when 'rack.url_scheme'
114
+ protocol = value
115
+
116
+ else
117
+ if key.index('HTTP_') == 0
118
+ # It's a HTTP header
119
+
120
+ # Normalizing it to be prettier
121
+ header = key[5..-1].downcase
122
+
123
+ # Transforming dashes into spaces, and uppercasing
124
+ # every first letter.
125
+ # Turning spaces into dashes.
126
+ header = header.split(/_/).map(&:capitalize).join('-')
127
+
128
+ headers[header] = value
129
+ end
130
+ end
131
+ end
132
+
133
+ r = Tilia::Http::Request.new(method, url, headers)
134
+ r.http_version = http_version
135
+ r.raw_server_data = server_array
136
+ r.absolute_url = "#{protocol}://#{host_name}#{url}"
137
+ r
138
+ end
139
+
140
+ # TODO: document
141
+ def initialize(env)
142
+ @env = env
143
+ @rack_request = Rack::Request.new(env)
144
+ end
145
+
146
+ # TODO: document
147
+ def request
148
+ r = create_from_server_array(@env)
149
+ r.body = StringIO.new
150
+ r.post_data = @rack_request.POST
151
+ r
152
+ end
153
+
154
+ # TODO: document
155
+ def send_response(response)
156
+ self.class.send_response(response)
157
+ end
158
+
159
+ # TODO: document
160
+ def create_from_server_array(server_array)
161
+ self.class.create_from_server_array(server_array)
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,70 @@
1
+ module Tilia
2
+ module Http
3
+ # URL utility class
4
+ #
5
+ # Note: this class is deprecated. All its functionality moved to functions.php
6
+ # or sabre\uri.
7
+ #
8
+ # @deprectated
9
+ module UrlUtil
10
+ # Encodes the path of a url.
11
+ #
12
+ # slashes (/) are treated as path-separators.
13
+ #
14
+ # @deprecated use \Sabre\HTTP\encode_path
15
+ # @param [String] path
16
+ # @return [String]
17
+ def self.encode_path(path)
18
+ Tilia::Http.encode_path(path)
19
+ end
20
+
21
+ # Encodes a 1 segment of a path
22
+ #
23
+ # Slashes are considered part of the name, and are encoded as %2f
24
+ #
25
+ # @deprecated use \Sabre\HTTP\encode_path_segment
26
+ # @param [String] path_segment
27
+ # @return [String]
28
+ def self.encode_path_segment(path_segment)
29
+ Tilia::Http.encode_path_segment(path_segment)
30
+ end
31
+
32
+ # Decodes a url-encoded path
33
+ #
34
+ # @deprecated use \Sabre\HTTP\decodePath
35
+ # @param [String] path
36
+ # @return [String]
37
+ def self.decode_path(path)
38
+ Tilia::Http.decode_path(path)
39
+ end
40
+
41
+ # Decodes a url-encoded path segment
42
+ #
43
+ # @deprecated use \Sabre\HTTP\decode_path_segment
44
+ # @param [String] path
45
+ # @return [String]
46
+ def self.decode_path_segment(path)
47
+ Tilia::Http.decode_path_segment(path)
48
+ end
49
+
50
+ # Returns the 'dirname' and 'basename' for a path.
51
+ #
52
+ # @deprecated Use Sabre\Uri\split.
53
+ # @param [String] path
54
+ # @return array
55
+ def self.split_path(path)
56
+ Tilia::Uri.split(path)
57
+ end
58
+
59
+ # Resolves relative urls, like a browser would.
60
+ #
61
+ # @deprecated Use Sabre\Uri\resolve.
62
+ # @param [String] base_path
63
+ # @param [String] new_path
64
+ # @return [String]
65
+ def self.resolve(base_path, new_path)
66
+ Tilia::Uri.resolve(base_path, new_path)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,51 @@
1
+ module Tilia
2
+ module Http
3
+ # HTTP utility methods
4
+ #
5
+ # @deprecated All these functions moved to the Tilia::Http namespace
6
+ module Util
7
+ # Content negotiation
8
+ #
9
+ # @deprecated Use Tilia::Http::negotiate_content_type
10
+ # @param [String, nil] accept_header_value
11
+ # @param array available_options
12
+ # @return [String, nil]
13
+ def self.negotiate_content_type(accept_header_value, available_options)
14
+ Http.negotiate_content_type(accept_header_value, available_options)
15
+ end
16
+
17
+ # Deprecated! Use negotiateContentType.
18
+ #
19
+ # @deprecated Use Tilia::Http::negotiate_content_type
20
+ # @param [String, nil] accept_header
21
+ # @param array available_options
22
+ # @return [String, nil]
23
+ def self.negotiate(accept_header_value, available_options)
24
+ Http.negotiate_content_type(accept_header_value, available_options)
25
+ end
26
+
27
+ # Parses a RFC2616-compatible date string
28
+ #
29
+ # This method returns false if the date is invalid
30
+ #
31
+ # @deprecated Use Tilia::Http::parse_date
32
+ # @param [String] date_header
33
+ # @return bool|DateTime
34
+ def self.parse_http_date(date_header)
35
+ Http.parse_date(date_header)
36
+ end
37
+
38
+ # Transforms a DateTime object to HTTP's most common date format.
39
+ #
40
+ # We're serializing it as the RFC 1123 date, which, for HTTP must be
41
+ # specified as GMT.
42
+ #
43
+ # @deprecated Use Tilia::Http::to_date
44
+ # @param \DateTime date_time
45
+ # @return [String]
46
+ def self.to_http_date(date_time)
47
+ Http.to_date(date_time)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,9 @@
1
+ module Tilia
2
+ module Http
3
+ # This class contains the version number for the HTTP package
4
+ class Version
5
+ # Full version number
6
+ VERSION = '4.1.0'
7
+ end
8
+ end
9
+ end