strelka 0.4.0 → 0.5.0.pre.393
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +1 -1
- data/Rakefile +1 -1
- data/lib/strelka/app/negotiation.rb +10 -39
- data/lib/strelka/httpresponse/negotiation.rb +36 -12
- data/lib/strelka.rb +1 -1
- data/spec/strelka/app/negotiation_spec.rb +20 -12
- data/spec/strelka/httpresponse/negotiation_spec.rb +10 -4
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d2cffaf505aa41496b0ce345534e70d6f4b45a0
|
4
|
+
data.tar.gz: c922b2aa4deafe3472b9be7d2d960237dc2e2b11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 295a62542aae175dd4c70d425fc70f43d314412db557a01989aa63b015931cdf20cad5793fefd4e15a237f49d0f50a17c95b72b5905f321a260520ba4c13e06f
|
7
|
+
data.tar.gz: 590d6dfab3b2a652e916b9e78ad497440b5e5de314abbd12b5c289fd917d43a1c9e4b212ec55fdc2d030693ef312ea44d8ce0b530c140ee5c714241388a0ae0d
|
checksums.yaml.gz.sig
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
Q�]O$S�S�������U��pMAx�q�T6��b?g7, ���C�����:�;|vN��ϤY�-�DΚ˴����[h���ŝ�t��؎���D���æ�}�٧л��^[h�o���ަ�5鑉gU��ַӢ�O�AOe���2�N���8�����L�dB����2��Ry~�����1�с�L�'%A��B�:�@00!Cu���4��YQ�b[J-��3g�r�+�<DUb��
|
data/Rakefile
CHANGED
@@ -27,7 +27,7 @@ hoespec = Hoe.spec 'strelka' do
|
|
27
27
|
self.dependency 'inversion', '~> 0.12'
|
28
28
|
self.dependency 'loggability', '~> 0.5'
|
29
29
|
self.dependency 'mongrel2', '~> 0.36'
|
30
|
-
self.dependency 'pluggability', '~> 0.
|
30
|
+
self.dependency 'pluggability', '~> 0.2'
|
31
31
|
self.dependency 'sysexits', '~> 1.1'
|
32
32
|
self.dependency 'trollop', '~> 2.0'
|
33
33
|
self.dependency 'uuidtools', '~> 2.1'
|
@@ -21,21 +21,7 @@ require 'strelka/httpresponse/negotiation'
|
|
21
21
|
#
|
22
22
|
# plugins :routing, :negotiation
|
23
23
|
#
|
24
|
-
# add_content_type :tnetstring, 'text/x-tnetstring'
|
25
|
-
# tnetstr = nil
|
26
|
-
# begin
|
27
|
-
# response.body.rewind
|
28
|
-
# tnetstr = TNetString.dump( response.body )
|
29
|
-
# rescue => err
|
30
|
-
# self.log.error "%p while transforming entity body to a TNetString: %s" %
|
31
|
-
# [ err.class, err.message ]
|
32
|
-
# return false
|
33
|
-
# else
|
34
|
-
# response.body = tnetstr
|
35
|
-
# response.content_type = 'text/x-tnetstring'
|
36
|
-
# return true
|
37
|
-
# end
|
38
|
-
# end
|
24
|
+
# add_content_type :tnetstring, 'text/x-tnetstring', TNetstring.method( :dump )
|
39
25
|
#
|
40
26
|
# end # class UserService
|
41
27
|
#
|
@@ -50,31 +36,16 @@ module Strelka::App::Negotiation
|
|
50
36
|
# Class methods to add to classes with content-negotiation.
|
51
37
|
module ClassMethods # :nodoc:
|
52
38
|
|
53
|
-
# Content-type tranform registry, keyed by name
|
54
|
-
@content_type_transforms = {}
|
55
|
-
attr_reader :content_type_transforms
|
56
|
-
|
57
|
-
# Content-type transform names, keyed by mimetype
|
58
|
-
@transform_names = {}
|
59
|
-
attr_reader :transform_names
|
60
|
-
|
61
|
-
|
62
|
-
### Extension callback -- add instance variables to extending objects.
|
63
|
-
def inherited( subclass )
|
64
|
-
super
|
65
|
-
subclass.instance_variable_set( :@content_type_transforms, @content_type_transforms.dup )
|
66
|
-
subclass.instance_variable_set( :@transform_names, @transform_names.dup )
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
39
|
### Define a new media-type associated with the specified +name+ and +mimetype+. Responses
|
71
|
-
### whose requests accept content of the given +mimetype+ will
|
72
|
-
### specified +
|
73
|
-
###
|
74
|
-
###
|
75
|
-
|
76
|
-
|
77
|
-
|
40
|
+
### whose requests accept content of the given +mimetype+ will #call the
|
41
|
+
### specified +callback+ with the current response body, and should return the
|
42
|
+
### transformed body. If the conversion failed, the callback can either raise an
|
43
|
+
### exception or return +nil+, either of which will continue on to any remaining
|
44
|
+
### transforms. If no +callback+ is given, the method's block will be used.
|
45
|
+
def add_content_type( name, mimetype, callback=nil ) # :yield: response.body
|
46
|
+
callback ||= Proc.new # Use the block
|
47
|
+
Strelka::HTTPResponse::Negotiation.mimetype_map[ name.to_sym ] = mimetype
|
48
|
+
Strelka::HTTPResponse::Negotiation.stringifiers[ mimetype ] = callback
|
78
49
|
end
|
79
50
|
|
80
51
|
end # module ClassMethods
|
@@ -8,6 +8,7 @@ require 'yajl'
|
|
8
8
|
|
9
9
|
require 'strelka/constants'
|
10
10
|
require 'strelka/exceptions'
|
11
|
+
require 'strelka/mixins'
|
11
12
|
require 'strelka/httpresponse' unless defined?( Strelka::HTTPResponse )
|
12
13
|
|
13
14
|
|
@@ -23,11 +24,12 @@ require 'strelka/httpresponse' unless defined?( Strelka::HTTPResponse )
|
|
23
24
|
# is acceptable according to its request's `Accept*` headers.
|
24
25
|
#
|
25
26
|
module Strelka::HTTPResponse::Negotiation
|
27
|
+
extend Strelka::MethodUtilities
|
26
28
|
include Strelka::Constants
|
27
29
|
|
28
30
|
# TODO: Perhaps replace this with something like this:
|
29
31
|
# Mongrel2::Config::Mimetype.to_hash( :extension => :mimetype )
|
30
|
-
|
32
|
+
BUILTIN_MIMETYPE_MAP = {
|
31
33
|
:html => 'text/html',
|
32
34
|
:text => 'text/plain',
|
33
35
|
|
@@ -43,10 +45,10 @@ module Strelka::HTTPResponse::Negotiation
|
|
43
45
|
:atom => 'application/atom+xml',
|
44
46
|
}
|
45
47
|
|
46
|
-
# A collection of stringifier callbacks, keyed by mimetype. If an
|
47
|
-
#
|
48
|
-
#
|
49
|
-
|
48
|
+
# A collection of default stringifier callbacks, keyed by mimetype. If an entry
|
49
|
+
# for the content-negotiation callback's mimetype exists in this Hash, it will
|
50
|
+
# be #call()ed on the callback's return value to stringify the body.
|
51
|
+
BUILTIN_STRINGIFIERS = {
|
50
52
|
'application/x-yaml' => YAML.method( :dump ),
|
51
53
|
'application/json' => Yajl.method( :dump ),
|
52
54
|
'text/plain' => Proc.new {|obj| obj.to_s },
|
@@ -62,6 +64,18 @@ module Strelka::HTTPResponse::Negotiation
|
|
62
64
|
]
|
63
65
|
|
64
66
|
|
67
|
+
##
|
68
|
+
# The Hash of symbolic mediatypes of the form:
|
69
|
+
# { <name (Symbol)> => <mimetype> }
|
70
|
+
singleton_attr_reader :mimetype_map
|
71
|
+
@mimetype_map = BUILTIN_MIMETYPE_MAP.dup
|
72
|
+
|
73
|
+
##
|
74
|
+
# The Hash of stringification callbacks, keyed by mimetype.
|
75
|
+
singleton_attr_reader :stringifiers
|
76
|
+
@stringifiers = BUILTIN_STRINGIFIERS.dup
|
77
|
+
|
78
|
+
|
65
79
|
### Add some instance variables for negotiation.
|
66
80
|
def initialize( * )
|
67
81
|
@mediatype_callbacks = {}
|
@@ -267,7 +281,11 @@ module Strelka::HTTPResponse::Negotiation
|
|
267
281
|
### to HTTP::OK.
|
268
282
|
def for( *mediatypes, &callback )
|
269
283
|
mediatypes.each do |mimetype|
|
270
|
-
|
284
|
+
if mimetype.is_a?( Symbol )
|
285
|
+
mimetype = Strelka::HTTPResponse::Negotiation.mimetype_map[ mimetype ] or
|
286
|
+
raise "No known mimetype mapped to %p" % [ mimetype ]
|
287
|
+
end
|
288
|
+
|
271
289
|
self.mediatype_callbacks[ mimetype ] = callback
|
272
290
|
end
|
273
291
|
|
@@ -307,17 +325,19 @@ module Strelka::HTTPResponse::Negotiation
|
|
307
325
|
### until one returns a true-ish value, which becomes the new entity
|
308
326
|
### body. If the body object is not a String,
|
309
327
|
def transform_content_type
|
328
|
+
self.log.debug "Applying content-type transforms (if any)"
|
310
329
|
return if self.mediatype_callbacks.empty?
|
311
330
|
|
312
|
-
self.log.debug "
|
331
|
+
self.log.debug " transform callbacks registered: %p" % [ self.mediatype_callbacks ]
|
313
332
|
self.better_mediatypes.each do |mediatype|
|
314
333
|
callbacks = self.mediatype_callbacks.find_all do |mimetype, _|
|
315
334
|
mediatype =~ mimetype
|
316
335
|
end
|
317
336
|
|
318
337
|
if callbacks.empty?
|
319
|
-
self.log.debug "
|
338
|
+
self.log.debug " no transforms for %s" % [ mediatype ]
|
320
339
|
else
|
340
|
+
self.log.debug " %d transform/s for %s" % [ callbacks.length, mediatype ]
|
321
341
|
callbacks.each do |mimetype, callback|
|
322
342
|
return if self.try_content_type_callback( mimetype, callback )
|
323
343
|
end
|
@@ -334,9 +354,13 @@ module Strelka::HTTPResponse::Negotiation
|
|
334
354
|
|
335
355
|
new_body = callback.call( mimetype ) or return false
|
336
356
|
|
337
|
-
self.log.debug " successfully transformed: %p! Setting up response." % [ new_body ]
|
338
|
-
|
339
|
-
|
357
|
+
self.log.debug " successfully transformed: %p! Setting up response." % [ new_body.class ]
|
358
|
+
stringifiers = Strelka::HTTPResponse::Negotiation.stringifiers
|
359
|
+
if stringifiers.key?( mimetype )
|
360
|
+
new_body = stringifiers[ mimetype ].call( new_body )
|
361
|
+
else
|
362
|
+
self.log.debug " no stringifier registered for %p" % [ mimetype ]
|
363
|
+
end
|
340
364
|
|
341
365
|
self.body = new_body
|
342
366
|
self.content_type = mimetype.dup # :TODO: Why is this frozen?
|
@@ -512,7 +536,7 @@ module Strelka::HTTPResponse::Negotiation
|
|
512
536
|
|
513
537
|
# Don't close the FD when this IO goes out of scope
|
514
538
|
oldbody = self.body
|
515
|
-
oldbody.
|
539
|
+
oldbody.autoclose = false
|
516
540
|
|
517
541
|
# Re-open the same file descriptor, but transcoding to the wanted encoding
|
518
542
|
self.body = IO.for_fd( oldbody.fileno, internal_encoding: enc )
|
data/lib/strelka.rb
CHANGED
@@ -46,6 +46,19 @@ describe Strelka::App::Negotiation do
|
|
46
46
|
def initialize( appid='conneg-test', sspec=TEST_SEND_SPEC, rspec=TEST_RECV_SPEC )
|
47
47
|
super
|
48
48
|
end
|
49
|
+
|
50
|
+
add_content_type :tnetstring, 'text/x-tnetstring', TNetstring.method(:dump)
|
51
|
+
|
52
|
+
def handle_request( req )
|
53
|
+
super do
|
54
|
+
res = req.response
|
55
|
+
res.for( :tnetstring ) {[ 'an', {'array' => 'of stuff'} ]}
|
56
|
+
res.for( :html ) do
|
57
|
+
"<html><head><title>Yep</title></head><body>Yeah!</body></html>"
|
58
|
+
end
|
59
|
+
res
|
60
|
+
end
|
61
|
+
end
|
49
62
|
end
|
50
63
|
end
|
51
64
|
|
@@ -54,18 +67,6 @@ describe Strelka::App::Negotiation do
|
|
54
67
|
end
|
55
68
|
|
56
69
|
|
57
|
-
it "has its config inherited by subclasses" do
|
58
|
-
@app.add_content_type :text, 'text/plain' do
|
59
|
-
"It's all text now, baby"
|
60
|
-
end
|
61
|
-
subclass = Class.new( @app )
|
62
|
-
|
63
|
-
subclass.transform_names.should == @app.transform_names
|
64
|
-
subclass.transform_names.should_not equal( @app.transform_names )
|
65
|
-
subclass.content_type_transforms.should == @app.content_type_transforms
|
66
|
-
subclass.content_type_transforms.should_not equal( @app.content_type_transforms )
|
67
|
-
end
|
68
|
-
|
69
70
|
it "gets requests that have been extended with content-negotiation" do
|
70
71
|
req = @request_factory.get( '/service/user/estark' )
|
71
72
|
@app.new.handle( req )
|
@@ -80,6 +81,13 @@ describe Strelka::App::Negotiation do
|
|
80
81
|
should include( Strelka::HTTPResponse::Negotiation )
|
81
82
|
end
|
82
83
|
|
84
|
+
it "adds custom content-type transforms to outgoing responses" do
|
85
|
+
req = @request_factory.get( '/service/user/astark', :accept => 'text/x-tnetstring' )
|
86
|
+
res = @app.new.handle( req )
|
87
|
+
res.content_type.should == 'text/x-tnetstring'
|
88
|
+
res.body.read.should == '28:2:an,19:5:array,8:of stuff,}]'
|
89
|
+
end
|
90
|
+
|
83
91
|
end
|
84
92
|
|
85
93
|
|
@@ -63,11 +63,11 @@ describe Strelka::HTTPResponse::Negotiation do
|
|
63
63
|
it "can provide blocks for bodies of several different mediatypes" do
|
64
64
|
@req.headers.accept = 'application/x-yaml, application/json; q=0.7, text/xml; q=0.2'
|
65
65
|
|
66
|
-
@res.for( 'application/json' ) {
|
67
|
-
@res.for( 'application/x-yaml' ) { "
|
66
|
+
@res.for( 'application/json' ) { ["a JSON dump"] }
|
67
|
+
@res.for( 'application/x-yaml' ) { { 'a' => "YAML dump" } }
|
68
68
|
|
69
69
|
@res.negotiated_body.rewind
|
70
|
-
@res.negotiated_body.read.should == "---\na: YAML dump\n
|
70
|
+
@res.negotiated_body.read.should == "---\na: YAML dump\n"
|
71
71
|
@res.content_type.should == "application/x-yaml"
|
72
72
|
@res.header_data.should =~ /accept(?!-)/i
|
73
73
|
end
|
@@ -100,6 +100,12 @@ describe Strelka::HTTPResponse::Negotiation do
|
|
100
100
|
@res.header_data.should =~ /accept(?!-)/i
|
101
101
|
end
|
102
102
|
|
103
|
+
it "raises an exception if given a block for an unknown symbolic mediatype" do
|
104
|
+
expect {
|
105
|
+
@res.for( :yaquil ) {}
|
106
|
+
}.to raise_error( StandardError, /no known mimetype/i )
|
107
|
+
end
|
108
|
+
|
103
109
|
end
|
104
110
|
|
105
111
|
|
@@ -132,7 +138,7 @@ describe Strelka::HTTPResponse::Negotiation do
|
|
132
138
|
@res.body = File.open( __FILE__, 'r:iso-8859-5' )
|
133
139
|
@res.content_type = 'text/plain'
|
134
140
|
|
135
|
-
@res.negotiated_body.encoding.should == Encoding::KOI8_R
|
141
|
+
@res.negotiated_body.read.encoding.should == Encoding::KOI8_R
|
136
142
|
@res.header_data.should =~ /accept-charset(?!-)/i
|
137
143
|
end
|
138
144
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strelka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0.pre.393
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
6mKCwjpegytE0oifXfF8k75A9105cBnNiMZOe1tXiqYc/exCgWvbggurzDOcRkZu
|
31
31
|
/YSusaiDXHKU2O3Akc3htA==
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2013-
|
33
|
+
date: 2013-05-02 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: configurability
|
@@ -122,14 +122,14 @@ dependencies:
|
|
122
122
|
requirements:
|
123
123
|
- - ~>
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: '0.
|
125
|
+
version: '0.2'
|
126
126
|
type: :runtime
|
127
127
|
prerelease: false
|
128
128
|
version_requirements: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
130
|
- - ~>
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version: '0.
|
132
|
+
version: '0.2'
|
133
133
|
- !ruby/object:Gem::Dependency
|
134
134
|
name: sysexits
|
135
135
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
Binary file
|