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,24 @@
|
|
|
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 native://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
|
+
|
|
12
|
+
# Contains functionality the is independent of
|
|
13
|
+
# the underlying HTTP libs
|
|
14
|
+
module HttpShared
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
require "#{Wrest::Root}/wrest/http_shared/headers"
|
|
19
|
+
require "#{Wrest::Root}/wrest/http_shared/standard_headers"
|
|
20
|
+
require "#{Wrest::Root}/wrest/http_shared/standard_tokens"
|
|
21
|
+
|
|
22
|
+
# Set up a shorter convenience API for constants
|
|
23
|
+
Wrest::H = Wrest::HttpShared::StandardHeaders
|
|
24
|
+
Wrest::T = Wrest::HttpShared::StandardTokens
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
module ConnectionFactory
|
|
12
|
+
def create_connection(timeout = 60)
|
|
13
|
+
timeout ||= 60
|
|
14
|
+
connection = Net::HTTP.new(self.host, self.port)
|
|
15
|
+
connection.read_timeout = timeout
|
|
16
|
+
if self.https?
|
|
17
|
+
connection.use_ssl = true
|
|
18
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
19
|
+
end
|
|
20
|
+
connection
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
|
-
module Wrest::
|
|
10
|
+
module Wrest::Native
|
|
11
11
|
class Delete < Request
|
|
12
12
|
def initialize(wrest_uri, parameters = {}, headers = {}, options = {})
|
|
13
13
|
super(
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
|
-
module Wrest::
|
|
10
|
+
module Wrest::Native
|
|
11
11
|
class Get < Request
|
|
12
12
|
def initialize(wrest_uri, parameters = {}, headers = {}, options = {})
|
|
13
13
|
follow_redirects = options[:follow_redirects]
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
|
-
module Wrest::
|
|
10
|
+
module Wrest::Native
|
|
11
11
|
class Options < Request
|
|
12
12
|
def initialize(wrest_uri, options = {})
|
|
13
13
|
super(
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
|
-
module Wrest::
|
|
10
|
+
module Wrest::Native
|
|
11
11
|
class Post < Request
|
|
12
12
|
def initialize(wrest_uri, body = '', headers = {}, parameters = {}, options = {})
|
|
13
13
|
super(
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
|
-
module Wrest::
|
|
10
|
+
module Wrest::Native
|
|
11
11
|
class Put < Request
|
|
12
12
|
def initialize(wrest_uri, body = '', headers = {}, parameters = {}, options = {})
|
|
13
13
|
super(
|
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
10
|
module Wrest #:nodoc:
|
|
11
|
-
module
|
|
11
|
+
module Native #:nodoc:
|
|
12
12
|
# Constructed by Wrest::Response.new if the HTTP response code is 3xx
|
|
13
13
|
# (http://en.wikipedia.org/wiki/300_Multiple_Choices#3xx_Redirection)
|
|
14
|
+
#
|
|
15
|
+
# This class is necessary because Net::HTTP doesn't seem to support
|
|
16
|
+
# redirection natively.
|
|
14
17
|
class Redirection < Response
|
|
15
18
|
|
|
16
19
|
# A get is invoked on the url stored in the response headers
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
|
-
module Wrest::
|
|
10
|
+
module Wrest::Native
|
|
11
11
|
# This represents a HTTP request. Typically you will never need to instantiate
|
|
12
12
|
# one of these yourself - you can use one of the more conveient APIs via Wrest::Uri
|
|
13
13
|
# or Wrest::Http::Get etc. instead.
|
|
14
14
|
class Request
|
|
15
|
-
attr_reader :http_request, :uri, :body, :headers, :username, :password, :follow_redirects,
|
|
16
|
-
:follow_redirects_limit, :follow_redirects_count, :timeout
|
|
15
|
+
attr_reader :http_request, :uri, :body, :headers, :username, :password, :follow_redirects,
|
|
16
|
+
:follow_redirects_limit, :follow_redirects_count, :timeout, :connection, :parameters
|
|
17
17
|
# Valid tuples for the options are:
|
|
18
18
|
# :username => String, defaults to nil
|
|
19
19
|
# :password => String, defaults to nil
|
|
@@ -28,10 +28,13 @@ module Wrest::Http
|
|
|
28
28
|
# until the follow_redirects_limit is hit. You should never set
|
|
29
29
|
# this option yourself.
|
|
30
30
|
# :timeout => The period, in seconds, after which a Timeout::Error is raised
|
|
31
|
-
# in the event of a connection failing to open.
|
|
31
|
+
# in the event of a connection failing to open. Defaulted to 60 by Uri#create_connection.
|
|
32
|
+
# :connection => The HTTP Connection object to use. This is how a keep-alive connection can be
|
|
33
|
+
# used for multiple requests.
|
|
32
34
|
def initialize(wrest_uri, http_request_klass, parameters = {}, body = nil, headers = {}, options = {})
|
|
33
35
|
@uri = wrest_uri
|
|
34
36
|
@headers = headers.stringify_keys
|
|
37
|
+
@parameters = parameters
|
|
35
38
|
@http_request = http_request_klass.new(parameters.empty? ? wrest_uri.full_path : "#{wrest_uri.full_path}?#{parameters.to_query}", @headers)
|
|
36
39
|
@body = body
|
|
37
40
|
@options = options.clone
|
|
@@ -40,33 +43,42 @@ module Wrest::Http
|
|
|
40
43
|
@follow_redirects = (@options[:follow_redirects] ||= false)
|
|
41
44
|
@follow_redirects_count = (@options[:follow_redirects_count] ||= 0)
|
|
42
45
|
@follow_redirects_limit = (@options[:follow_redirects_limit] ||= 5)
|
|
43
|
-
@timeout =
|
|
46
|
+
@timeout = @options[:timeout]
|
|
47
|
+
@connection = @options[:connection]
|
|
44
48
|
end
|
|
45
49
|
|
|
46
|
-
# Makes a request and returns a Wrest::
|
|
50
|
+
# Makes a request and returns a Wrest::Native::Response.
|
|
47
51
|
# Data about the request is and logged to Wrest.logger
|
|
52
|
+
# The log entry contains the following information:
|
|
53
|
+
#
|
|
54
|
+
# --> indicates a request
|
|
55
|
+
# <-- indicates a response
|
|
56
|
+
#
|
|
57
|
+
# The type of request is mentioned in caps, followed by a hash
|
|
58
|
+
# uniquely uniquely identifying a particular request/response pair.
|
|
59
|
+
# In a multi-process or multi-threaded scenario, this can be used
|
|
60
|
+
# to identify request-response pairs.
|
|
61
|
+
#
|
|
62
|
+
# The request hash is followed by a connection hash; requests using the
|
|
63
|
+
# same connection (effectively a keep-alive connection) will have the
|
|
64
|
+
# same connection hash.
|
|
65
|
+
#
|
|
66
|
+
# This is followed by the response code, the payload size and the time taken.
|
|
48
67
|
def invoke
|
|
49
68
|
response = nil
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
http_connection = create_connection(timeout)
|
|
69
|
+
|
|
70
|
+
@connection ||= @uri.create_connection(timeout)
|
|
53
71
|
http_request.basic_auth username, password
|
|
54
72
|
|
|
73
|
+
prefix = "#{http_request.method} #{http_request.hash} #{@connection.hash}"
|
|
74
|
+
|
|
55
75
|
Wrest.logger.debug "--> (#{prefix}) #{@uri.protocol}://#{@uri.host}:#{@uri.port}#{@http_request.path}"
|
|
56
|
-
time = Benchmark.realtime { response = Wrest::
|
|
76
|
+
time = Benchmark.realtime { response = Wrest::Native::Response.new( @connection.request(@http_request, @body) ) }
|
|
57
77
|
Wrest.logger.debug "<-- (#{prefix}) %d %s (%d bytes %.2fs)" % [response.code, response.message, response.body ? response.body.length : 0, time]
|
|
58
78
|
|
|
59
79
|
@follow_redirects ? response.follow(@options) : response
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def create_connection(timeout)
|
|
63
|
-
connection = Net::HTTP.new(@uri.host, @uri.port)
|
|
64
|
-
connection.read_timeout = timeout
|
|
65
|
-
if @uri.https?
|
|
66
|
-
connection.use_ssl = true
|
|
67
|
-
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
68
|
-
end
|
|
69
|
-
connection
|
|
80
|
+
rescue Timeout::Error => e
|
|
81
|
+
raise Wrest::Exceptions::Timeout.new(e)
|
|
70
82
|
end
|
|
71
83
|
end
|
|
72
84
|
end
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
# See the License for the specific language governing permissions and limitations under the License.
|
|
9
9
|
|
|
10
10
|
module Wrest #:nodoc:
|
|
11
|
-
module
|
|
11
|
+
module Native #:nodoc:
|
|
12
12
|
# Decorates a response providing support for deserialisation.
|
|
13
13
|
#
|
|
14
|
-
# The following methods are also available (unlisted by rdoc because they're forwarded):
|
|
14
|
+
# The following methods are also available (unlisted by rdoc because they're forwarded to Net::HTTP::Response):
|
|
15
15
|
#
|
|
16
16
|
# <tt>:@Http_response, :code, :message, :body, :Http_version,
|
|
17
17
|
# :[], :content_length, :content_type, :each_header, :each_name, :each_value, :fetch,
|
|
@@ -19,15 +19,19 @@ module Wrest #:nodoc:
|
|
|
19
19
|
#
|
|
20
20
|
# They behave exactly like their Net::HttpResponse equivalents.
|
|
21
21
|
class Response
|
|
22
|
+
attr_reader :http_response
|
|
23
|
+
|
|
22
24
|
extend Forwardable
|
|
23
25
|
def_delegators :@http_response, :code, :message, :body, :Http_version,
|
|
24
26
|
:[], :content_length, :content_type, :each_header, :each_name, :each_value, :fetch,
|
|
25
27
|
:get_fields, :key?, :type_params
|
|
26
28
|
|
|
27
29
|
# We're overriding :new to act as a factory so
|
|
28
|
-
# we can build the appropriate Response instance
|
|
30
|
+
# we can build the appropriate Response instance based
|
|
31
|
+
# on th response code.
|
|
29
32
|
def self.new(http_response)
|
|
30
|
-
|
|
33
|
+
code = http_response.code.to_i
|
|
34
|
+
instance = ((300..303).include?(code) || (305..399).include?(code) ? Wrest::Native::Redirection : self).allocate
|
|
31
35
|
instance.send :initialize, http_response
|
|
32
36
|
instance
|
|
33
37
|
end
|
|
@@ -56,6 +60,10 @@ module Wrest #:nodoc:
|
|
|
56
60
|
def follow(redirect_request_options = {})
|
|
57
61
|
self
|
|
58
62
|
end
|
|
63
|
+
|
|
64
|
+
def connection_closed?
|
|
65
|
+
self[Native::StandardHeaders::Connection].downcase == Native::StandardTokens::Close.downcase
|
|
66
|
+
end
|
|
59
67
|
end
|
|
60
68
|
end
|
|
61
69
|
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 = { Wrest::Native::StandardHeaders::Connection => Wrest::Native::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/native.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
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 native://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
|
+
|
|
12
|
+
# Contains all native protocol related classes such as
|
|
13
|
+
# Get, Post, Request, Response etc. and uses the native
|
|
14
|
+
# Ruby Net::native libraries.
|
|
15
|
+
module Native
|
|
16
|
+
include Wrest::HttpShared
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
require "#{Wrest::Root}/wrest/native/connection_factory"
|
|
21
|
+
require "#{Wrest::Root}/wrest/native/response"
|
|
22
|
+
require "#{Wrest::Root}/wrest/native/redirection"
|
|
23
|
+
require "#{Wrest::Root}/wrest/native/request"
|
|
24
|
+
require "#{Wrest::Root}/wrest/native/get"
|
|
25
|
+
require "#{Wrest::Root}/wrest/native/put"
|
|
26
|
+
require "#{Wrest::Root}/wrest/native/post"
|
|
27
|
+
require "#{Wrest::Root}/wrest/native/delete"
|
|
28
|
+
require "#{Wrest::Root}/wrest/native/options"
|
|
29
|
+
require "#{Wrest::Root}/wrest/native/session"
|
|
30
|
+
|
|
31
|
+
# default to using Native libs
|
|
32
|
+
Wrest::Http = Wrest::Native
|
data/lib/wrest/resource/base.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Wrest::Resource #:nodoc:
|
|
|
11
11
|
# Resource::Base is the equivalent of ActiveResource::Base.
|
|
12
12
|
# It is a REST client targetted at Rails REST apps.
|
|
13
13
|
class Base
|
|
14
|
-
include Wrest::Components::
|
|
14
|
+
include Wrest::Components::Container
|
|
15
15
|
|
|
16
16
|
always_has :id
|
|
17
17
|
typecast :id => as_integer
|
data/lib/wrest/resource.rb
CHANGED
data/lib/wrest/test.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "#{Wrest::Root}/wrest/test/request_patches"
|
data/lib/wrest/uri.rb
CHANGED
|
@@ -22,14 +22,13 @@ module Wrest #:nodoc:
|
|
|
22
22
|
#
|
|
23
23
|
# You can find examples that use real APIs (like delicious) under the wrest/examples directory.
|
|
24
24
|
class Uri
|
|
25
|
-
attr_reader :uri, :username, :password
|
|
26
|
-
|
|
25
|
+
attr_reader :uri, :username, :password, :uri_string
|
|
26
|
+
|
|
27
27
|
# See Wrest::Http::Request for the available options and their default values.
|
|
28
28
|
def initialize(uri_string, options = {})
|
|
29
29
|
@options = options
|
|
30
30
|
@uri_string = uri_string.clone
|
|
31
31
|
@uri = URI.parse(uri_string)
|
|
32
|
-
@options = options
|
|
33
32
|
@username = (@options[:username] ||= @uri.user)
|
|
34
33
|
@password = (@options[:password] ||= @uri.password)
|
|
35
34
|
end
|
|
@@ -53,6 +52,12 @@ module Wrest #:nodoc:
|
|
|
53
52
|
Uri.new(@uri_string+path, options || @options)
|
|
54
53
|
end
|
|
55
54
|
|
|
55
|
+
# Clones a Uri, building a new instance with exactly the same uri string.
|
|
56
|
+
# You can however change the Uri options or add new ones.
|
|
57
|
+
def clone(opts = {})
|
|
58
|
+
Uri.new(@uri_string, @options.merge(opts))
|
|
59
|
+
end
|
|
60
|
+
|
|
56
61
|
def eql?(other)
|
|
57
62
|
self == other
|
|
58
63
|
end
|
|
@@ -66,6 +71,13 @@ module Wrest #:nodoc:
|
|
|
66
71
|
@uri.hash + @username.hash + @password.hash + 20090423
|
|
67
72
|
end
|
|
68
73
|
|
|
74
|
+
# This produces exactly the same string as the Wrest::Uri was constructed with.
|
|
75
|
+
# If the orignial URI contained a HTTP username and password, that too will
|
|
76
|
+
# show up, so be careful if using this for logging.
|
|
77
|
+
def to_s
|
|
78
|
+
uri_string
|
|
79
|
+
end
|
|
80
|
+
|
|
69
81
|
# Make a GET request to this URI. This is a convenience API
|
|
70
82
|
# that creates a Wrest::Http::Get, executes it and returns a Wrest::Http::Response.
|
|
71
83
|
#
|
|
@@ -84,11 +96,25 @@ module Wrest #:nodoc:
|
|
|
84
96
|
|
|
85
97
|
# Makes a POST request to this URI. This is a convenience API
|
|
86
98
|
# that creates a Wrest::Http::Post, executes it and returns a Wrest::Http::Response.
|
|
99
|
+
# Note that sending an empty body will blow up if you're using libcurl.
|
|
87
100
|
#
|
|
88
101
|
# Remember to escape all parameter strings if necessary, using URI.escape
|
|
89
102
|
def post(body = '', headers = {}, parameters = {})
|
|
90
103
|
Http::Post.new(self, body.to_s, headers, parameters, @options).invoke
|
|
91
104
|
end
|
|
105
|
+
|
|
106
|
+
# Makes a POST request to this URI. This is a convenience API
|
|
107
|
+
# that mimics a form being posted; some allegly RESTful APIs like FCBK
|
|
108
|
+
# require this to be used.
|
|
109
|
+
#
|
|
110
|
+
# Form encoding involves munging the parameters into a string and placing them
|
|
111
|
+
# in the body, as well as setting the Content-Type header to
|
|
112
|
+
# application/x-www-form-urlencoded
|
|
113
|
+
def post_form(parameters = {}, headers = {})
|
|
114
|
+
headers = headers.merge(Wrest::H::ContentType => Wrest::T::FormEncoded)
|
|
115
|
+
body = parameters.to_query
|
|
116
|
+
Http::Post.new(self, body, headers, {}, @options).invoke
|
|
117
|
+
end
|
|
92
118
|
|
|
93
119
|
# Makes a DELETE request to this URI. This is a convenience API
|
|
94
120
|
# that creates a Wrest::Http::Delete, executes it and returns a Wrest::Http::Response.
|
|
@@ -128,5 +154,7 @@ module Wrest #:nodoc:
|
|
|
128
154
|
def port
|
|
129
155
|
uri.port
|
|
130
156
|
end
|
|
157
|
+
|
|
158
|
+
include Http::ConnectionFactory
|
|
131
159
|
end
|
|
132
160
|
end
|
data/lib/wrest/version.rb
CHANGED
data/lib/wrest.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Copyright 2009 Sidu Ponnappa
|
|
2
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
-
# you may not use this file except in compliance with the License.
|
|
4
|
-
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
-
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
6
|
-
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
7
|
-
# See the License for the specific language governing permissions and limitations under the License.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
6
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
7
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
|
8
8
|
|
|
9
9
|
require 'rubygems'
|
|
10
|
-
gem 'activesupport', '>= 2.3.
|
|
10
|
+
gem 'activesupport', '>= 2.3.5'
|
|
11
11
|
|
|
12
12
|
require 'net/http'
|
|
13
13
|
require 'net/https'
|
|
@@ -19,16 +19,25 @@ require 'logger'
|
|
|
19
19
|
require 'benchmark'
|
|
20
20
|
require 'active_support'
|
|
21
21
|
|
|
22
|
-
WREST_ROOT = File.dirname(__FILE__)
|
|
23
22
|
|
|
24
23
|
module Wrest #:nodoc:
|
|
24
|
+
Root = File.dirname(__FILE__)
|
|
25
25
|
def self.logger=(logger)
|
|
26
26
|
@logger = logger
|
|
27
27
|
end
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
def self.logger
|
|
30
30
|
@logger
|
|
31
31
|
end
|
|
32
|
+
|
|
33
|
+
def self.use_native
|
|
34
|
+
silence_warnings{ Wrest.const_set('Http', Wrest::Native) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.use_curl
|
|
38
|
+
require "#{Wrest::Root}/wrest/curl"
|
|
39
|
+
silence_warnings{ Wrest.const_set('Http', Wrest::Curl) }
|
|
40
|
+
end
|
|
32
41
|
end
|
|
33
42
|
|
|
34
43
|
Wrest.logger = ActiveSupport::BufferedLogger.new(STDOUT)
|
|
@@ -38,13 +47,40 @@ begin
|
|
|
38
47
|
gem 'libxml-ruby', '>= 1.1.3'
|
|
39
48
|
ActiveSupport::XmlMini.backend='LibXML'
|
|
40
49
|
rescue Gem::LoadError
|
|
41
|
-
Wrest.logger.
|
|
50
|
+
Wrest.logger.debug "Warning: LibXML >= 1.1.3 not found, attempting to use Nokogiri. To install LibXML run `(sudo) gem install libxml-ruby` (libxml-ruby is not available on JRuby)"
|
|
51
|
+
begin
|
|
52
|
+
gem 'nokogiri', '>= 1.3.3'
|
|
53
|
+
ActiveSupport::XmlMini.backend='Nokogiri'
|
|
54
|
+
rescue Gem::LoadError
|
|
55
|
+
Wrest.logger.debug "Warning: Nokogiri >= 1.3.3 not found, falling back to #{ActiveSupport::XmlMini.backend} (which is probably significantly slower). To install Nokogiri run `(sudo) (jruby -S) gem install nokogiri`"
|
|
56
|
+
if RUBY_PLATFORM =~ /java/
|
|
57
|
+
begin
|
|
58
|
+
gem 'jrexml', '>= 0.5.3'
|
|
59
|
+
require 'jrexml'
|
|
60
|
+
Wrest.logger.debug "Detected JRuby, JREXML loaded."
|
|
61
|
+
rescue Gem::LoadError
|
|
62
|
+
Wrest.logger.debug "Warning: Detected JRuby, but failed to load JREXML. JREXML offers *some* performance improvement when using REXML on JRuby. To install JREXML run `(sudo) jruby -S gem install jrexml`"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
42
66
|
end
|
|
43
67
|
|
|
44
|
-
|
|
68
|
+
Dir["#{File.expand_path(File.dirname(__FILE__))}/wrest/core_ext/*.rb"].each { |file| require file }
|
|
69
|
+
|
|
70
|
+
# Load Wrest Core
|
|
71
|
+
require "#{Wrest::Root}/wrest/http_shared"
|
|
72
|
+
require "#{Wrest::Root}/wrest/native"
|
|
73
|
+
|
|
74
|
+
# Load Wrest Wrappers
|
|
75
|
+
require "#{Wrest::Root}/wrest/uri"
|
|
76
|
+
require "#{Wrest::Root}/wrest/uri_template"
|
|
77
|
+
require "#{Wrest::Root}/wrest/version"
|
|
78
|
+
require "#{Wrest::Root}/wrest/exceptions"
|
|
79
|
+
require "#{Wrest::Root}/wrest/components"
|
|
80
|
+
|
|
81
|
+
# Load Wrest::Resource
|
|
82
|
+
require "#{Wrest::Root}/wrest/resource"
|
|
45
83
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
}
|
|
84
|
+
# if (ENV['RAILS_ENV'] == 'test' || (Kernel.const_defined?(:RAILS_ENV) && (RAILS_ENV == 'test')))
|
|
85
|
+
# require "#{Wrest::Root}/wrest/test"
|
|
86
|
+
# end
|
data/spec/unit/spec_helper.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../../lib/wrest")
|
|
2
|
+
require "#{Wrest::Root}/wrest/curl" unless RUBY_PLATFORM =~ /java/
|
|
2
3
|
require 'spec'
|
|
3
4
|
|
|
4
5
|
['/../custom_matchers/**/*.rb'].each{|directory|
|
|
@@ -7,7 +8,7 @@ require 'spec'
|
|
|
7
8
|
}
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
Wrest.logger = Logger.new(File.open("#{
|
|
11
|
+
Wrest.logger = Logger.new(File.open("#{Wrest::Root}/../log/test.log", 'a'))
|
|
11
12
|
|
|
12
13
|
def p(*args)
|
|
13
14
|
# super *(args << caller[0])
|
|
@@ -17,10 +18,18 @@ end
|
|
|
17
18
|
|
|
18
19
|
def puts(*args)
|
|
19
20
|
# super *(args << caller[0])
|
|
20
|
-
super *(args
|
|
21
|
+
super *(['<pre>'] + args + ['</pre>'])
|
|
21
22
|
# super *args
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
Spec::Runner.configure do |config|
|
|
25
26
|
config.include(CustomMatchers)
|
|
26
|
-
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def build_ok_response(body = '')
|
|
30
|
+
returning mock(Net::HTTPOK) do |response|
|
|
31
|
+
response.stub!(:code).and_return('200')
|
|
32
|
+
response.stub!(:message).and_return('OK')
|
|
33
|
+
response.stub!(:body).and_return(body)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/../../../spec_helper'
|
|
2
2
|
|
|
3
3
|
module Wrest::Components
|
|
4
|
-
describe
|
|
4
|
+
describe Container::AliasAccessors do
|
|
5
5
|
before :each do
|
|
6
6
|
@Demon = Class.new
|
|
7
7
|
@Demon.class_eval do
|
|
8
|
-
include Wrest::Components::
|
|
8
|
+
include Wrest::Components::Container
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/../../../spec_helper'
|
|
2
2
|
|
|
3
3
|
module Wrest::Components
|
|
4
|
-
describe
|
|
4
|
+
describe Container::Typecaster do
|
|
5
5
|
before :each do
|
|
6
6
|
@Demon = Class.new
|
|
7
7
|
@Demon.class_eval do
|
|
8
|
-
include Wrest::Components::
|
|
9
|
-
include Wrest::Components::
|
|
8
|
+
include Wrest::Components::Container
|
|
9
|
+
include Wrest::Components::Container::Typecaster
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -25,7 +25,7 @@ module Wrest::Components
|
|
|
25
25
|
|
|
26
26
|
it "hash should not typecast" do
|
|
27
27
|
class TestUser
|
|
28
|
-
include Wrest::Components::
|
|
28
|
+
include Wrest::Components::Container
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
@Demon.class_eval{ typecast :user => lambda{|user| TestUser.new(user)}}
|
|
@@ -58,8 +58,8 @@ module Wrest::Components
|
|
|
58
58
|
before :each do
|
|
59
59
|
@Sidhe = Class.new
|
|
60
60
|
@Sidhe.class_eval do
|
|
61
|
-
include Wrest::Components::
|
|
62
|
-
include Wrest::Components::
|
|
61
|
+
include Wrest::Components::Container
|
|
62
|
+
include Wrest::Components::Container::Typecaster
|
|
63
63
|
|
|
64
64
|
typecast :age => as_integer
|
|
65
65
|
end
|