strelka-cors 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 48fb286bb78b2e0b3b07f2882a1ea18b6f8a341d
4
+ data.tar.gz: 3f7e5b4603ddd26fdd2b6b08f2276084383c6337
5
+ SHA512:
6
+ metadata.gz: 25e395f533d5ffd157fcad3bbf70bb5cfa40d7481b25eb2229f46428164e0155a0b1f2a7c5109b8197b9e6b793d8c9fce0d6b50d90b734bebf7e52db9497bb91
7
+ data.tar.gz: 765eb6ca99a5653c3d630919b6b28c853bc9aa7b50c73cb70738a0e6a1e571ef781de0e5400420b4efa07efab6b28f32f30b7a9efb8a9511cf73cb5022621e70
Binary file
Binary file
@@ -0,0 +1,52 @@
1
+ 2016-11-03 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * History.md:
4
+ Update history.
5
+ [7f93206d73ef] [tip]
6
+
7
+ * certs/ged.pem, strelka-cors.gemspec:
8
+ Add my gem cert and update the gemspec.
9
+ [3b0e5784e4c1]
10
+
11
+ * .hgignore, .hoerc, History.md, Manifest.txt, README.md, data
12
+ /strelka-cors/apps/cors-demo, data/strelka-
13
+ cors/templates/layout.tmpl, data/strelka-cors/templates/top.tmpl,
14
+ lib/strelka/app/cors.rb, lib/strelka/cors.rb,
15
+ lib/strelka/httpresponse/cors.rb, spec/strelka/app/cors_spec.rb,
16
+ spec/strelka/cors_spec.rb, spec/strelka/httpresponse/cors_spec.rb:
17
+ Finish up initial implementation.
18
+ [608d8c7cdb47] [github/master]
19
+
20
+ 2016-07-27 Michael Granger <ged@FaerieMUD.org>
21
+
22
+ * .gems, .hgignore, .ruby-gemset, .ruby-version, .rvm.gems, .rvmrc,
23
+ History.md, History.rdoc, README.md, README.rdoc, Rakefile,
24
+ lib/strelka/app/cors.rb, lib/strelka/cors.rb,
25
+ lib/strelka/httprequest/cors.rb, lib/strelka/httpresponse/cors.rb,
26
+ spec/strelka/app/cors_spec.rb,
27
+ spec/strelka/httprequest/cors_spec.rb,
28
+ spec/strelka/httpresponse/cors_spec.rb:
29
+ Flesh out the API, add request/response convenience method
30
+ [d9d38f5b5817]
31
+
32
+ 2014-02-27 Michael Granger <ged@FaerieMUD.org>
33
+
34
+ * README.rdoc:
35
+ Add a project status note to the README
36
+ [70c8b19774a9]
37
+
38
+ * .rvm.gems, .rvmrc, README.rdoc, cors_server_flowchart.png,
39
+ lib/strelka/app/cors.rb, lib/strelka/cors.rb,
40
+ lib/strelka/httprequest/cors.rb, spec/helpers.rb,
41
+ spec/strelka/app/cors_spec.rb, spec/strelka/cors_spec.rb:
42
+ Started work
43
+ [516a648b0100]
44
+
45
+ 2013-09-10 Michael Granger <ged@FaerieMUD.org>
46
+
47
+ * .tm_properties, History.rdoc, Manifest.txt, README.rdoc, Rakefile,
48
+ data/strelka-cors/apps/cors-demo, data/strelka-
49
+ cors/templates/layout.tmpl, data/strelka-cors/templates/top.tmpl,
50
+ lib/strelka/cors.rb, spec/strelka/cors_spec.rb:
51
+ Initial project setup
52
+ [dbe7b7b1a374]
@@ -0,0 +1,4 @@
1
+ ## v0.0.1 [2016-11-03] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Initial release.
4
+
@@ -0,0 +1,14 @@
1
+ ChangeLog
2
+ History.md
3
+ Manifest.txt
4
+ README.md
5
+ Rakefile
6
+ lib/strelka/app/cors.rb
7
+ lib/strelka/cors.rb
8
+ lib/strelka/httprequest/cors.rb
9
+ lib/strelka/httpresponse/cors.rb
10
+ spec/helpers.rb
11
+ spec/strelka/app/cors_spec.rb
12
+ spec/strelka/cors_spec.rb
13
+ spec/strelka/httprequest/cors_spec.rb
14
+ spec/strelka/httpresponse/cors_spec.rb
@@ -0,0 +1,134 @@
1
+ # strelka-cors
2
+
3
+ home
4
+ : http://deveiate.org/projects/Strelka-CORS
5
+
6
+ code
7
+ : http://bitbucket.org/ged/strelka-cors
8
+
9
+ github
10
+ : https://github.com/ged/strelka-cors
11
+
12
+ docs
13
+ : http://deveiate.org/code/strelka-cors
14
+
15
+
16
+ ## Description
17
+
18
+ This is a Strelka application plugin for describing rules for [Cross-Origin Resource Sharing (CORS)](http://www.w3.org/TR/cors/).
19
+
20
+ NOTE: It's still a work in progress.
21
+
22
+ By default, the plugin has paranoid defaults, and doesn't do anything. You'll need to grant access to the resources you want to share.
23
+
24
+ To grant access, you declare one or more `access_control` blocks which can modify responses to matching access-control requests. All the blocks which match the incoming request's URI are called with the request and response objects in the order in which they're declared:
25
+
26
+ # Allow access to all resources from any origin by default
27
+ access_control do |req, res|
28
+ res.allow_origin '*'
29
+ res.allow_methods 'GET', 'POST'
30
+ res.allow_credentials
31
+ res.allow_headers :content_type
32
+ end
33
+
34
+
35
+ These are applied in the order you declare them, with each matching block passed the request if it matches. This happens before the application gets the request, so it can do any further modification it needs to, and so it can block requests from disallowed origins/methods/etc.
36
+
37
+ There are a number of helper methods added to the request and response objects for applying and declaring access-control rules when this plugin is loaded:
38
+
39
+
40
+ ### `HTTPResponse#allow_origin <origin>+`
41
+
42
+ The `origin` parameter specifies a URI that may access the resource by setting the `Access-Control-Allow-Origin` header.
43
+
44
+ access_control do |req, res|
45
+ res.allow_origin 'http://acme.com/', 'http://www.acme.com/
46
+ res.allow_origin( req.origin )
47
+ res.allow_origin # same as above
48
+ res.allow_origin '*'
49
+ end
50
+
51
+
52
+ ### `HTTPResponse#expose_headers`
53
+ Specify a whitelist of headers that browsers are allowed to access by setting the `Access-Control-Expose-Headers` header on responses.
54
+
55
+ response.expose_headers :content_type, 'x-custom-header'
56
+
57
+
58
+ ### `HTTPResponse#access_control_max_age`
59
+
60
+ Specify how long the results of a preflight request can be cached by setting the `Access-Control-Max-Age` header.
61
+
62
+
63
+ ### `HTTPResponse#allow_credentials`
64
+
65
+ Specify whether or not a request can be made using credentials by setting the `Access-Control-Allow-Credentials` header on responses.
66
+
67
+
68
+ ### `HTTPResponse#allow_methods`
69
+
70
+ Specifies the method or methods allowed when accessing the resource by setting the `Access-Control-Allow-Methods` header on responses.
71
+
72
+
73
+ ### `HTTPResponse#allow_headers`
74
+
75
+ Specify the HTTP headers that can be used when making a request.
76
+
77
+
78
+
79
+
80
+
81
+ ### Allow All Simple Requests
82
+
83
+ If you just want to allow simple (GET, HEAD, POST) requests to your application
84
+ from any origin, you can do it like so:
85
+
86
+ require 'strelka/app'
87
+
88
+ class MyApp < Strelka::App
89
+ plugin :cors
90
+ allow_origins '*'
91
+
92
+ # The rest of your app
93
+
94
+ end
95
+
96
+ This will add the appropriate header to outgoing responses.
97
+
98
+
99
+ ## Installation
100
+
101
+ gem install strelka-cors
102
+
103
+
104
+ ## License
105
+
106
+ Copyright (c) 2015-2016, Michael Granger
107
+ All rights reserved.
108
+
109
+ Redistribution and use in source and binary forms, with or without
110
+ modification, are permitted provided that the following conditions are met:
111
+
112
+ * Redistributions of source code must retain the above copyright notice,
113
+ this list of conditions and the following disclaimer.
114
+
115
+ * Redistributions in binary form must reproduce the above copyright notice,
116
+ this list of conditions and the following disclaimer in the documentation
117
+ and/or other materials provided with the distribution.
118
+
119
+ * Neither the name of the author/s, nor the names of the project's
120
+ contributors may be used to endorse or promote products derived from this
121
+ software without specific prior written permission.
122
+
123
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
124
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
125
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
127
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
128
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
129
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
130
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
131
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
132
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133
+
134
+
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env rake
2
+
3
+ begin
4
+ require 'hoe'
5
+ rescue LoadError
6
+ abort "This Rakefile requires hoe (gem install hoe)"
7
+ end
8
+
9
+ GEMSPEC = 'strelka-cors.gemspec'
10
+
11
+
12
+ Hoe.plugin :mercurial
13
+ Hoe.plugin :signing
14
+ Hoe.plugin :deveiate
15
+
16
+
17
+ hoespec = Hoe.spec 'strelka-cors' do |spec|
18
+ spec.readme_file = 'README.md'
19
+ spec.history_file = 'History.md'
20
+ spec.extra_rdoc_files = FileList[ '*.rdoc', '*.md' ]
21
+ spec.license 'BSD-3-Clause'
22
+ spec.urls = {
23
+ home: 'http://deveiate.org/projects/strelka-cors',
24
+ code: 'http://bitbucket.org/ged/strelka-cors',
25
+ docs: 'http://deveiate.org/code/strelka-cors',
26
+ github: 'http://github.com/ged/strelka-cors',
27
+ }
28
+
29
+ spec.developer 'Michael Granger', 'ged@FaerieMUD.org'
30
+
31
+ spec.dependency 'strelka', '~> 0.11'
32
+
33
+ spec.dependency 'rspec', '~> 3.2', :developer
34
+ spec.dependency 'simplecov', '~> 0.9', :developer
35
+ spec.dependency 'timecop', '~> 0.7', :developer
36
+
37
+ spec.require_ruby_version( '>=2.2.0' )
38
+ spec.hg_sign_tags = true if spec.respond_to?( :hg_sign_tags= )
39
+
40
+ spec.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
41
+ end
42
+
43
+
44
+ ENV['VERSION'] ||= hoespec.spec.version.to_s
45
+
46
+ # Run the tests before checking in
47
+ task 'hg:precheckin' => [ :check_history, :check_manifest, :gemspec, :spec ]
48
+
49
+ # Rebuild the ChangeLog immediately before release
50
+ task :prerelease => 'ChangeLog'
51
+ CLOBBER.include( 'ChangeLog' )
52
+
53
+ desc "Build a coverage report"
54
+ task :coverage do
55
+ ENV["COVERAGE"] = 'yes'
56
+ Rake::Task[:spec].invoke
57
+ end
58
+
59
+
60
+ # Use the fivefish formatter for docs generated from development checkout
61
+ if File.directory?( '.hg' )
62
+ require 'rdoc/task'
63
+
64
+ Rake::Task[ 'docs' ].clear
65
+ RDoc::Task.new( 'docs' ) do |rdoc|
66
+ rdoc.main = "README.md"
67
+ rdoc.rdoc_files.include( "*.rdoc", "*.md", "ChangeLog", "lib/**/*.rb" )
68
+ rdoc.generator = :fivefish
69
+ rdoc.title = 'Strelka-CORS'
70
+ rdoc.rdoc_dir = 'doc'
71
+ end
72
+ end
73
+
74
+ task :gemspec => [ 'ChangeLog', GEMSPEC ]
75
+ file GEMSPEC => __FILE__ do |task|
76
+ spec = $hoespec.spec
77
+ spec.files.delete( '.gemtest' )
78
+ spec.files.delete( 'LICENSE' )
79
+ spec.signing_key = nil
80
+ spec.version = "#{spec.version}.pre#{Time.now.strftime("%Y%m%d%H%M%S")}"
81
+ File.open( task.name, 'w' ) do |fh|
82
+ fh.write( spec.to_ruby )
83
+ end
84
+ end
85
+
86
+ task :default => :gemspec
87
+
@@ -0,0 +1,111 @@
1
+ # -*- ruby -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
4
+
5
+ require 'strelka/app' unless defined?( Strelka::App )
6
+ require 'strelka/httprequest/cors'
7
+ require 'strelka/httpresponse/cors'
8
+
9
+
10
+ # Strelka::App plugin module for Cross-Origin Resource Sharing (CORS)
11
+ #
12
+ # class MyService < Strelka::App
13
+ # plugins :cors
14
+ #
15
+ # allow_origins '*'
16
+ #
17
+ # end # MyService
18
+ #
19
+ # Resources:
20
+ #
21
+ # * http://www.w3.org/TR/cors/
22
+ # * http://enable-cors.org/server.html
23
+ # * http://www.html5rocks.com/en/tutorials/cors/
24
+ #
25
+ module Strelka::App::CORS
26
+ extend Strelka::Plugin
27
+
28
+ run_outside :routing, :restresources, :negotiation
29
+ run_inside :errors, :sessions, :auth
30
+
31
+
32
+ # Class methods to add to including applications
33
+ module ClassMethods
34
+
35
+ ### Extension hook. Add instance variables to extended classes.
36
+ def self::extended( mod )
37
+ mod.instance_variable_set( :@access_controls, [] )
38
+ end
39
+
40
+
41
+ ##
42
+ # An Array of access control tuples of the form:
43
+ # [ <uri_pattern>, <options_hash> ]
44
+ attr_reader :access_controls
45
+
46
+
47
+ ### Get/declare access control rules for requests whose app_path matches the specified
48
+ ### +uri_pattern+, and whose other attributes match the given +options+.
49
+ def access_control( uri_pattern=nil, **options, &block )
50
+ options[ :block ] = block if block
51
+ self.access_controls << [ uri_pattern, options ]
52
+ end
53
+ alias_method :cors_access_control, :access_control
54
+
55
+ end # module ClassMethods
56
+
57
+
58
+ ### Extension callback -- extend the HTTPRequest class with Auth
59
+ ### support when this plugin is loaded.
60
+ def self::included( object )
61
+ self.log.debug "Extending Request with CORS mixin"
62
+ Strelka::HTTPRequest.class_eval { include Strelka::HTTPRequest::CORS }
63
+ Strelka::HTTPResponse.class_eval { include Strelka::HTTPResponse::CORS }
64
+ super
65
+ end
66
+
67
+
68
+ ### Extend handled requests with CORS stuff.
69
+ def handle_request( request )
70
+ if request.origin
71
+ self.log.info "Request has an Origin (%p): applying CORS" % [ request.origin ]
72
+ response = if request.is_preflight?
73
+ self.log.debug "Preflight request for %s" % [ request.uri ]
74
+ self.handle_preflight_request( request )
75
+ else
76
+ request.response.add_cors_headers
77
+ super
78
+ end
79
+
80
+ return response
81
+ else
82
+ super
83
+ end
84
+ end
85
+
86
+
87
+ ### Handle a CORS preflight +request+.
88
+ def handle_preflight_request( request )
89
+ path = request.app_path
90
+ response = request.response
91
+
92
+ self.class.access_controls.each do |pattern, options|
93
+ self.log.debug "Applying access controls: %p (%p)" % [ pattern, options ]
94
+
95
+ # TODO: Skip requests that don't match options? E.g.,
96
+ # next unless options[:allowed_methods].include?( request.verb )
97
+
98
+ options[:block].call( request, response ) if
99
+ options[:block] && ( !pattern || path.match(pattern) )
100
+ end
101
+
102
+ response.add_cors_headers
103
+ response.status = 204
104
+
105
+ return response
106
+ end
107
+
108
+
109
+ end # module Strelka::App::CORS
110
+
111
+
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
4
+
5
+
6
+ require 'strelka' unless defined?( Strelka )
7
+
8
+
9
+ module Strelka::CORS
10
+
11
+ # The library version
12
+ VERSION = '0.0.1'
13
+
14
+ # Version control revision
15
+ REVISION = %q$Revision: 608d8c7cdb47 $
16
+
17
+
18
+ require 'strelka/app/cors'
19
+ require 'strelka/httprequest/cors'
20
+ require 'strelka/httpresponse/cors'
21
+
22
+ end # module Strelka::CORS
23
+
@@ -0,0 +1,55 @@
1
+ # -*- ruby -*-
2
+ #encoding: utf-8
3
+
4
+ require 'strelka/httprequest'
5
+
6
+
7
+ # The mixin that adds methods to Strelka::HTTPRequest for
8
+ # Cross-Origin Resource Sharing (CORS).
9
+ module Strelka::HTTPRequest::CORS
10
+
11
+
12
+ ### Add some instance variables to the request object.
13
+ def initialize( * ) # :notnew:
14
+ super
15
+ @origin = nil
16
+ end
17
+
18
+
19
+ ######
20
+ public
21
+ ######
22
+
23
+ ### Return the URI in the Origin header (if the request has one) as a
24
+ ### URI object. If the request doesn't have an Origin: header, returns
25
+ ### nil.
26
+ def origin
27
+ unless @origin
28
+ origin_uri = self.headers.origin or return nil
29
+ @origin = URI( origin_uri )
30
+ end
31
+
32
+ return @origin
33
+ end
34
+
35
+
36
+ ### Returns +true+ if the request contains an Origin header whose
37
+ ### URI has a host that's different than its Host: header.
38
+ def cross_origin?
39
+ return self.origin && self.headers.host != self.origin.host
40
+ end
41
+ alias_method :is_cross_origin?, :cross_origin?
42
+
43
+
44
+ ### Returns +true+ if the receiver is a CORS preflight request.
45
+ def preflight?
46
+ return self.origin &&
47
+ self.verb == :OPTIONS &&
48
+ self.header.access_control_request_method
49
+ end
50
+ alias_method :is_preflight?, :preflight?
51
+
52
+
53
+ end # module Strelka::HTTPRequest::CORS
54
+
55
+