skypager 2.1.0 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/skypager.rb +5 -0
- data/lib/skypager/protector.rb +87 -0
- data/lib/skypager/proxy.rb +29 -30
- data/lib/skypager/version.rb +1 -1
- data/skypager.gemspec +1 -0
- data/spec/interface/protector_spec.rb +6 -0
- data/spec/spec_helper.rb +0 -0
- metadata +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b58af966708284b603f3b068b4ab53a189a26f0
|
4
|
+
data.tar.gz: d6b27bfb6058d82621d9049ef13e8cbef4d307d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a0045b02510e64763469763600d4c5cc2b74abd714c60657a3cd40a9870caf282d01c47e1f62705126673492c4e23ba5424b87bc5c2a56df12a8a80ad0f787d
|
7
|
+
data.tar.gz: 420e672d05b052513ce0bed3afd1e7a40eef7ac3247fc4abc696cadfcb2e7d4cc9670a988d08cad3810fb1f30f6c194f4821b69476464c429d2ba0facd533f8a
|
data/lib/skypager.rb
CHANGED
@@ -12,9 +12,14 @@ require 'active_support/core_ext/string'
|
|
12
12
|
|
13
13
|
module Skypager
|
14
14
|
def self.router(app, options={})
|
15
|
+
require 'skypager/router'
|
15
16
|
@router ||= Skypager::Router.new(app, options)
|
16
17
|
end
|
17
18
|
|
19
|
+
def self.protector(options={})
|
20
|
+
Skypager::Protector.new(options)
|
21
|
+
end
|
22
|
+
|
18
23
|
def self.proxy(options={})
|
19
24
|
if options.is_a?(String)
|
20
25
|
options = {bucket: options}
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# This app should check for the presence of certain
|
2
|
+
# cookies, and optionally validate their values.
|
3
|
+
#
|
4
|
+
# It should either show a login page, or the requested path
|
5
|
+
module Skypager
|
6
|
+
class Protector
|
7
|
+
attr_accessor :validator, :options
|
8
|
+
|
9
|
+
# Skypager::Protector.new(options) do |request|
|
10
|
+
# # validate request here
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Valid options are:
|
14
|
+
# - build_dir: defaults to ./build
|
15
|
+
# - login_path: defaults to /login/index.html
|
16
|
+
# - not_found_path: defaults to /not-found.html
|
17
|
+
def initialize(options={}, &validator)
|
18
|
+
@options = options
|
19
|
+
@validator = validator
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
request = Rack::Request.new(env)
|
24
|
+
|
25
|
+
if !validate(request)
|
26
|
+
serve_login_path
|
27
|
+
end
|
28
|
+
|
29
|
+
path = normalize_path(request.path)
|
30
|
+
file = build_path.join(path)
|
31
|
+
|
32
|
+
binding.pry
|
33
|
+
|
34
|
+
if file.exist?
|
35
|
+
serve_file(file)
|
36
|
+
else
|
37
|
+
serve_not_found_path
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def serve_file(file)
|
42
|
+
mime_type = Rack::Mime.mime_type(Pathname(file).extname).to_s
|
43
|
+
content = Pathname(file).read.to_s
|
44
|
+
content_length = content.size.to_s
|
45
|
+
|
46
|
+
[200, {"Content-Type" => mime_type,"Content-Length" => content_length}, [content]]
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_path
|
50
|
+
build_dir = options.fetch(:build_dir) { Pathname(Dir.pwd).join('build') }
|
51
|
+
Pathname(build_dir)
|
52
|
+
end
|
53
|
+
|
54
|
+
def serve_not_found_path
|
55
|
+
not_found_path = options.fetch(:not_found_path, "/not-found.html")
|
56
|
+
[404, {"Content-Type" => "text/html"}, [not_found_path.read]]
|
57
|
+
end
|
58
|
+
|
59
|
+
def serve_login_path
|
60
|
+
login_path = options.fetch(:login_path, "/login.html")
|
61
|
+
[302, {"Content-Type" => "text/html", "Location" => login_path}, ["302 You've been redirected"]]
|
62
|
+
end
|
63
|
+
|
64
|
+
def normalize_path(path)
|
65
|
+
if !path.to_s.match(/\.\w+/)
|
66
|
+
path = path.gsub(/\/$/,'') + path_extension
|
67
|
+
end
|
68
|
+
|
69
|
+
path.to_s.gsub(/^\//,'')
|
70
|
+
end
|
71
|
+
|
72
|
+
def path_extension
|
73
|
+
options.fetch(:path_extension ) do
|
74
|
+
options[:directory_indexes] ? "/index.html" : ".html"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
def validate(request)
|
78
|
+
return true if validator.nil? || !validator.respond_to?(:call)
|
79
|
+
|
80
|
+
validator.call({
|
81
|
+
cookies: request.cookies,
|
82
|
+
params: request.params,
|
83
|
+
env: request.env
|
84
|
+
})
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/skypager/proxy.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# Based on the s3_proxy gem
|
2
|
-
|
3
|
-
require 'aws-sdk-core'
|
4
|
-
require 'stringio'
|
5
|
-
|
2
|
+
require 'rack/proxy'
|
6
3
|
module Skypager
|
7
4
|
class Proxy
|
8
5
|
|
@@ -14,8 +11,6 @@ module Skypager
|
|
14
11
|
def initialize(options={})
|
15
12
|
@options = options
|
16
13
|
@bucket = options[:bucket]
|
17
|
-
@access_key_id = options.fetch(:access_key_id) { Skypager.config.aws_access_key_id }
|
18
|
-
@secret_access_key = options.fetch(:secret_access_key) { Skypager.config.aws_secret_access_key }
|
19
14
|
end
|
20
15
|
|
21
16
|
def call(env)
|
@@ -31,7 +26,7 @@ module Skypager
|
|
31
26
|
end
|
32
27
|
|
33
28
|
def s3
|
34
|
-
|
29
|
+
Datapimp::Sync.amazon.storage
|
35
30
|
end
|
36
31
|
|
37
32
|
def request_proxy
|
@@ -41,12 +36,12 @@ module Skypager
|
|
41
36
|
|
42
37
|
def s3_call(env)
|
43
38
|
return Errors.method_not_allowed unless %w(GET HEAD).include?(env['REQUEST_METHOD'])
|
44
|
-
return Errors.not_found if env['PATH_INFO'].empty?
|
39
|
+
return Errors.not_found('path_info') if env['PATH_INFO'].empty?
|
45
40
|
|
46
41
|
rack_request = Rack::Request.new(env)
|
47
42
|
key = "#{rack_request.path}".without_leading_slash
|
48
43
|
|
49
|
-
return Errors.not_found unless bucket && key
|
44
|
+
return Errors.not_found('no-bucket-no-key') unless bucket && key
|
50
45
|
|
51
46
|
path = key.without_leading_slash
|
52
47
|
last = path.split("/").last
|
@@ -55,14 +50,18 @@ module Skypager
|
|
55
50
|
|
56
51
|
req[:key] = "index.html" if req[:key].to_s.length == 0
|
57
52
|
|
58
|
-
req[
|
59
|
-
req[
|
60
|
-
req[
|
61
|
-
req[
|
53
|
+
req['If-Match'] = env['HTTP_IF_MATCH'] if env['HTTP_IF_MATCH']
|
54
|
+
req['If-None-Match'] = env['HTTP_IF_NONE_MATCH'] if env['HTTP_IF_NONE_MATCH']
|
55
|
+
req['If-Modified-Since'] = env['HTTP_IF_MODIFIED_SINCE'] if env['HTTP_IF_MODIFIED_SINCE']
|
56
|
+
req['If-Unmodified-Since'] = env['HTTP_IF_UNMODIFIED_SINCE'] if env['HTTP_UNMODIFIED_SINCE']
|
62
57
|
|
63
|
-
|
58
|
+
begin
|
59
|
+
head = s3.head_object(bucket, key, req)
|
60
|
+
rescue => e
|
61
|
+
return Errors.not_found('could not head ' + bucket.to_s + ' ' + key.to_s + ' ' + e.message)
|
62
|
+
end
|
64
63
|
|
65
|
-
return Errors.not_found unless head
|
64
|
+
return Errors.not_found('no-head') unless head
|
66
65
|
|
67
66
|
case env['REQUEST_METHOD']
|
68
67
|
when 'HEAD'
|
@@ -75,13 +74,13 @@ module Skypager
|
|
75
74
|
end
|
76
75
|
end
|
77
76
|
|
78
|
-
rescue
|
79
|
-
return Errors.not_found
|
77
|
+
rescue Excon::Errors::NotFound
|
78
|
+
return Errors.not_found('rescue')
|
80
79
|
|
81
|
-
rescue
|
80
|
+
rescue Excon::Errors::NotModified
|
82
81
|
return Errors.not_modified
|
83
82
|
|
84
|
-
rescue
|
83
|
+
rescue Excon::Errors::PreconditionFailed
|
85
84
|
return Errors.precondition_failed
|
86
85
|
|
87
86
|
rescue NameError => e
|
@@ -101,10 +100,10 @@ module Skypager
|
|
101
100
|
io.write "HTTP/1.1 200 OK\r\n"
|
102
101
|
io.write "Status: 200\r\n"
|
103
102
|
io.write "Connection: close\r\n"
|
104
|
-
io.write "Content-Type: #{head.
|
105
|
-
io.write "Content-Length: #{head.
|
106
|
-
io.write "ETag: #{head.
|
107
|
-
io.write "Last-Modified: #{head.
|
103
|
+
io.write "Content-Type: #{head.headers['Content-Type']}\r\n"
|
104
|
+
io.write "Content-Length: #{head.headers['Content-Length']}\r\n"
|
105
|
+
io.write "ETag: #{head.headers['ETag']}\r\n"
|
106
|
+
io.write "Last-Modified: #{head.headers['Last-Modified']}\r\n"
|
108
107
|
io.write "\r\n"
|
109
108
|
io.flush
|
110
109
|
|
@@ -119,7 +118,7 @@ module Skypager
|
|
119
118
|
case env['REQUEST_METHOD']
|
120
119
|
when 'GET'
|
121
120
|
fiber = Fiber.new do
|
122
|
-
s3.get_object(request) do |chunk|
|
121
|
+
s3.get_object(request[:bucket], request[:key], request) do |chunk|
|
123
122
|
Fiber.yield(chunk)
|
124
123
|
end
|
125
124
|
Fiber.yield(nil)
|
@@ -135,10 +134,10 @@ module Skypager
|
|
135
134
|
end
|
136
135
|
|
137
136
|
headers = {
|
138
|
-
'Content-Type' => head.
|
139
|
-
'Content-Length' => head.
|
140
|
-
'Last-Modified' => head.
|
141
|
-
'ETag' => head.
|
137
|
+
'Content-Type' => head.headers['Content-Type'].to_s,
|
138
|
+
'Content-Length' => head.headers['Content-Length'].to_s,
|
139
|
+
'Last-Modified' => head.headers['Last-Modified'].to_s,
|
140
|
+
'ETag' => head.headers['ETag'].to_s,
|
142
141
|
}
|
143
142
|
|
144
143
|
[200, headers, body]
|
@@ -150,8 +149,8 @@ module Skypager
|
|
150
149
|
[405, {'Content-Type' => 'text/plain'}, ["method not allowed"]]
|
151
150
|
end
|
152
151
|
|
153
|
-
def not_found
|
154
|
-
[404, {'Content-Type' => 'text/plain'}, [
|
152
|
+
def not_found(reason="not found man")
|
153
|
+
[404, {'Content-Type' => 'text/plain'}, [reason.to_s]]
|
155
154
|
end
|
156
155
|
|
157
156
|
def forbidden
|
data/lib/skypager/version.rb
CHANGED
data/skypager.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency 'activesupport', '>= 3.0.0'
|
26
26
|
spec.add_dependency 'uri_template'
|
27
27
|
spec.add_dependency 'rack-proxy'
|
28
|
+
spec.add_dependency 'datapimp', '>= 1.1.1'
|
28
29
|
|
29
30
|
spec.add_development_dependency "bundler", "~> 1.3"
|
30
31
|
spec.add_development_dependency "rake", '~> 0'
|
data/spec/spec_helper.rb
ADDED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skypager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Soeder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: datapimp
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.1.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.1.1
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: bundler
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -215,12 +229,15 @@ files:
|
|
215
229
|
- lib/skypager/cli/config.rb
|
216
230
|
- lib/skypager/configuration.rb
|
217
231
|
- lib/skypager/core_ext.rb
|
232
|
+
- lib/skypager/protector.rb
|
218
233
|
- lib/skypager/proxy.rb
|
219
234
|
- lib/skypager/router.rb
|
220
235
|
- lib/skypager/site.rb
|
221
236
|
- lib/skypager/tar.rb
|
222
237
|
- lib/skypager/version.rb
|
223
238
|
- skypager.gemspec
|
239
|
+
- spec/interface/protector_spec.rb
|
240
|
+
- spec/spec_helper.rb
|
224
241
|
homepage: http://skypager.io
|
225
242
|
licenses:
|
226
243
|
- MIT
|
@@ -246,5 +263,7 @@ signing_key:
|
|
246
263
|
specification_version: 4
|
247
264
|
summary: Skypager lets people collaborate on advanced, dynamic sites using simple
|
248
265
|
familiar tools
|
249
|
-
test_files:
|
266
|
+
test_files:
|
267
|
+
- spec/interface/protector_spec.rb
|
268
|
+
- spec/spec_helper.rb
|
250
269
|
has_rdoc:
|