wrest 0.0.9-java → 0.1.0-java
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.
- data/CHANGELOG +34 -0
- data/README.rdoc +16 -10
- data/Rakefile +362 -124
- data/VERSION.yml +2 -2
- data/examples/delicious.rb +17 -7
- data/examples/facebook.rb +101 -0
- data/examples/keep_alive.rb +37 -0
- data/examples/twitter.rb +3 -3
- data/examples/twitter_public_timeline.rb +11 -4
- data/examples/wow_realm_status.rb +8 -2
- data/{spec/functional/sample_rails_app/public/favicon.ico → init.rb} +0 -0
- data/lib/wrest/components/{attributes_container → container}/alias_accessors.rb +4 -4
- data/lib/wrest/components/{attributes_container → container}/typecaster.rb +1 -1
- data/lib/wrest/components/{attributes_container.rb → container.rb} +46 -16
- data/lib/wrest/components/mutators.rb +4 -4
- data/lib/wrest/components/translators/json.rb +2 -2
- data/lib/wrest/components/translators/xml.rb +3 -2
- data/lib/wrest/components/translators.rb +3 -3
- data/lib/wrest/components.rb +3 -3
- data/lib/wrest/core_ext/hash.rb +1 -1
- data/lib/wrest/core_ext/string.rb +1 -1
- data/lib/wrest/curl/delete.rb +23 -0
- data/lib/wrest/curl/get.rb +23 -0
- data/lib/wrest/curl/options.rb +16 -0
- data/lib/wrest/curl/post.rb +23 -0
- data/lib/wrest/curl/put.rb +23 -0
- data/lib/wrest/curl/request.rb +95 -0
- data/lib/wrest/curl/response.rb +63 -0
- data/lib/wrest/curl/session.rb +57 -0
- data/lib/wrest/curl.rb +49 -0
- data/lib/wrest/exceptions.rb +16 -1
- data/lib/wrest/http_shared/headers.rb +350 -0
- data/lib/wrest/http_shared/standard_headers.rb +21 -0
- data/lib/wrest/http_shared/standard_tokens.rb +18 -0
- data/lib/wrest/http_shared.rb +24 -0
- data/lib/wrest/native/connection_factory.rb +23 -0
- data/lib/wrest/{http → native}/delete.rb +1 -1
- data/lib/wrest/{http → native}/get.rb +1 -1
- data/lib/wrest/{http → native}/options.rb +1 -1
- data/lib/wrest/{http → native}/post.rb +1 -1
- data/lib/wrest/{http → native}/put.rb +1 -1
- data/lib/wrest/{http → native}/redirection.rb +4 -1
- data/lib/wrest/{http → native}/request.rb +32 -20
- data/lib/wrest/{http → native}/response.rb +12 -4
- data/lib/wrest/native/session.rb +57 -0
- data/lib/wrest/native.rb +32 -0
- data/lib/wrest/resource/base.rb +1 -1
- data/lib/wrest/resource.rb +1 -1
- data/lib/wrest/test/request_patches.rb +5 -0
- data/lib/wrest/test.rb +1 -0
- data/lib/wrest/uri.rb +31 -3
- data/lib/wrest/version.rb +2 -2
- data/lib/wrest.rb +52 -16
- data/spec/unit/spec_helper.rb +12 -3
- data/spec/unit/wrest/components/attributes_container/alias_accessors_spec.rb +2 -2
- data/spec/unit/wrest/components/attributes_container/typecaster_spec.rb +6 -6
- data/spec/unit/wrest/components/attributes_container_spec.rb +44 -12
- data/spec/unit/wrest/components/translators/xml_spec.rb +7 -3
- data/spec/unit/wrest/curl/request_spec.rb +19 -0
- data/spec/unit/wrest/curl/response_spec.rb +16 -0
- data/spec/unit/wrest/http/response_spec.rb +17 -38
- data/spec/unit/wrest/{http → native}/redirection_spec.rb +5 -5
- data/spec/unit/wrest/{http → native}/request_spec.rb +15 -14
- data/spec/unit/wrest/native/response_spec.rb +72 -0
- data/spec/unit/wrest/native/session_spec.rb +74 -0
- data/spec/unit/wrest/resource/base_spec.rb +2 -2
- data/spec/unit/wrest/uri_spec.rb +51 -11
- data/wrest.gemspec +168 -0
- metadata +60 -164
- data/lib/wrest/http.rb +0 -25
- data/spec/functional/sample_rails_app/README +0 -3
- data/spec/functional/sample_rails_app/Rakefile +0 -10
- data/spec/functional/sample_rails_app/app/controllers/application_controller.rb +0 -10
- data/spec/functional/sample_rails_app/app/controllers/lead_bottles_controller.rb +0 -7
- data/spec/functional/sample_rails_app/app/helpers/application_helper.rb +0 -3
- data/spec/functional/sample_rails_app/app/models/bottle.rb +0 -3
- data/spec/functional/sample_rails_app/app/models/glass_bottle.rb +0 -3
- data/spec/functional/sample_rails_app/app/models/lead_bottle.rb +0 -3
- data/spec/functional/sample_rails_app/config/boot.rb +0 -110
- data/spec/functional/sample_rails_app/config/database.yml +0 -16
- data/spec/functional/sample_rails_app/config/environment.rb +0 -42
- data/spec/functional/sample_rails_app/config/environments/development.rb +0 -17
- data/spec/functional/sample_rails_app/config/environments/production.rb +0 -28
- data/spec/functional/sample_rails_app/config/environments/test.rb +0 -28
- data/spec/functional/sample_rails_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/functional/sample_rails_app/config/initializers/inflections.rb +0 -10
- data/spec/functional/sample_rails_app/config/initializers/mime_types.rb +0 -5
- data/spec/functional/sample_rails_app/config/initializers/new_rails_defaults.rb +0 -19
- data/spec/functional/sample_rails_app/config/initializers/session_store.rb +0 -15
- data/spec/functional/sample_rails_app/config/locales/en.yml +0 -5
- data/spec/functional/sample_rails_app/config/routes.rb +0 -3
- data/spec/functional/sample_rails_app/db/development.sqlite3 +0 -0
- data/spec/functional/sample_rails_app/db/migrate/20090319115628_create_bottle.rb +0 -13
- data/spec/functional/sample_rails_app/db/schema.rb +0 -20
- data/spec/functional/sample_rails_app/db/test.sqlite3 +0 -0
- data/spec/functional/sample_rails_app/log/development.log +0 -1
- data/spec/functional/sample_rails_app/public/404.html +0 -30
- data/spec/functional/sample_rails_app/public/422.html +0 -30
- data/spec/functional/sample_rails_app/public/500.html +0 -30
- data/spec/functional/sample_rails_app/public/images/rails.png +0 -0
- data/spec/functional/sample_rails_app/public/index.html +0 -275
- data/spec/functional/sample_rails_app/public/robots.txt +0 -5
- data/spec/functional/sample_rails_app/script/about +0 -4
- data/spec/functional/sample_rails_app/script/autospec +0 -6
- data/spec/functional/sample_rails_app/script/console +0 -3
- data/spec/functional/sample_rails_app/script/dbconsole +0 -3
- data/spec/functional/sample_rails_app/script/destroy +0 -3
- data/spec/functional/sample_rails_app/script/generate +0 -3
- data/spec/functional/sample_rails_app/script/performance/benchmarker +0 -3
- data/spec/functional/sample_rails_app/script/performance/profiler +0 -3
- data/spec/functional/sample_rails_app/script/plugin +0 -3
- data/spec/functional/sample_rails_app/script/runner +0 -3
- data/spec/functional/sample_rails_app/script/server +0 -3
- data/spec/functional/sample_rails_app/script/spec +0 -10
- data/spec/functional/sample_rails_app/script/spec_server +0 -9
- data/spec/functional/sample_rails_app/test/performance/browsing_test.rb +0 -9
- data/spec/functional/sample_rails_app/test/test_helper.rb +0 -38
- data/spec/functional/sample_rails_app/tmtags +0 -2559
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/MIT-LICENSE +0 -20
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/README.rdoc +0 -100
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/Rakefile +0 -18
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/init.rb +0 -5
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/install.rb +0 -1
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/base.rb +0 -140
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources.rb +0 -16
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/resources_controller.rb +0 -26
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/controllers/routes_controller.rb +0 -16
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/api.rb +0 -26
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/exception.rb +0 -23
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/core_extensions/from_json.rb +0 -15
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/dispatch.rb +0 -235
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/models/resourced_route.rb +0 -84
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/query.rb +0 -337
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/html.rb +0 -50
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/json.rb +0 -75
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render/xml.rb +0 -65
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/render.rb +0 -63
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/retrieve.rb +0 -74
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full/version.rb +0 -9
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/lib/resource_full.rb +0 -14
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/base_spec.rb +0 -88
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/controllers/resources_spec.rb +0 -29
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/dispatch_spec.rb +0 -262
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/models/resourced_route_spec.rb +0 -62
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query/parameter_spec.rb +0 -57
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/query_spec.rb +0 -462
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/html_spec.rb +0 -4
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/json_spec.rb +0 -107
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render/xml_spec.rb +0 -98
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/render_spec.rb +0 -5
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/resource_full/retrieve_spec.rb +0 -173
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/spec/spec_helper.rb +0 -98
- data/spec/functional/sample_rails_app/vendor/plugins/resource_full/uninstall.rb +0 -1
- data/spec/functional/spec_helper.rb +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Copyright 2009 Sidu Ponnappa
|
|
2
|
+
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
7
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
|
+
|
|
10
|
+
module Wrest::Curl
|
|
11
|
+
# This represents a HTTP request. Typically you will never need to instantiate
|
|
12
|
+
# one of these yourself - you can use one of the more conveient APIs via Wrest::Uri
|
|
13
|
+
# or Wrest::Http::Get etc. instead.
|
|
14
|
+
class Request
|
|
15
|
+
attr_reader :http_request, :uri, :body, :headers, :username, :password, :follow_redirects,
|
|
16
|
+
:follow_redirects_limit, :timeout, :connection, :parameters, :auth_type
|
|
17
|
+
# Valid tuples for the options are:
|
|
18
|
+
# :username => String, defaults to nil
|
|
19
|
+
# :password => String, defaults to nil
|
|
20
|
+
# :follow_redirects => Boolean, defaults to true for Get, false for anything else
|
|
21
|
+
# :follow_redirects_limit => Integer, defaults to 5. This is the number of redirects
|
|
22
|
+
# that Wrest will automatically follow before raising an
|
|
23
|
+
# Wrest::Exceptions::AutoRedirectLimitExceeded exception.
|
|
24
|
+
# For example, if you set this to 1, the very first redirect
|
|
25
|
+
# will raise the exception.
|
|
26
|
+
# :timeout => The period, in seconds, after which a Timeout::Error is raised
|
|
27
|
+
# in the event of a connection failing to open. Defaulted to 60 by Uri#create_connection.
|
|
28
|
+
# :connection => The HTTP Connection object to use. This is how a keep-alive connection can be
|
|
29
|
+
# used for multiple requests. Not yet fully implemented for Curl.
|
|
30
|
+
#
|
|
31
|
+
# Curl specific options:
|
|
32
|
+
# :auth_type => This is a curl specific option and can be one of :basic, :digest, or :any. The default is :basic.
|
|
33
|
+
def initialize(wrest_uri, http_verb, parameters = {}, body = nil, headers = {}, options = {})
|
|
34
|
+
@uri = wrest_uri
|
|
35
|
+
@headers = headers.stringify_keys
|
|
36
|
+
@parameters = parameters
|
|
37
|
+
@body = body
|
|
38
|
+
|
|
39
|
+
@options = options.clone
|
|
40
|
+
@auth_type = @options[:auth_type] || :basic
|
|
41
|
+
@username = @options[:username]
|
|
42
|
+
@password = @options[:password]
|
|
43
|
+
@follow_redirects = (@options[:follow_redirects] ||= false)
|
|
44
|
+
|
|
45
|
+
@follow_redirects_limit = (@options[:follow_redirects_limit] ||= 5)
|
|
46
|
+
@timeout = @options[:timeout] || 60
|
|
47
|
+
@connection = @options[:connection]
|
|
48
|
+
|
|
49
|
+
@http_request = Patron::Request.new
|
|
50
|
+
@http_request.action = http_verb
|
|
51
|
+
@http_request.upload_data = body
|
|
52
|
+
@http_request.headers = headers
|
|
53
|
+
@http_request.username = username
|
|
54
|
+
@http_request.password = password
|
|
55
|
+
@http_request.auth_type = auth_type
|
|
56
|
+
@http_request.url = parameters.empty? ? uri.to_s : "#{uri.to_s}?#{parameters.to_query}"
|
|
57
|
+
@http_request.max_redirects = follow_redirects_limit if follow_redirects
|
|
58
|
+
@http_request.timeout = @timeout
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Makes a request and returns a Wrest::Http::Response.
|
|
62
|
+
# Data about the request is and logged to Wrest.logger
|
|
63
|
+
# The log entry contains the following information:
|
|
64
|
+
#
|
|
65
|
+
# --> indicates a request
|
|
66
|
+
# <-- indicates a response
|
|
67
|
+
#
|
|
68
|
+
# The type of request is mentioned in caps, followed by a hash
|
|
69
|
+
# uniquely uniquely identifying a particular request/response pair.
|
|
70
|
+
# In a multi-process or multi-threaded scenario, this can be used
|
|
71
|
+
# to identify request-response pairs.
|
|
72
|
+
#
|
|
73
|
+
# The request hash is followed by a connection hash; requests using the
|
|
74
|
+
# same connection (effectively a keep-alive connection) will have the
|
|
75
|
+
# same connection hash.
|
|
76
|
+
#
|
|
77
|
+
# This is followed by the response code, the payload size and the time taken.
|
|
78
|
+
def invoke
|
|
79
|
+
response = nil
|
|
80
|
+
|
|
81
|
+
@connection ||= Patron::Session.new
|
|
82
|
+
raise ArgumentError, "Empty URL" if http_request.url.empty?
|
|
83
|
+
|
|
84
|
+
prefix = "#{http_request.action.to_s.upcase} #{http_request.hash} #{connection.hash}"
|
|
85
|
+
|
|
86
|
+
Wrest.logger.debug "--> (#{prefix}) #{http_request.url}"
|
|
87
|
+
time = Benchmark.realtime { response = Wrest::Curl::Response.new(connection.handle_request(http_request))}
|
|
88
|
+
Wrest.logger.debug "<-- (#{prefix}) %s (%d bytes %.2fs)" % [response.message, response.body ? response.body.length : 0, time]
|
|
89
|
+
|
|
90
|
+
response
|
|
91
|
+
rescue Patron::TimeoutError => e
|
|
92
|
+
raise Wrest::Exceptions::Timeout.new(e)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Copyright 2009 Sidu Ponnappa
|
|
2
|
+
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at Http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
7
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
|
+
|
|
10
|
+
module Wrest #:nodoc:
|
|
11
|
+
module Curl #:nodoc:
|
|
12
|
+
# Decorates a response providing support for deserialisation.
|
|
13
|
+
class Response
|
|
14
|
+
attr_reader :http_response
|
|
15
|
+
include HttpShared::Headers
|
|
16
|
+
|
|
17
|
+
extend Forwardable
|
|
18
|
+
def_delegators :@http_response, :body, :headers
|
|
19
|
+
|
|
20
|
+
def initialize(http_response)
|
|
21
|
+
@http_response = http_response
|
|
22
|
+
initialize_http_header
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def deserialise
|
|
26
|
+
deserialise_using(Wrest::Components::Translators.lookup(content_type))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def deserialise_using(translator)
|
|
30
|
+
translator.deserialise(@http_response)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def code
|
|
34
|
+
@http_response.status
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def message
|
|
38
|
+
@http_response.status_line
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def content_length
|
|
42
|
+
self[H::ContentLength].try(:to_i)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def content_type
|
|
46
|
+
self[H::ContentType].split(';').first
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# A null object implementation - invoking this method on
|
|
50
|
+
# a response simply returns the same response unless
|
|
51
|
+
# the response is a Redirection (code 3xx), in which case a
|
|
52
|
+
# get is invoked on the url stored in the response headers
|
|
53
|
+
# under the key 'location' and the new Response is returned.
|
|
54
|
+
def follow(redirect_request_options = {})
|
|
55
|
+
self
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def connection_closed?
|
|
59
|
+
self[StandardHeaders::Connection].downcase == StandardTokens::Close.downcase
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Copyright 2009 Sidu Ponnappa
|
|
2
|
+
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
7
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
|
+
|
|
10
|
+
module Wrest::Native
|
|
11
|
+
# This class is a wrapper for a keep-alive HTTP connection. It simply passes the
|
|
12
|
+
# same connection instance as an option to all Wrest::Http::Request instances created using it.
|
|
13
|
+
#
|
|
14
|
+
# If at any point the server closes an existing connection during a Session by returning a
|
|
15
|
+
# Connection: Close header the current connection is destroyed and a fresh one created for the next
|
|
16
|
+
# request.
|
|
17
|
+
#
|
|
18
|
+
# The Session constructor can accept either a String URI or a Wrest::Uri as a parameter. If you
|
|
19
|
+
# need HTTP authentication, you should use a Wrest::Uri.
|
|
20
|
+
class Session
|
|
21
|
+
attr_reader :uri
|
|
22
|
+
def initialize(uri)
|
|
23
|
+
@uri = uri.is_a?(String) ? uri.to_uri : uri
|
|
24
|
+
@default_headers = { StandardHeaders::Connection => StandardTokens::KeepAlive }
|
|
25
|
+
|
|
26
|
+
yield(self) if block_given?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def connection
|
|
30
|
+
@connection ||= @uri.create_connection
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def get(path = '', parameters = {}, headers = {})
|
|
34
|
+
maybe_destroy_connection @uri[path, {:connection => self.connection}].get(parameters, headers.merge(@default_headers))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def post(path = '', body = '', headers = {}, params = {})
|
|
38
|
+
maybe_destroy_connection @uri[path, {:connection => self.connection}].post(body, headers.merge(@default_headers), params)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def put(path = '', body = '', headers = {}, params = {})
|
|
42
|
+
maybe_destroy_connection @uri[path, {:connection => self.connection}].put(body, headers.merge(@default_headers), params)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def delete(path = '', parameters = {}, headers = {})
|
|
46
|
+
maybe_destroy_connection @uri[path, {:connection => self.connection}].delete(parameters, headers.merge(@default_headers))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def maybe_destroy_connection(response)
|
|
50
|
+
if response.connection_closed?
|
|
51
|
+
Wrest.logger.warn "Connection #{@connection.hash} has been closed by the server"
|
|
52
|
+
@connection = nil
|
|
53
|
+
end
|
|
54
|
+
response
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/wrest/curl.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright 2009 Sidu Ponnappa
|
|
2
|
+
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
7
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
gem 'patron', '>=0.4.4'
|
|
12
|
+
rescue Gem::LoadError => e
|
|
13
|
+
Wrest.logger.debug "Patron >= 0.4.4 not found. Patron is necessary to use libcurl. To install Patron run `sudo gem install patron` (patron is not available on JRuby, but you shouldn't need it anyway)."
|
|
14
|
+
raise e
|
|
15
|
+
end
|
|
16
|
+
require 'patron'
|
|
17
|
+
|
|
18
|
+
module Wrest #:nodoc:
|
|
19
|
+
|
|
20
|
+
# Contains all HTTP protocol related classes such as
|
|
21
|
+
# Get, Post, Request, Response etc. and uses Curl for
|
|
22
|
+
# better performance, but works only on CRuby and only on a *nix OS.
|
|
23
|
+
#
|
|
24
|
+
# This functionality is under development and the Wrest API
|
|
25
|
+
# may not cover using it fully.
|
|
26
|
+
#
|
|
27
|
+
# Note:
|
|
28
|
+
# * The Curl based APIs do *not* support the HTTP 'options' verb.
|
|
29
|
+
# * Since auto-redirect is natively supported by Curl, auto-redirect may
|
|
30
|
+
# behave differently from the native implementation for now.
|
|
31
|
+
module Curl
|
|
32
|
+
include Wrest::HttpShared
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
module Patron
|
|
37
|
+
class Session
|
|
38
|
+
public :handle_request
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
require "#{Wrest::Root}/wrest/curl/response"
|
|
43
|
+
require "#{Wrest::Root}/wrest/curl/request"
|
|
44
|
+
require "#{Wrest::Root}/wrest/curl/get"
|
|
45
|
+
require "#{Wrest::Root}/wrest/curl/put"
|
|
46
|
+
require "#{Wrest::Root}/wrest/curl/post"
|
|
47
|
+
require "#{Wrest::Root}/wrest/curl/delete"
|
|
48
|
+
require "#{Wrest::Root}/wrest/curl/options"
|
|
49
|
+
# require "#{Wrest::Root}/wrest/curl/session"
|
data/lib/wrest/exceptions.rb
CHANGED
|
@@ -9,10 +9,25 @@ module Wrest
|
|
|
9
9
|
# is requested. See Translators.
|
|
10
10
|
class UnsupportedContentType < StandardError
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
# Raised when a request auto redirects more times than are allowed
|
|
14
14
|
# by its follow_redirects_limit. See Wrest::Http::Redirection.
|
|
15
15
|
class AutoRedirectLimitExceeded < StandardError
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
# Raised when a request is made when either RAILS_ENV or
|
|
19
|
+
# ENV['RAILS_ENV'] is set to 'test', which is the case when
|
|
20
|
+
# running tests/specs in a Rails application.
|
|
21
|
+
#
|
|
22
|
+
# See wrest/test/request_patches.
|
|
23
|
+
class RealRequestMadeInTestEnvironmet < StandardError
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Raised when a request times out
|
|
27
|
+
class Timeout < StandardError
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class UnsupportedHttpVerb < StandardError
|
|
31
|
+
end
|
|
17
32
|
end
|
|
18
33
|
end
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Header module.
|
|
3
|
+
#
|
|
4
|
+
# Provides access to headers in the mixed-into class as a hash-like
|
|
5
|
+
# object, except with case-insensitive keys. Also provides
|
|
6
|
+
# methods for accessing commonly-used header values in a more
|
|
7
|
+
# convenient format.
|
|
8
|
+
#
|
|
9
|
+
# Sourced from Net::HTTP and then modified to be generic
|
|
10
|
+
module Wrest
|
|
11
|
+
module HttpShared
|
|
12
|
+
module Headers
|
|
13
|
+
|
|
14
|
+
def initialize_http_header
|
|
15
|
+
headers.each do |key, value|
|
|
16
|
+
headers[key.downcase] = value.strip
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns the header field corresponding to the case-insensitive key.
|
|
21
|
+
# For example, a key of "Content-Type" might return "text/html"
|
|
22
|
+
def [](key)
|
|
23
|
+
headers[key] || headers[key.downcase]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# # Sets the header field corresponding to the case-insensitive key.
|
|
27
|
+
# def []=(key, val)
|
|
28
|
+
# unless val
|
|
29
|
+
# headers.delete key.downcase
|
|
30
|
+
# return val
|
|
31
|
+
# end
|
|
32
|
+
# headers[key.downcase] = [val]
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
# # [Ruby 1.8.3]
|
|
36
|
+
# # Adds header field instead of replace.
|
|
37
|
+
# # Second argument +val+ must be a String.
|
|
38
|
+
# # See also #[]=, #[] and #get_fields.
|
|
39
|
+
# #
|
|
40
|
+
# # request.add_field 'X-My-Header', 'a'
|
|
41
|
+
# # p request['X-My-Header'] #=> "a"
|
|
42
|
+
# # p request.get_fields('X-My-Header') #=> ["a"]
|
|
43
|
+
# # request.add_field 'X-My-Header', 'b'
|
|
44
|
+
# # p request['X-My-Header'] #=> "a, b"
|
|
45
|
+
# # p request.get_fields('X-My-Header') #=> ["a", "b"]
|
|
46
|
+
# # request.add_field 'X-My-Header', 'c'
|
|
47
|
+
# # p request['X-My-Header'] #=> "a, b, c"
|
|
48
|
+
# # p request.get_fields('X-My-Header') #=> ["a", "b", "c"]
|
|
49
|
+
# #
|
|
50
|
+
# def add_field(key, val)
|
|
51
|
+
# if headers.key?(key.downcase)
|
|
52
|
+
# headers[key.downcase].push val
|
|
53
|
+
# else
|
|
54
|
+
# headers[key.downcase] = [val]
|
|
55
|
+
# end
|
|
56
|
+
# end
|
|
57
|
+
#
|
|
58
|
+
# # [Ruby 1.8.3]
|
|
59
|
+
# # Returns an array of header field strings corresponding to the
|
|
60
|
+
# # case-insensitive +key+. This method allows you to get duplicated
|
|
61
|
+
# # header fields without any processing. See also #[].
|
|
62
|
+
# #
|
|
63
|
+
# # p response.get_fields('Set-Cookie')
|
|
64
|
+
# # #=> ["session=al98axx; expires=Fri, 31-Dec-1999 23:58:23",
|
|
65
|
+
# # "query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"]
|
|
66
|
+
# # p response['Set-Cookie']
|
|
67
|
+
# # #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"
|
|
68
|
+
# #
|
|
69
|
+
# def get_fields(key)
|
|
70
|
+
# return nil unless headers[key.downcase]
|
|
71
|
+
# headers[key.downcase].dup
|
|
72
|
+
# end
|
|
73
|
+
#
|
|
74
|
+
# # Returns the header field corresponding to the case-insensitive key.
|
|
75
|
+
# # Returns the default value +args+, or the result of the block, or nil,
|
|
76
|
+
# # if there's no header field named key. See Hash#fetch
|
|
77
|
+
# def fetch(key, *args, &block) #:yield: +key+
|
|
78
|
+
# a = headers.fetch(key.downcase, *args, &block)
|
|
79
|
+
# a.join(', ')
|
|
80
|
+
# end
|
|
81
|
+
#
|
|
82
|
+
# # Iterates for each header names and values.
|
|
83
|
+
# def each_header #:yield: +key+, +value+
|
|
84
|
+
# headers.each do |k,va|
|
|
85
|
+
# yield k, va.join(', ')
|
|
86
|
+
# end
|
|
87
|
+
# end
|
|
88
|
+
#
|
|
89
|
+
# alias each each_header
|
|
90
|
+
#
|
|
91
|
+
# # Iterates for each header names.
|
|
92
|
+
# def each_name(&block) #:yield: +key+
|
|
93
|
+
# headers.each_key(&block)
|
|
94
|
+
# end
|
|
95
|
+
#
|
|
96
|
+
# alias each_key each_name
|
|
97
|
+
#
|
|
98
|
+
# # Iterates for each capitalized header names.
|
|
99
|
+
# def each_capitalized_name(&block) #:yield: +key+
|
|
100
|
+
# headers.each_key do |k|
|
|
101
|
+
# yield capitalize(k)
|
|
102
|
+
# end
|
|
103
|
+
# end
|
|
104
|
+
#
|
|
105
|
+
# # Iterates for each header values.
|
|
106
|
+
# def each_value #:yield: +value+
|
|
107
|
+
# headers.each_value do |va|
|
|
108
|
+
# yield va.join(', ')
|
|
109
|
+
# end
|
|
110
|
+
# end
|
|
111
|
+
#
|
|
112
|
+
# # Removes a header field.
|
|
113
|
+
# def delete(key)
|
|
114
|
+
# headers.delete(key.downcase)
|
|
115
|
+
# end
|
|
116
|
+
#
|
|
117
|
+
# # true if +key+ header exists.
|
|
118
|
+
# def key?(key)
|
|
119
|
+
# headers.key?(key.downcase)
|
|
120
|
+
# end
|
|
121
|
+
#
|
|
122
|
+
# # Returns a Hash consist of header names and values.
|
|
123
|
+
# def to_hash
|
|
124
|
+
# headers.dup
|
|
125
|
+
# end
|
|
126
|
+
#
|
|
127
|
+
# # As for #each_header, except the keys are provided in capitalized form.
|
|
128
|
+
# def each_capitalized
|
|
129
|
+
# headers.each do |k,v|
|
|
130
|
+
# yield capitalize(k), v.join(', ')
|
|
131
|
+
# end
|
|
132
|
+
# end
|
|
133
|
+
#
|
|
134
|
+
# alias canonical_each each_capitalized
|
|
135
|
+
#
|
|
136
|
+
# def capitalize(name)
|
|
137
|
+
# name.split(/-/).map {|s| s.capitalize }.join('-')
|
|
138
|
+
# end
|
|
139
|
+
# private :capitalize
|
|
140
|
+
#
|
|
141
|
+
# # Returns an Array of Range objects which represents Range: header field,
|
|
142
|
+
# # or +nil+ if there is no such header.
|
|
143
|
+
# def range
|
|
144
|
+
# return nil unless headers['range']
|
|
145
|
+
# self['Range'].split(/,/).map {|spec|
|
|
146
|
+
# m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match(spec) or
|
|
147
|
+
# raise HTTPHeaderSyntaxError, "wrong Range: #{spec}"
|
|
148
|
+
# d1 = m[1].to_i
|
|
149
|
+
# d2 = m[2].to_i
|
|
150
|
+
# if m[1] and m[2] then d1..d2
|
|
151
|
+
# elsif m[1] then d1..-1
|
|
152
|
+
# elsif m[2] then -d2..-1
|
|
153
|
+
# else
|
|
154
|
+
# raise HTTPHeaderSyntaxError, 'range is not specified'
|
|
155
|
+
# end
|
|
156
|
+
# }
|
|
157
|
+
# end
|
|
158
|
+
#
|
|
159
|
+
# # Set Range: header from Range (arg r) or beginning index and
|
|
160
|
+
# # length from it (arg idx&len).
|
|
161
|
+
# #
|
|
162
|
+
# # req.range = (0..1023)
|
|
163
|
+
# # req.set_range 0, 1023
|
|
164
|
+
# #
|
|
165
|
+
# def set_range(r, e = nil)
|
|
166
|
+
# unless r
|
|
167
|
+
# headers.delete 'range'
|
|
168
|
+
# return r
|
|
169
|
+
# end
|
|
170
|
+
# r = (r...r+e) if e
|
|
171
|
+
# case r
|
|
172
|
+
# when Numeric
|
|
173
|
+
# n = r.to_i
|
|
174
|
+
# rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
|
|
175
|
+
# when Range
|
|
176
|
+
# first = r.first
|
|
177
|
+
# last = r.last
|
|
178
|
+
# last -= 1 if r.exclude_end?
|
|
179
|
+
# if last == -1
|
|
180
|
+
# rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
|
|
181
|
+
# else
|
|
182
|
+
# raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
|
|
183
|
+
# raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
|
|
184
|
+
# raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
|
|
185
|
+
# rangestr = "#{first}-#{last}"
|
|
186
|
+
# end
|
|
187
|
+
# else
|
|
188
|
+
# raise TypeError, 'Range/Integer is required'
|
|
189
|
+
# end
|
|
190
|
+
# headers['range'] = ["bytes=#{rangestr}"]
|
|
191
|
+
# r
|
|
192
|
+
# end
|
|
193
|
+
#
|
|
194
|
+
# alias range= set_range
|
|
195
|
+
#
|
|
196
|
+
# # Returns an Integer object which represents the Content-Length: header field
|
|
197
|
+
# # or +nil+ if that field is not provided.
|
|
198
|
+
# def content_length
|
|
199
|
+
# return nil unless key?('Content-Length')
|
|
200
|
+
# len = self['Content-Length'].slice(/\d+/) or
|
|
201
|
+
# raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
|
|
202
|
+
# len.to_i
|
|
203
|
+
# end
|
|
204
|
+
#
|
|
205
|
+
# def content_length=(len)
|
|
206
|
+
# unless len
|
|
207
|
+
# headers.delete 'content-length'
|
|
208
|
+
# return nil
|
|
209
|
+
# end
|
|
210
|
+
# headers['content-length'] = [len.to_i.to_s]
|
|
211
|
+
# end
|
|
212
|
+
#
|
|
213
|
+
# # Returns "true" if the "transfer-encoding" header is present and
|
|
214
|
+
# # set to "chunked". This is an HTTP/1.1 feature, allowing the
|
|
215
|
+
# # the content to be sent in "chunks" without at the outset
|
|
216
|
+
# # stating the entire content length.
|
|
217
|
+
# def chunked?
|
|
218
|
+
# return false unless headers['transfer-encoding']
|
|
219
|
+
# field = self['Transfer-Encoding']
|
|
220
|
+
# (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
|
|
221
|
+
# end
|
|
222
|
+
#
|
|
223
|
+
# # Returns a Range object which represents Content-Range: header field.
|
|
224
|
+
# # This indicates, for a partial entity body, where this fragment
|
|
225
|
+
# # fits inside the full entity body, as range of byte offsets.
|
|
226
|
+
# def content_range
|
|
227
|
+
# return nil unless headers['content-range']
|
|
228
|
+
# m = %r<bytes\s+(\d+)-(\d+)/(\d+|\*)>i.match(self['Content-Range']) or
|
|
229
|
+
# raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
|
|
230
|
+
# m[1].to_i .. m[2].to_i + 1
|
|
231
|
+
# end
|
|
232
|
+
#
|
|
233
|
+
# # The length of the range represented in Content-Range: header.
|
|
234
|
+
# def range_length
|
|
235
|
+
# r = content_range() or return nil
|
|
236
|
+
# r.end - r.begin
|
|
237
|
+
# end
|
|
238
|
+
#
|
|
239
|
+
# # Returns a content type string such as "text/html".
|
|
240
|
+
# # This method returns nil if Content-Type: header field does not exist.
|
|
241
|
+
# def content_type
|
|
242
|
+
# return nil unless main_type()
|
|
243
|
+
# if sub_type()
|
|
244
|
+
# "#{main_type()}/#{sub_type()}"
|
|
245
|
+
# else
|
|
246
|
+
# main_type()
|
|
247
|
+
# end
|
|
248
|
+
# end
|
|
249
|
+
#
|
|
250
|
+
# # Returns a content type string such as "text".
|
|
251
|
+
# # This method returns nil if Content-Type: header field does not exist.
|
|
252
|
+
# def main_type
|
|
253
|
+
# return nil unless headers['content-type']
|
|
254
|
+
# self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
|
|
255
|
+
# end
|
|
256
|
+
#
|
|
257
|
+
# # Returns a content type string such as "html".
|
|
258
|
+
# # This method returns nil if Content-Type: header field does not exist
|
|
259
|
+
# # or sub-type is not given (e.g. "Content-Type: text").
|
|
260
|
+
# def sub_type
|
|
261
|
+
# return nil unless headers['content-type']
|
|
262
|
+
# main, sub = *self['Content-Type'].split(';').first.to_s.split('/')
|
|
263
|
+
# return nil unless sub
|
|
264
|
+
# sub.strip
|
|
265
|
+
# end
|
|
266
|
+
#
|
|
267
|
+
# # Returns content type parameters as a Hash as like
|
|
268
|
+
# # {"charset" => "iso-2022-jp"}.
|
|
269
|
+
# def type_params
|
|
270
|
+
# result = {}
|
|
271
|
+
# list = self['Content-Type'].to_s.split(';')
|
|
272
|
+
# list.shift
|
|
273
|
+
# list.each do |param|
|
|
274
|
+
# k, v = *param.split('=', 2)
|
|
275
|
+
# result[k.strip] = v.strip
|
|
276
|
+
# end
|
|
277
|
+
# result
|
|
278
|
+
# end
|
|
279
|
+
#
|
|
280
|
+
# # Set Content-Type: header field by +type+ and +params+.
|
|
281
|
+
# # +type+ must be a String, +params+ must be a Hash.
|
|
282
|
+
# def set_content_type(type, params = {})
|
|
283
|
+
# headers['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
|
|
284
|
+
# end
|
|
285
|
+
#
|
|
286
|
+
# alias content_type= set_content_type
|
|
287
|
+
#
|
|
288
|
+
# # Set header fields and a body from HTML form data.
|
|
289
|
+
# # +params+ should be a Hash containing HTML form data.
|
|
290
|
+
# # Optional argument +sep+ means data record separator.
|
|
291
|
+
# #
|
|
292
|
+
# # This method also set Content-Type: header field to
|
|
293
|
+
# # application/x-www-form-urlencoded.
|
|
294
|
+
# #
|
|
295
|
+
# # Example:
|
|
296
|
+
# # http.form_data = {"q" => "ruby", "lang" => "en"}
|
|
297
|
+
# # http.form_data = {"q" => ["ruby", "perl"], "lang" => "en"}
|
|
298
|
+
# # http.set_form_data({"q" => "ruby", "lang" => "en"}, ';')
|
|
299
|
+
# #
|
|
300
|
+
# def set_form_data(params, sep = '&')
|
|
301
|
+
# self.body = params.map {|k, v| encode_kvpair(k, v) }.flatten.join(sep)
|
|
302
|
+
# self.content_type = 'application/x-www-form-urlencoded'
|
|
303
|
+
# end
|
|
304
|
+
#
|
|
305
|
+
# alias form_data= set_form_data
|
|
306
|
+
#
|
|
307
|
+
# def encode_kvpair(k, vs)
|
|
308
|
+
# Array(vs).map {|v| "#{urlencode(k)}=#{urlencode(v.to_s)}" }
|
|
309
|
+
# end
|
|
310
|
+
# private :encode_kvpair
|
|
311
|
+
#
|
|
312
|
+
# def urlencode(str)
|
|
313
|
+
# str.dup.force_encoding('ASCII-8BIT').gsub(/[^a-zA-Z0-9_\.\-]/){'%%%02x' % $&.ord}
|
|
314
|
+
# end
|
|
315
|
+
# private :urlencode
|
|
316
|
+
#
|
|
317
|
+
# # Set the Authorization: header for "Basic" authorization.
|
|
318
|
+
# def basic_auth(account, password)
|
|
319
|
+
# headers['authorization'] = [basic_encode(account, password)]
|
|
320
|
+
# end
|
|
321
|
+
#
|
|
322
|
+
# # Set Proxy-Authorization: header for "Basic" authorization.
|
|
323
|
+
# def proxy_basic_auth(account, password)
|
|
324
|
+
# headers['proxy-authorization'] = [basic_encode(account, password)]
|
|
325
|
+
# end
|
|
326
|
+
#
|
|
327
|
+
# def basic_encode(account, password)
|
|
328
|
+
# 'Basic ' + ["#{account}:#{password}"].pack('m').delete("\r\n")
|
|
329
|
+
# end
|
|
330
|
+
# private :basic_encode
|
|
331
|
+
#
|
|
332
|
+
# def connection_close?
|
|
333
|
+
# tokens(headers['connection']).include?('close') or
|
|
334
|
+
# tokens(headers['proxy-connection']).include?('close')
|
|
335
|
+
# end
|
|
336
|
+
#
|
|
337
|
+
# def connection_keep_alive?
|
|
338
|
+
# tokens(headers['connection']).include?('keep-alive') or
|
|
339
|
+
# tokens(headers['proxy-connection']).include?('keep-alive')
|
|
340
|
+
# end
|
|
341
|
+
#
|
|
342
|
+
# def tokens(vals)
|
|
343
|
+
# return [] unless vals
|
|
344
|
+
# vals.map {|v| v.split(',') }.flatten\
|
|
345
|
+
# .reject {|str| str.strip.empty? }\
|
|
346
|
+
# .map {|tok| tok.strip.downcase }
|
|
347
|
+
# end
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright 2009 Sidu Ponnappa
|
|
2
|
+
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at Http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
7
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
|
+
|
|
10
|
+
module Wrest #:nodoc:
|
|
11
|
+
module HttpShared #:nodoc:
|
|
12
|
+
module StandardHeaders
|
|
13
|
+
Connection = 'connection'
|
|
14
|
+
ContentType = 'content-type'
|
|
15
|
+
ContentLength = 'content-length'
|
|
16
|
+
IfNoneMatch = 'if-none-match'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright 2009 Sidu Ponnappa
|
|
2
|
+
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at Http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
7
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
|
+
|
|
10
|
+
module Wrest #:nodoc:
|
|
11
|
+
module HttpShared #:nodoc:
|
|
12
|
+
module StandardTokens
|
|
13
|
+
Close = 'close'
|
|
14
|
+
KeepAlive = 'keep-alive'
|
|
15
|
+
FormEncoded = 'application/x-www-form-urlencoded'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|