restfulie 0.8.0 → 0.8.1
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/Gemfile +10 -5
- data/Rakefile +5 -2
- data/lib/restfulie.rb +10 -5
- data/lib/restfulie/client.rb +13 -9
- data/lib/restfulie/client/base.rb +24 -65
- data/lib/restfulie/client/configuration.rb +62 -64
- data/lib/restfulie/client/entry_point.rb +36 -0
- data/lib/restfulie/client/ext/atom_ext.rb +12 -0
- data/lib/restfulie/client/ext/http_ext.rb +22 -0
- data/lib/restfulie/client/ext/json_ext.rb +12 -0
- data/lib/restfulie/client/ext/xml_ext.rb +4 -0
- data/lib/restfulie/client/http.rb +25 -13
- data/lib/restfulie/client/http/cache.rb +22 -22
- data/lib/restfulie/client/http/error.rb +70 -70
- data/lib/restfulie/client/http/link_request_builder.rb +15 -0
- data/lib/restfulie/client/http/request_adapter.rb +209 -0
- data/lib/restfulie/client/http/request_builder.rb +107 -0
- data/lib/restfulie/client/http/request_builder_executor.rb +24 -0
- data/lib/restfulie/client/http/request_executor.rb +17 -0
- data/lib/restfulie/client/http/request_follow.rb +42 -0
- data/lib/restfulie/client/http/request_follow_executor.rb +10 -0
- data/lib/restfulie/client/http/request_history.rb +69 -0
- data/lib/restfulie/client/http/request_history_executor.rb +10 -0
- data/lib/restfulie/client/http/request_marshaller.rb +127 -0
- data/lib/restfulie/client/http/request_marshaller_executor.rb +10 -0
- data/lib/restfulie/client/http/response.rb +23 -0
- data/lib/restfulie/client/http/response_handler.rb +67 -0
- data/lib/restfulie/client/http/response_holder.rb +9 -0
- data/lib/restfulie/client/mikyung.rb +17 -14
- data/lib/restfulie/client/mikyung/concatenator.rb +15 -12
- data/lib/restfulie/client/mikyung/core.rb +65 -39
- data/lib/restfulie/client/mikyung/languages.rb +8 -26
- data/lib/restfulie/client/mikyung/languages/german.rb +24 -0
- data/lib/restfulie/client/mikyung/languages/portuguese.rb +23 -0
- data/lib/restfulie/client/mikyung/rest_process_model.rb +184 -107
- data/lib/restfulie/client/mikyung/steady_state_walker.rb +34 -28
- data/lib/restfulie/client/mikyung/then_condition.rb +33 -27
- data/lib/restfulie/client/mikyung/when_condition.rb +53 -49
- data/lib/restfulie/common.rb +7 -12
- data/lib/restfulie/common/converter.rb +20 -9
- data/lib/restfulie/common/converter/atom.rb +8 -83
- data/lib/restfulie/common/converter/atom/base.rb +89 -0
- data/lib/restfulie/common/converter/atom/builder.rb +101 -99
- data/lib/restfulie/common/converter/atom/helpers.rb +16 -8
- data/lib/restfulie/common/converter/json.rb +12 -0
- data/lib/restfulie/common/converter/json/base.rb +84 -0
- data/lib/restfulie/common/converter/json/builder.rb +102 -0
- data/lib/restfulie/common/converter/json/helpers.rb +17 -0
- data/lib/restfulie/common/converter/values.rb +30 -26
- data/lib/restfulie/common/converter/xml.rb +14 -0
- data/lib/restfulie/common/converter/xml/base.rb +61 -0
- data/lib/restfulie/common/converter/xml/builder.rb +112 -0
- data/lib/restfulie/common/converter/xml/helpers.rb +17 -0
- data/lib/restfulie/common/converter/xml/link.rb +25 -0
- data/lib/restfulie/common/converter/xml/links.rb +25 -0
- data/lib/restfulie/common/core_ext.rb +1 -5
- data/lib/restfulie/common/core_ext/hash.rb +12 -0
- data/lib/restfulie/common/error.rb +19 -0
- data/lib/restfulie/common/logger.rb +17 -9
- data/lib/restfulie/common/representation.rb +9 -10
- data/lib/restfulie/common/representation/atom.rb +15 -47
- data/lib/restfulie/common/representation/atom/base.rb +122 -365
- data/lib/restfulie/common/representation/atom/category.rb +41 -0
- data/lib/restfulie/common/representation/atom/entry.rb +52 -100
- data/lib/restfulie/common/representation/atom/factory.rb +43 -0
- data/lib/restfulie/common/representation/atom/feed.rb +103 -99
- data/lib/restfulie/common/representation/atom/link.rb +68 -0
- data/lib/restfulie/common/representation/atom/person.rb +48 -0
- data/lib/restfulie/common/representation/atom/source.rb +59 -0
- data/lib/restfulie/common/representation/atom/tag_collection.rb +38 -0
- data/lib/restfulie/common/representation/atom/xml.rb +95 -0
- data/lib/restfulie/common/representation/generic.rb +30 -29
- data/lib/restfulie/common/representation/json.rb +10 -22
- data/lib/restfulie/common/representation/json/base.rb +27 -0
- data/lib/restfulie/common/representation/json/keys_as_methods.rb +72 -0
- data/lib/restfulie/common/representation/json/link.rb +29 -0
- data/lib/restfulie/common/representation/json/link_collection.rb +23 -0
- data/lib/restfulie/common/representation/xml.rb +18 -227
- data/lib/restfulie/server.rb +9 -10
- data/lib/restfulie/server/action_controller.rb +10 -12
- data/lib/restfulie/server/action_controller/base.rb +18 -15
- data/lib/restfulie/server/action_controller/{routing/patch.rb → patch.rb} +0 -0
- data/lib/restfulie/server/action_controller/restful_responder.rb +43 -35
- data/lib/restfulie/server/action_view.rb +8 -6
- data/lib/restfulie/server/action_view/helpers.rb +47 -41
- data/lib/restfulie/server/action_view/template_handlers.rb +24 -12
- data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +17 -12
- data/lib/restfulie/server/configuration.rb +22 -19
- data/lib/restfulie/server/{restfulie_controller.rb → controller.rb} +1 -10
- data/lib/restfulie/server/core_ext.rb +1 -1
- data/lib/restfulie/version.rb +14 -0
- metadata +52 -16
- data/lib/restfulie/client/http/adapter.rb +0 -502
- data/lib/restfulie/client/http/atom_ext.rb +0 -4
- data/lib/restfulie/client/http/core_ext.rb +0 -6
- data/lib/restfulie/client/http/core_ext/http.rb +0 -19
- data/lib/restfulie/client/http/marshal.rb +0 -145
- data/lib/restfulie/client/http/xml_ext.rb +0 -7
- data/lib/restfulie/common/core_ext/proc.rb +0 -48
- data/lib/restfulie/common/errors.rb +0 -15
- data/lib/restfulie/server/action_controller/routing.rb +0 -12
- data/lib/restfulie/server/action_controller/routing/restful_route.rb +0 -14
@@ -1,8 +1,10 @@
|
|
1
1
|
if defined? ::ActionView and ::ActionController
|
2
|
-
|
3
|
-
|
2
|
+
module Restfulie #:nodoc:
|
3
|
+
module Server #:nodoc:
|
4
|
+
module ActionView #:nodoc:
|
5
|
+
autoload :TemplateHandlers, 'restfulie/server/action_view/template_handlers'
|
6
|
+
autoload :Helpers, 'restfulie/server/action_view/helpers'
|
7
|
+
end
|
8
|
+
end
|
4
9
|
end
|
5
|
-
|
6
|
-
require 'restfulie/server/action_view/template_handlers'
|
7
|
-
require 'restfulie/server/action_view/helpers'
|
8
|
-
end
|
10
|
+
end
|
@@ -1,45 +1,51 @@
|
|
1
|
-
module Restfulie
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
1
|
+
module Restfulie
|
2
|
+
module Server
|
3
|
+
module ActionView
|
4
|
+
module Helpers
|
5
|
+
# Load a partial template to execute in describe
|
6
|
+
#
|
7
|
+
# For example:
|
8
|
+
#
|
9
|
+
# Passing the current context to partial in template:
|
10
|
+
#
|
11
|
+
# member(@album) do |member, album|
|
12
|
+
# partial('member', binding)
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# in partial:
|
16
|
+
#
|
17
|
+
# member.links << link(:rel => :artists, :href => album_artists_url(album))
|
18
|
+
#
|
19
|
+
# Or passing local variables assing
|
20
|
+
#
|
21
|
+
# collection(@albums) do |collection|
|
22
|
+
# collection.members do |member, album|
|
23
|
+
# partial("member", :locals => {:member => member, :album => album})
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
def partial(partial_path, caller_binding = nil)
|
28
|
+
template = _pick_partial_template(partial_path)
|
29
|
+
|
30
|
+
# Create a context to assing variables
|
31
|
+
if caller_binding.kind_of?(Hash)
|
32
|
+
Proc.new do
|
33
|
+
extend @restfulie_type_helpers
|
34
|
+
context = eval("(class << self; self; end)", binding)
|
35
|
+
|
36
|
+
unless caller_binding[:locals].nil?
|
37
|
+
caller_binding[:locals].each do |k, v|
|
38
|
+
context.send(:define_method, k.to_sym) { v }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
partial(partial_path, binding)
|
43
|
+
end.call
|
44
|
+
else
|
45
|
+
eval(template.source, caller_binding, template.path)
|
36
46
|
end
|
37
47
|
end
|
38
|
-
|
39
|
-
partial(partial_path, binding)
|
40
|
-
end.call
|
41
|
-
else
|
42
|
-
eval(template.source, caller_binding, template.path)
|
48
|
+
end
|
43
49
|
end
|
44
50
|
end
|
45
|
-
end
|
51
|
+
end
|
@@ -1,13 +1,25 @@
|
|
1
|
-
module Restfulie
|
1
|
+
module Restfulie
|
2
|
+
module Server
|
3
|
+
module ActionView
|
4
|
+
module TemplateHandlers #:nodoc:
|
5
|
+
autoload :Tokamak, 'restfulie/server/action_view/template_handlers/tokamak'
|
6
|
+
|
7
|
+
# It is needed to explicitly call 'activate!' to install the Tokamak
|
8
|
+
# template handler
|
9
|
+
def self.activate!
|
10
|
+
if defined? ::ActionView::Template and
|
11
|
+
::ActionView::Template.respond_to?(:register_template_handler)
|
12
|
+
::ActionView::Template
|
13
|
+
else
|
14
|
+
::ActionView::Base
|
15
|
+
end.register_template_handler(:tokamak,
|
16
|
+
Restfulie::Server::ActionView::TemplateHandlers::Tokamak)
|
17
|
+
|
18
|
+
if defined? ::ActionController::Base
|
19
|
+
::ActionController::Base.exempt_from_layout :tokamak
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
2
25
|
end
|
3
|
-
|
4
|
-
require 'restfulie/server/action_view/template_handlers/tokamak'
|
5
|
-
|
6
|
-
if defined? ::ActionView::Template and ::ActionView::Template.respond_to? :register_template_handler
|
7
|
-
::ActionView::Template
|
8
|
-
else
|
9
|
-
::ActionView::Base
|
10
|
-
end.register_template_handler(:tokamak, Restfulie::Server::ActionView::TemplateHandlers::Tokamak)
|
11
|
-
|
12
|
-
::ActionController::Base.exempt_from_layout :tokamak if defined? ::ActionController::Base
|
13
|
-
|
@@ -1,15 +1,20 @@
|
|
1
|
-
module Restfulie
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module Restfulie
|
2
|
+
module Server
|
3
|
+
module ActionView
|
4
|
+
module TemplateHandlers
|
5
|
+
class Tokamak < ::ActionView::TemplateHandler
|
6
|
+
include ::ActionView::TemplateHandlers::Compilable
|
7
|
+
|
8
|
+
def compile(template)
|
9
|
+
"@restfulie_type_helpers = Restfulie::Client::HTTP::RequestMarshaller.content_type_for(self.response.content_type).helper; " +
|
10
|
+
"extend @restfulie_type_helpers; " +
|
11
|
+
"extend Restfulie::Server::ActionView::Helpers; " +
|
12
|
+
"code_block = lambda { #{template.source} };" +
|
13
|
+
"builder = code_block.call; " +
|
14
|
+
"builder.to_s"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -1,21 +1,24 @@
|
|
1
|
-
module Restfulie
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
module Restfulie
|
2
|
+
module Server
|
3
|
+
module Configuration
|
4
|
+
# Defines host to be passed to polymorphic_url.
|
5
|
+
# You need to setup this to your own domain in order to generate meaningful links.
|
6
|
+
mattr_accessor :host
|
7
|
+
@@host = 'localhost'
|
8
|
+
|
9
|
+
# Passes a symbol to polymorphic_url in order to use a namespaced named_route.
|
10
|
+
# So, if config.named_route_prefix = :rest, it will search for rest_album_url,
|
11
|
+
# rest_album_songs_url, and so on.
|
12
|
+
mattr_accessor :named_route_prefix
|
13
|
+
@@named_route_prefix = nil
|
14
|
+
|
15
|
+
# This defines a Rails-like way to setup options. You can do, in a initializer:
|
16
|
+
# Restfulie::Server.setup do |config|
|
17
|
+
# config.host = 'mydomain.com'
|
18
|
+
# end
|
19
|
+
def self.setup
|
20
|
+
yield self
|
21
|
+
end
|
22
|
+
end
|
19
23
|
end
|
20
24
|
end
|
21
|
-
|
@@ -1,15 +1,10 @@
|
|
1
1
|
module Restfulie
|
2
|
-
|
3
2
|
module Server
|
4
|
-
|
5
3
|
# Controller which adds default CRUD + search + other operations.
|
6
4
|
# TODO: move these actions to controller/base.rb (maybe using InheritedResources, maybe not)
|
7
5
|
module Controller
|
8
|
-
|
9
6
|
# creates a model based on the request media-type extracted from its content-type
|
10
|
-
#
|
11
7
|
def create
|
12
|
-
|
13
8
|
type = model_type
|
14
9
|
return head 415 unless fits_content(type, request.headers['CONTENT_TYPE'])
|
15
10
|
|
@@ -19,7 +14,6 @@ module Restfulie
|
|
19
14
|
else
|
20
15
|
render :xml => @model.errors, :status => :unprocessable_entity
|
21
16
|
end
|
22
|
-
|
23
17
|
end
|
24
18
|
|
25
19
|
# renders this resource
|
@@ -75,9 +69,6 @@ module Restfulie
|
|
75
69
|
type.media_type_representations.include?(content_type) :
|
76
70
|
Restfulie::MediaType.default_representations.include?(content_type))
|
77
71
|
end
|
78
|
-
|
79
72
|
end
|
80
|
-
|
81
73
|
end
|
82
|
-
|
83
|
-
end
|
74
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
require 'restfulie/server/core_ext/array'
|
1
|
+
require 'restfulie/server/core_ext/array'
|
metadata
CHANGED
@@ -5,16 +5,16 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 8
|
8
|
-
-
|
9
|
-
version: 0.8.
|
8
|
+
- 1
|
9
|
+
version: 0.8.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
|
-
-
|
12
|
+
- Guilherme Silveira, Caue Guerra, Luis Cipriani, Everton Ribeiro, George Guimaraes, Paulo Ahagon
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-06-03 00:00:00 -03:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -98,17 +98,32 @@ extra_rdoc_files: []
|
|
98
98
|
files:
|
99
99
|
- lib/restfulie/client/base.rb
|
100
100
|
- lib/restfulie/client/configuration.rb
|
101
|
-
- lib/restfulie/client/
|
102
|
-
- lib/restfulie/client/
|
101
|
+
- lib/restfulie/client/entry_point.rb
|
102
|
+
- lib/restfulie/client/ext/atom_ext.rb
|
103
|
+
- lib/restfulie/client/ext/http_ext.rb
|
104
|
+
- lib/restfulie/client/ext/json_ext.rb
|
105
|
+
- lib/restfulie/client/ext/xml_ext.rb
|
103
106
|
- lib/restfulie/client/http/cache.rb
|
104
|
-
- lib/restfulie/client/http/core_ext/http.rb
|
105
|
-
- lib/restfulie/client/http/core_ext.rb
|
106
107
|
- lib/restfulie/client/http/error.rb
|
107
|
-
- lib/restfulie/client/http/
|
108
|
-
- lib/restfulie/client/http/
|
108
|
+
- lib/restfulie/client/http/link_request_builder.rb
|
109
|
+
- lib/restfulie/client/http/request_adapter.rb
|
110
|
+
- lib/restfulie/client/http/request_builder.rb
|
111
|
+
- lib/restfulie/client/http/request_builder_executor.rb
|
112
|
+
- lib/restfulie/client/http/request_executor.rb
|
113
|
+
- lib/restfulie/client/http/request_follow.rb
|
114
|
+
- lib/restfulie/client/http/request_follow_executor.rb
|
115
|
+
- lib/restfulie/client/http/request_history.rb
|
116
|
+
- lib/restfulie/client/http/request_history_executor.rb
|
117
|
+
- lib/restfulie/client/http/request_marshaller.rb
|
118
|
+
- lib/restfulie/client/http/request_marshaller_executor.rb
|
119
|
+
- lib/restfulie/client/http/response.rb
|
120
|
+
- lib/restfulie/client/http/response_handler.rb
|
121
|
+
- lib/restfulie/client/http/response_holder.rb
|
109
122
|
- lib/restfulie/client/http.rb
|
110
123
|
- lib/restfulie/client/mikyung/concatenator.rb
|
111
124
|
- lib/restfulie/client/mikyung/core.rb
|
125
|
+
- lib/restfulie/client/mikyung/languages/german.rb
|
126
|
+
- lib/restfulie/client/mikyung/languages/portuguese.rb
|
112
127
|
- lib/restfulie/client/mikyung/languages.rb
|
113
128
|
- lib/restfulie/client/mikyung/rest_process_model.rb
|
114
129
|
- lib/restfulie/client/mikyung/steady_state_walker.rb
|
@@ -116,40 +131,61 @@ files:
|
|
116
131
|
- lib/restfulie/client/mikyung/when_condition.rb
|
117
132
|
- lib/restfulie/client/mikyung.rb
|
118
133
|
- lib/restfulie/client.rb
|
134
|
+
- lib/restfulie/common/converter/atom/base.rb
|
119
135
|
- lib/restfulie/common/converter/atom/builder.rb
|
120
136
|
- lib/restfulie/common/converter/atom/helpers.rb
|
121
137
|
- lib/restfulie/common/converter/atom.rb
|
138
|
+
- lib/restfulie/common/converter/json/base.rb
|
139
|
+
- lib/restfulie/common/converter/json/builder.rb
|
140
|
+
- lib/restfulie/common/converter/json/helpers.rb
|
141
|
+
- lib/restfulie/common/converter/json.rb
|
122
142
|
- lib/restfulie/common/converter/values.rb
|
143
|
+
- lib/restfulie/common/converter/xml/base.rb
|
144
|
+
- lib/restfulie/common/converter/xml/builder.rb
|
145
|
+
- lib/restfulie/common/converter/xml/helpers.rb
|
146
|
+
- lib/restfulie/common/converter/xml/link.rb
|
147
|
+
- lib/restfulie/common/converter/xml/links.rb
|
148
|
+
- lib/restfulie/common/converter/xml.rb
|
123
149
|
- lib/restfulie/common/converter.rb
|
124
|
-
- lib/restfulie/common/core_ext/
|
150
|
+
- lib/restfulie/common/core_ext/hash.rb
|
125
151
|
- lib/restfulie/common/core_ext.rb
|
126
|
-
- lib/restfulie/common/
|
152
|
+
- lib/restfulie/common/error.rb
|
127
153
|
- lib/restfulie/common/logger.rb
|
128
154
|
- lib/restfulie/common/representation/atom/base.rb
|
155
|
+
- lib/restfulie/common/representation/atom/category.rb
|
129
156
|
- lib/restfulie/common/representation/atom/entry.rb
|
157
|
+
- lib/restfulie/common/representation/atom/factory.rb
|
130
158
|
- lib/restfulie/common/representation/atom/feed.rb
|
159
|
+
- lib/restfulie/common/representation/atom/link.rb
|
160
|
+
- lib/restfulie/common/representation/atom/person.rb
|
161
|
+
- lib/restfulie/common/representation/atom/source.rb
|
162
|
+
- lib/restfulie/common/representation/atom/tag_collection.rb
|
163
|
+
- lib/restfulie/common/representation/atom/xml.rb
|
131
164
|
- lib/restfulie/common/representation/atom.rb
|
132
165
|
- lib/restfulie/common/representation/generic.rb
|
166
|
+
- lib/restfulie/common/representation/json/base.rb
|
167
|
+
- lib/restfulie/common/representation/json/keys_as_methods.rb
|
168
|
+
- lib/restfulie/common/representation/json/link.rb
|
169
|
+
- lib/restfulie/common/representation/json/link_collection.rb
|
133
170
|
- lib/restfulie/common/representation/json.rb
|
134
171
|
- lib/restfulie/common/representation/xml.rb
|
135
172
|
- lib/restfulie/common/representation.rb
|
136
173
|
- lib/restfulie/common.rb
|
137
174
|
- lib/restfulie/server/action_controller/base.rb
|
138
175
|
- lib/restfulie/server/action_controller/params_parser.rb
|
176
|
+
- lib/restfulie/server/action_controller/patch.rb
|
139
177
|
- lib/restfulie/server/action_controller/restful_responder.rb
|
140
|
-
- lib/restfulie/server/action_controller/routing/patch.rb
|
141
|
-
- lib/restfulie/server/action_controller/routing/restful_route.rb
|
142
|
-
- lib/restfulie/server/action_controller/routing.rb
|
143
178
|
- lib/restfulie/server/action_controller.rb
|
144
179
|
- lib/restfulie/server/action_view/helpers.rb
|
145
180
|
- lib/restfulie/server/action_view/template_handlers/tokamak.rb
|
146
181
|
- lib/restfulie/server/action_view/template_handlers.rb
|
147
182
|
- lib/restfulie/server/action_view.rb
|
148
183
|
- lib/restfulie/server/configuration.rb
|
184
|
+
- lib/restfulie/server/controller.rb
|
149
185
|
- lib/restfulie/server/core_ext/array.rb
|
150
186
|
- lib/restfulie/server/core_ext.rb
|
151
|
-
- lib/restfulie/server/restfulie_controller.rb
|
152
187
|
- lib/restfulie/server.rb
|
188
|
+
- lib/restfulie/version.rb
|
153
189
|
- lib/restfulie.rb
|
154
190
|
- Gemfile
|
155
191
|
- LICENSE
|
@@ -1,502 +0,0 @@
|
|
1
|
-
module Restfulie::Client::HTTP #:nodoc:
|
2
|
-
|
3
|
-
#=Response
|
4
|
-
# Default response class
|
5
|
-
class Response
|
6
|
-
|
7
|
-
attr_reader :method
|
8
|
-
attr_reader :path
|
9
|
-
attr_reader :code
|
10
|
-
attr_reader :body
|
11
|
-
attr_reader :headers
|
12
|
-
|
13
|
-
def initialize(method, path, code, body, headers)
|
14
|
-
@method = method
|
15
|
-
@path = path
|
16
|
-
@code = code
|
17
|
-
@body = body
|
18
|
-
@headers = headers
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
#=ResponseHandler
|
24
|
-
# You can change instance registering a class according to the code.
|
25
|
-
#
|
26
|
-
#==Example
|
27
|
-
#
|
28
|
-
# class RequestExecutor
|
29
|
-
# include RequestAdapter
|
30
|
-
# def initialize(host)
|
31
|
-
# self.host=host
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# class FakeResponse < Restfulie::Client::HTTP::Response
|
36
|
-
# end
|
37
|
-
#
|
38
|
-
# Restfulie::Client::HTTP::ResponseHandler.register(201,FakeResponse)
|
39
|
-
# @re = Restfulie::Client::HTTP::RequestExecutor.new('http://restfulie.com')
|
40
|
-
# puts @re.as('application/atom+xml').get!('/posts').class.to_i #=> FakeResponse
|
41
|
-
#
|
42
|
-
module ResponseHandler
|
43
|
-
|
44
|
-
@@response_handlers = {}
|
45
|
-
##
|
46
|
-
# :singleton-method:
|
47
|
-
# Response handlers attribute reader
|
48
|
-
# * code: HTTP status code
|
49
|
-
def self.handlers(code)
|
50
|
-
@@response_handlers[code]
|
51
|
-
end
|
52
|
-
|
53
|
-
##
|
54
|
-
# :singleton-method:
|
55
|
-
# Use to register response handlers
|
56
|
-
#
|
57
|
-
# * <tt>code: HTTP status code</tt>
|
58
|
-
# * <tt>response_class: Response class</tt>
|
59
|
-
#
|
60
|
-
#==Example:
|
61
|
-
# class FakeResponse < ::Restfulie::Client::HTTP::Response
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# Restfulie::Client::HTTP::ResponseHandler.register(200,FakeResponse)
|
65
|
-
#
|
66
|
-
def self.register(code,response_class)
|
67
|
-
@@response_handlers[code] = response_class
|
68
|
-
end
|
69
|
-
|
70
|
-
##
|
71
|
-
# :singleton-method:
|
72
|
-
# Request Adapter uses this method to choose response instance
|
73
|
-
#
|
74
|
-
# *<tt>method: :get,:post,:delete,:head,:put</tt>
|
75
|
-
# *<tt>path: '/posts'</tt>
|
76
|
-
# *<tt>http_response</tt>
|
77
|
-
#
|
78
|
-
def self.handle(method, path, http_response)
|
79
|
-
response_class = @@response_handlers[http_response.code.to_i] || Response
|
80
|
-
headers = {}
|
81
|
-
http_response.header.each { |k, v| headers[k] = v }
|
82
|
-
response_class.new( method, path, http_response.code.to_i, http_response.body, headers)
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
#
|
88
|
-
# Request Adapter provides a minimal interface to exchange information between server over HTTP protocol through simple adapters.
|
89
|
-
#
|
90
|
-
# All the concrete adapters follow the interface laid down in this module.
|
91
|
-
# Default connection provider is net/http
|
92
|
-
#
|
93
|
-
#==Example
|
94
|
-
#
|
95
|
-
# @re = ::Restfulie::Client::HTTP::RequestExecutor.new('http://restfulie.com') #this class includes RequestAdapter module.
|
96
|
-
# puts @re.as('application/atom+xml').get!('/posts').title #=> 'Hello World!'
|
97
|
-
#
|
98
|
-
module RequestAdapter
|
99
|
-
|
100
|
-
attr_reader :host
|
101
|
-
attr_accessor :cookies
|
102
|
-
attr_writer :default_headers
|
103
|
-
|
104
|
-
def host=(host)
|
105
|
-
if host.is_a?(::URI)
|
106
|
-
@host = host
|
107
|
-
else
|
108
|
-
@host = ::URI.parse(host)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def default_headers
|
113
|
-
@default_headers ||= {}
|
114
|
-
end
|
115
|
-
|
116
|
-
#GET HTTP verb without {Error}
|
117
|
-
# * <tt>path: '/posts'</tt>
|
118
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
119
|
-
def get(path, *args)
|
120
|
-
request(:get, path, *args)
|
121
|
-
end
|
122
|
-
|
123
|
-
#HEAD HTTP verb without {Error}
|
124
|
-
# * <tt>path: '/posts'</tt>
|
125
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
126
|
-
def head(path, *args)
|
127
|
-
request(:head, path, *args)
|
128
|
-
end
|
129
|
-
|
130
|
-
#POST HTTP verb without {Error}
|
131
|
-
# * <tt>path: '/posts'</tt>
|
132
|
-
# * <tt>payload: 'some text'</tt>
|
133
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
134
|
-
def post(path, payload, *args)
|
135
|
-
request(:post, path, payload, *args)
|
136
|
-
end
|
137
|
-
|
138
|
-
#PATCH HTTP verb without {Error}
|
139
|
-
# * <tt>path: '/posts'</tt>
|
140
|
-
# * <tt>payload: 'some text'</tt>
|
141
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
142
|
-
def patch(path, payload, *args)
|
143
|
-
request(:patch, path, payload, *args)
|
144
|
-
end
|
145
|
-
|
146
|
-
#PUT HTTP verb without {Error}
|
147
|
-
# * <tt>path: '/posts'</tt>
|
148
|
-
# * <tt>payload: 'some text'</tt>
|
149
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
150
|
-
def put(path, payload, *args)
|
151
|
-
request(:put, path, payload, *args)
|
152
|
-
end
|
153
|
-
|
154
|
-
#DELETE HTTP verb without {Error}
|
155
|
-
# * <tt>path: '/posts'</tt>
|
156
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
157
|
-
def delete(path, *args)
|
158
|
-
request(:delete, path, *args)
|
159
|
-
end
|
160
|
-
|
161
|
-
#GET HTTP verb {Error}
|
162
|
-
# * <tt>path: '/posts'</tt>
|
163
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
164
|
-
def get!(path, *args)
|
165
|
-
request!(:get, path, *args)
|
166
|
-
end
|
167
|
-
|
168
|
-
#HEAD HTTP verb {Error}
|
169
|
-
# * <tt>path: '/posts'</tt>
|
170
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
171
|
-
def head!(path, *args)
|
172
|
-
request!(:head, path, *args)
|
173
|
-
end
|
174
|
-
|
175
|
-
#POST HTTP verb {Error}
|
176
|
-
# * <tt>path: '/posts'</tt>
|
177
|
-
# * <tt>payload: 'some text'</tt>
|
178
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
179
|
-
def post!(path, payload, *args)
|
180
|
-
request!(:post, path, payload, *args)
|
181
|
-
end
|
182
|
-
|
183
|
-
#PATCH HTTP verb {Error}
|
184
|
-
# * <tt>path: '/posts'</tt>
|
185
|
-
# * <tt>payload: 'some text'</tt>
|
186
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
187
|
-
def patch!(path, payload, *args)
|
188
|
-
request!(:patch, path, payload, *args)
|
189
|
-
end
|
190
|
-
|
191
|
-
#PUT HTTP verb {Error}
|
192
|
-
# * <tt>path: '/posts'</tt>
|
193
|
-
# * <tt>payload: 'some text'</tt>
|
194
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
195
|
-
def put!(path, payload, *args)
|
196
|
-
request!(:put, path, payload, *args)
|
197
|
-
end
|
198
|
-
|
199
|
-
#DELETE HTTP verb {Error}
|
200
|
-
# * <tt>path: '/posts'</tt>
|
201
|
-
# * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
202
|
-
def delete!(path, *args)
|
203
|
-
request!(:delete, path, *args)
|
204
|
-
end
|
205
|
-
|
206
|
-
#Executes a request against your server and return a response instance without {Error}
|
207
|
-
# * <tt>method: :get,:post,:delete,:head,:put</tt>
|
208
|
-
# * <tt>path: '/posts'</tt>
|
209
|
-
# * <tt>args: payload: 'some text' and/or headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
210
|
-
def request(method, path, *args)
|
211
|
-
request!(method, path, *args)
|
212
|
-
rescue Error::RESTError => se
|
213
|
-
se.response
|
214
|
-
end
|
215
|
-
|
216
|
-
#Executes a request against your server and return a response instance.
|
217
|
-
# * <tt>method: :get,:post,:delete,:head,:put</tt>
|
218
|
-
# * <tt>path: '/posts'</tt>
|
219
|
-
# * <tt>args: payload: 'some text' and/or headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
|
220
|
-
def request!(method, path, *args)
|
221
|
-
headers = default_headers.merge(args.extract_options!)
|
222
|
-
unless @host.user.blank? && @host.password.blank?
|
223
|
-
headers["Authorization"] = "Basic " + ["#{@host.user}:#{@host.password}"].pack("m").delete("\r\n")
|
224
|
-
end
|
225
|
-
headers['cookie'] = @cookies if @cookies
|
226
|
-
args << headers
|
227
|
-
|
228
|
-
::Restfulie::Common::Logger.logger.info(request_to_s(method, path, *args)) if ::Restfulie::Common::Logger.logger
|
229
|
-
begin
|
230
|
-
response = ResponseHandler.handle(method, path, get_connection_provider.send(method, path, *args))
|
231
|
-
rescue Exception => e
|
232
|
-
raise Error::ServerNotAvailableError.new(self, Response.new(method, path, 503, nil, {}), e )
|
233
|
-
end
|
234
|
-
|
235
|
-
case response.code
|
236
|
-
when 100..299
|
237
|
-
response
|
238
|
-
when 300..399
|
239
|
-
raise Error::Redirection.new(self, response)
|
240
|
-
when 400
|
241
|
-
raise Error::BadRequest.new(self, response)
|
242
|
-
when 401
|
243
|
-
raise Error::Unauthorized.new(self, response)
|
244
|
-
when 403
|
245
|
-
raise Error::Forbidden.new(self, response)
|
246
|
-
when 404
|
247
|
-
raise Error::NotFound.new(self, response)
|
248
|
-
when 405
|
249
|
-
raise Error::MethodNotAllowed.new(self, response)
|
250
|
-
when 407
|
251
|
-
raise Error::ProxyAuthenticationRequired.new(self, response)
|
252
|
-
when 409
|
253
|
-
raise Error::Conflict.new(self, response)
|
254
|
-
when 410
|
255
|
-
raise Error::Gone.new(self, response)
|
256
|
-
when 412
|
257
|
-
raise Error::PreconditionFailed.new(self, response)
|
258
|
-
when 402, 406, 408, 411, 413..499
|
259
|
-
raise Error::ClientError.new(self, response)
|
260
|
-
when 501
|
261
|
-
raise Error::NotImplemented.new(self, response)
|
262
|
-
when 500, 502..599
|
263
|
-
raise Error::ServerError.new(self, response)
|
264
|
-
else
|
265
|
-
raise Error::UnknownError.new(self, response)
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
private
|
270
|
-
|
271
|
-
def get_connection_provider
|
272
|
-
@connection ||= ::Net::HTTP.new(@host.host, @host.port)
|
273
|
-
end
|
274
|
-
|
275
|
-
protected
|
276
|
-
|
277
|
-
def request_to_s(method, path, *args)
|
278
|
-
result = ["#{method.to_s.upcase} #{path}"]
|
279
|
-
|
280
|
-
arguments = args.dup
|
281
|
-
headers = arguments.extract_options!
|
282
|
-
|
283
|
-
if [:post, :put].include?(method)
|
284
|
-
body = arguments.shift
|
285
|
-
end
|
286
|
-
|
287
|
-
result << headers.collect { |key, value| "#{key}: #{value}" }.join("\n")
|
288
|
-
|
289
|
-
(result + [body ? (body.inspect + "\n") : nil]).compact.join("\n") << "\n"
|
290
|
-
end
|
291
|
-
|
292
|
-
end
|
293
|
-
|
294
|
-
#=RequestBuilder
|
295
|
-
# Uses RequestAdapater to create a HTTP Request DSL
|
296
|
-
#
|
297
|
-
#==Example:
|
298
|
-
#
|
299
|
-
# @builder = ::Restfulie::Client::HTTP::RequestBuilderExecutor.new("http://restfulie.com") #this class includes RequestBuilder module.
|
300
|
-
# @builder.at('/posts').as('application/xml').accepts('application/atom+xml').with('Accept-Language' => 'en').get.code #=> 200
|
301
|
-
#
|
302
|
-
module RequestBuilder
|
303
|
-
include RequestAdapter
|
304
|
-
|
305
|
-
#Set host
|
306
|
-
def at(url)
|
307
|
-
self.host = url
|
308
|
-
self
|
309
|
-
end
|
310
|
-
|
311
|
-
#Set Content-Type and Accept headers
|
312
|
-
def as(content_type)
|
313
|
-
headers['Content-Type'] = content_type
|
314
|
-
accepts(content_type)
|
315
|
-
end
|
316
|
-
|
317
|
-
#Set Accept headers
|
318
|
-
def accepts(content_type)
|
319
|
-
headers['Accept'] = content_type
|
320
|
-
self
|
321
|
-
end
|
322
|
-
|
323
|
-
#
|
324
|
-
#Merge internal header
|
325
|
-
#
|
326
|
-
# * <tt>headers (e.g. {'Cache-control' => 'no-cache'})</tt>
|
327
|
-
#
|
328
|
-
def with(headers)
|
329
|
-
self.headers.merge!(headers)
|
330
|
-
self
|
331
|
-
end
|
332
|
-
|
333
|
-
def headers
|
334
|
-
@headers || @headers = {}
|
335
|
-
end
|
336
|
-
|
337
|
-
#Path (e.g. http://restfulie.com/posts => /posts)
|
338
|
-
def path
|
339
|
-
host.path
|
340
|
-
end
|
341
|
-
|
342
|
-
def get
|
343
|
-
request(:get, path, headers)
|
344
|
-
end
|
345
|
-
|
346
|
-
def head
|
347
|
-
request(:head, path, headers)
|
348
|
-
end
|
349
|
-
|
350
|
-
def post(payload)
|
351
|
-
request(:post, path, payload, headers)
|
352
|
-
end
|
353
|
-
|
354
|
-
def patch(payload)
|
355
|
-
request(:patch, path, payload, headers)
|
356
|
-
end
|
357
|
-
|
358
|
-
def put(payload)
|
359
|
-
request(:put, path, payload, headers)
|
360
|
-
end
|
361
|
-
|
362
|
-
def delete
|
363
|
-
request(:delete, path, headers)
|
364
|
-
end
|
365
|
-
|
366
|
-
def get!
|
367
|
-
request!(:get, path, headers)
|
368
|
-
end
|
369
|
-
|
370
|
-
def head!
|
371
|
-
request!(:head, path, headers)
|
372
|
-
end
|
373
|
-
|
374
|
-
def post!(payload)
|
375
|
-
request!(:post, path, payload, headers)
|
376
|
-
end
|
377
|
-
|
378
|
-
def patch!(payload)
|
379
|
-
request!(:patch, path, payload, headers)
|
380
|
-
end
|
381
|
-
|
382
|
-
def put!(payload)
|
383
|
-
request!(:put, path, payload, headers)
|
384
|
-
end
|
385
|
-
|
386
|
-
def delete!
|
387
|
-
request!(:delete, path, headers)
|
388
|
-
end
|
389
|
-
|
390
|
-
protected
|
391
|
-
|
392
|
-
def headers=(h)
|
393
|
-
@headers = h
|
394
|
-
end
|
395
|
-
|
396
|
-
end
|
397
|
-
|
398
|
-
|
399
|
-
#=RequestHistory
|
400
|
-
# Uses RequestBuilder and remind previous requests
|
401
|
-
#
|
402
|
-
#==Example:
|
403
|
-
#
|
404
|
-
# @executor = ::Restfulie::Client::HTTP::RequestHistoryExecutor.new("http://restfulie.com") #this class includes RequestHistory module.
|
405
|
-
# @executor.at('/posts').as('application/xml').accepts('application/atom+xml').with('Accept-Language' => 'en').get.code #=> 200 #first request
|
406
|
-
# @executor.at('/blogs').as('application/xml').accepts('application/atom+xml').with('Accept-Language' => 'en').get.code #=> 200 #second request
|
407
|
-
# @executor.request_history!(0) #doing first request
|
408
|
-
#
|
409
|
-
module RequestHistory
|
410
|
-
include RequestBuilder
|
411
|
-
|
412
|
-
attr_accessor_with_default :max_to_remind, 10
|
413
|
-
|
414
|
-
def snapshots
|
415
|
-
@snapshots || @snapshots = []
|
416
|
-
end
|
417
|
-
|
418
|
-
def request!(method=nil, path=nil, *args)#:nodoc:
|
419
|
-
if method == nil || path == nil
|
420
|
-
raise 'History not selected' unless @snapshot
|
421
|
-
super( @snapshot[:method], @snapshot[:path], *@snapshot[:args] )
|
422
|
-
else
|
423
|
-
@snapshot = make_snapshot(method, path, *args)
|
424
|
-
unless snapshots.include?(@snapshot)
|
425
|
-
snapshots.shift if snapshots.size >= max_to_remind
|
426
|
-
snapshots << @snapshot
|
427
|
-
end
|
428
|
-
super
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
def request(method=nil, path=nil, *args)#:nodoc:
|
433
|
-
request!(method, path, *args)
|
434
|
-
rescue Error::RESTError => se
|
435
|
-
se.response
|
436
|
-
end
|
437
|
-
|
438
|
-
def history(number)
|
439
|
-
@snapshot = snapshots[number]
|
440
|
-
raise "Undefined snapshot for #{number}" unless @snapshot
|
441
|
-
self.host = @snapshot[:host]
|
442
|
-
self.cookies = @snapshot[:cookies]
|
443
|
-
self.headers = @snapshot[:headers]
|
444
|
-
self.default_headers = @snapshot[:default_headers]
|
445
|
-
at(@snapshot[:path])
|
446
|
-
end
|
447
|
-
|
448
|
-
private
|
449
|
-
|
450
|
-
def make_snapshot(method, path, *args)
|
451
|
-
arguments = args.dup
|
452
|
-
cutom_headers = arguments.extract_options!
|
453
|
-
{ :host => self.host.dup,
|
454
|
-
:default_headers => self.default_headers.dup,
|
455
|
-
:headers => self.headers.dup,
|
456
|
-
:cookies => self.cookies,
|
457
|
-
:method => method,
|
458
|
-
:path => path,
|
459
|
-
:args => arguments << self.headers.merge(cutom_headers) }
|
460
|
-
end
|
461
|
-
|
462
|
-
end
|
463
|
-
|
464
|
-
#=This class includes RequestAdapter module.
|
465
|
-
class RequestExecutor
|
466
|
-
include RequestAdapter
|
467
|
-
|
468
|
-
# * <tt> host (e.g. 'http://restfulie.com') </tt>
|
469
|
-
# * <tt> default_headers (e.g. {'Cache-control' => 'no-cache'} ) </tt>
|
470
|
-
def initialize(host, default_headers = {})
|
471
|
-
self.host=host
|
472
|
-
self.default_headers=default_headers
|
473
|
-
end
|
474
|
-
|
475
|
-
end
|
476
|
-
|
477
|
-
#=This class includes RequestBuilder module.
|
478
|
-
class RequestBuilderExecutor < RequestExecutor
|
479
|
-
include RequestBuilder
|
480
|
-
|
481
|
-
def host=(host)
|
482
|
-
super
|
483
|
-
at(self.host.path)
|
484
|
-
end
|
485
|
-
|
486
|
-
def at(path)
|
487
|
-
@path = path
|
488
|
-
self
|
489
|
-
end
|
490
|
-
|
491
|
-
def path
|
492
|
-
@path
|
493
|
-
end
|
494
|
-
|
495
|
-
end
|
496
|
-
|
497
|
-
#=This class inherits RequestFollowExecutor and include RequestHistory module.
|
498
|
-
class RequestHistoryExecutor < RequestBuilderExecutor
|
499
|
-
include RequestHistory
|
500
|
-
end
|
501
|
-
|
502
|
-
end
|