angelo 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/Gemfile +1 -0
- data/angelo.gemspec +1 -0
- data/lib/angelo/base.rb +6 -1
- data/lib/angelo/rspec/helpers.rb +1 -1
- data/lib/angelo/server.rb +59 -1
- data/lib/angelo/version.rb +1 -1
- data/lib/angelo.rb +10 -0
- data/spec/angelo/erb_spec.rb +1 -3
- data/spec/angelo/mustermann_spec.rb +1 -3
- data/spec/angelo/static_spec.rb +59 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/test_app_root/public/test.css +6 -0
- data/spec/test_app_root/public/test.html +1 -0
- data/spec/test_app_root/public/test.js +1 -0
- data/spec/test_app_root/public/what.png +0 -0
- data/spec/{angelo → test_app_root}/views/index.html.erb +0 -0
- data/spec/{angelo → test_app_root}/views/layout.html.erb +0 -0
- metadata +30 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 667a3b95c269095d00f41d03cadfe1e3cc40f404
|
4
|
+
data.tar.gz: 9143b9fee78b9b06591516f147a29ce147169447
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85107d56bb0446a5611a53eec5fd91b737f5e27362345bd9d87370d7183639da3254aa3101709297f9c7fcd90d15563e597de418255fcf14090a5bbb7b91c369
|
7
|
+
data.tar.gz: 8e248165128d31c5f4e891cf74d7508d982fc9798def4fea2fa022e6bf24fbcf77ce87b5d6b12c7e3e1eeef071bf24f123064386433ebbf03d1199b5c285fa3e
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
### 0.1.2 5 mar 2014 burnout, denial
|
5
|
+
|
6
|
+
* basic static file support (i.e. /public files)
|
7
|
+
* basic ETag/If-None-Match support
|
8
|
+
|
9
|
+
### 0.1.1 3 mar 2014
|
10
|
+
|
11
|
+
* fix for params with no Content-Type header
|
12
|
+
|
13
|
+
### 0.1.0 24 feb 2014
|
14
|
+
|
15
|
+
* fix for socket paths with mustermann
|
16
|
+
* sorta common log-ish-ness
|
17
|
+
|
4
18
|
### 0.0.9 20 feb 2014
|
5
19
|
|
6
20
|
* memoize params
|
data/Gemfile
CHANGED
data/angelo.gemspec
CHANGED
data/lib/angelo/base.rb
CHANGED
@@ -32,10 +32,15 @@ module Angelo
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def subclass.view_dir
|
35
|
-
v = self.class_variable_get(:@@views) rescue
|
35
|
+
v = self.class_variable_get(:@@views) rescue DEFAULT_VIEW_DIR
|
36
36
|
File.join root, v
|
37
37
|
end
|
38
38
|
|
39
|
+
def subclass.public_dir
|
40
|
+
p = self.class_variable_get(:@@public_dir) rescue DEFAULT_PUBLIC_DIR
|
41
|
+
File.join root, p
|
42
|
+
end
|
43
|
+
|
39
44
|
end
|
40
45
|
|
41
46
|
def compile! name, &block
|
data/lib/angelo/rspec/helpers.rb
CHANGED
data/lib/angelo/server.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
1
3
|
module Angelo
|
2
4
|
|
3
5
|
class Server < Reel::Server
|
@@ -14,13 +16,21 @@ module Angelo
|
|
14
16
|
# RubyProf.resume
|
15
17
|
connection.each_request do |request|
|
16
18
|
meth = request.websocket? ? :socket : request.method.downcase.to_sym
|
17
|
-
|
19
|
+
dispatch! meth, connection, request
|
18
20
|
end
|
19
21
|
# RubyProf.pause
|
20
22
|
end
|
21
23
|
|
22
24
|
private
|
23
25
|
|
26
|
+
def dispatch! meth, connection, request
|
27
|
+
if staticable?(meth) and lp = local_path(request.path)
|
28
|
+
static! meth, connection, request, lp
|
29
|
+
else
|
30
|
+
route! meth, connection, request
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
24
34
|
def route! meth, connection, request
|
25
35
|
rs = @base.routes[meth][request.path]
|
26
36
|
if rs
|
@@ -34,6 +44,54 @@ module Angelo
|
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
47
|
+
def local_path path
|
48
|
+
if @base.public_dir
|
49
|
+
lp = File.join(@base.public_dir, path)
|
50
|
+
File.file?(lp) ? lp : nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def staticable? meth
|
55
|
+
STATICABLE.include? meth
|
56
|
+
end
|
57
|
+
|
58
|
+
def static! meth, connection, request, local_path
|
59
|
+
etag = etag_for local_path
|
60
|
+
if request.headers[IF_NONE_MATCH_HEADER_KEY] == etag
|
61
|
+
Angelo.log connection, request, nil, :not_modified, 0
|
62
|
+
connection.respond :not_modified
|
63
|
+
else
|
64
|
+
headers = {
|
65
|
+
|
66
|
+
# Content-Type
|
67
|
+
#
|
68
|
+
CONTENT_TYPE_HEADER_KEY =>
|
69
|
+
(MIME::Types.type_for(File.extname(local_path))[0].content_type rescue HTML_TYPE),
|
70
|
+
|
71
|
+
# Content-Disposition
|
72
|
+
#
|
73
|
+
CONTENT_DISPOSITION_HEADER_KEY =>
|
74
|
+
DEFAULT_CONTENT_DISPOSITION + "; filename=#{File.basename local_path}",
|
75
|
+
|
76
|
+
# Content-Length
|
77
|
+
#
|
78
|
+
CONTENT_LENGTH_HEADER_KEY => File.size(local_path),
|
79
|
+
|
80
|
+
# ETag
|
81
|
+
#
|
82
|
+
ETAG_HEADER_KEY => etag
|
83
|
+
|
84
|
+
}
|
85
|
+
Angelo.log connection, request, nil, :ok, headers[CONTENT_LENGTH_HEADER_KEY]
|
86
|
+
connection.respond :ok, headers, (meth == :head ? nil : File.read(local_path))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def etag_for local_path
|
91
|
+
fs = File::Stat.new local_path
|
92
|
+
OpenSSL::Digest::SHA.hexdigest fs.ino.to_s + fs.size.to_s + fs.mtime.to_s
|
93
|
+
end
|
94
|
+
|
37
95
|
end
|
38
96
|
|
39
97
|
end
|
data/lib/angelo/version.rb
CHANGED
data/lib/angelo.rb
CHANGED
@@ -16,16 +16,26 @@ module Angelo
|
|
16
16
|
|
17
17
|
ROUTABLE = [:get, :post, :put, :delete, :socket]
|
18
18
|
HTTPABLE = [:get, :post, :put, :delete]
|
19
|
+
STATICABLE = [:get, :head]
|
19
20
|
|
20
21
|
CONTENT_TYPE_HEADER_KEY = 'Content-Type'
|
22
|
+
CONTENT_DISPOSITION_HEADER_KEY = 'Content-Disposition'
|
23
|
+
CONTENT_LENGTH_HEADER_KEY = 'Content-Length'
|
24
|
+
DEFAULT_CONTENT_DISPOSITION = 'attachment'
|
25
|
+
ETAG_HEADER_KEY = 'ETag'
|
26
|
+
IF_NONE_MATCH_HEADER_KEY = 'If-None-Match'
|
21
27
|
|
22
28
|
HTML_TYPE = 'text/html'
|
23
29
|
JSON_TYPE = 'application/json'
|
24
30
|
FORM_TYPE = 'application/x-www-form-urlencoded'
|
31
|
+
FILE_TYPE = 'application/octet-stream'
|
25
32
|
|
26
33
|
DEFAULT_ADDR = '127.0.0.1'
|
27
34
|
DEFAULT_PORT = 4567
|
28
35
|
|
36
|
+
DEFAULT_VIEW_DIR = 'views'
|
37
|
+
DEFAULT_PUBLIC_DIR = 'public'
|
38
|
+
|
29
39
|
DEFAULT_RESPONSE_HEADERS = {
|
30
40
|
CONTENT_TYPE_HEADER_KEY => HTML_TYPE
|
31
41
|
}
|
data/spec/angelo/erb_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
require 'angelo/tilt/erb'
|
3
3
|
|
4
|
-
ROOT = File.expand_path '..', __FILE__
|
5
|
-
|
6
4
|
describe Angelo::Base do
|
7
5
|
describe Angelo::Tilt::ERB do
|
8
6
|
|
@@ -10,7 +8,7 @@ describe Angelo::Base do
|
|
10
8
|
|
11
9
|
include Angelo::Tilt::ERB
|
12
10
|
|
13
|
-
@root =
|
11
|
+
@root = TEST_APP_ROOT
|
14
12
|
|
15
13
|
def set_vars
|
16
14
|
@title = 'test'
|
@@ -3,8 +3,6 @@ if RUBY_VERSION =~ /^2\./
|
|
3
3
|
require_relative '../spec_helper'
|
4
4
|
require 'angelo/mustermann'
|
5
5
|
|
6
|
-
TILT_MM_TEST_ROOT = File.expand_path '..', __FILE__
|
7
|
-
|
8
6
|
describe Angelo::Mustermann do
|
9
7
|
|
10
8
|
describe 'pattern matching' do
|
@@ -63,7 +61,7 @@ if RUBY_VERSION =~ /^2\./
|
|
63
61
|
include Angelo::Tilt::ERB
|
64
62
|
include Angelo::Mustermann
|
65
63
|
|
66
|
-
@root =
|
64
|
+
@root = TEST_APP_ROOT
|
67
65
|
|
68
66
|
get '/:foo/things/:bar' do
|
69
67
|
@title = params[:foo]
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
describe Angelo::Server do
|
5
|
+
|
6
|
+
describe 'serving static files' do
|
7
|
+
|
8
|
+
let(:test_css_etag) do
|
9
|
+
fs = File::Stat.new File.join(TEST_APP_ROOT, 'public', 'test.css')
|
10
|
+
OpenSSL::Digest::SHA.hexdigest fs.ino.to_s + fs.size.to_s + fs.mtime.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
define_app do
|
14
|
+
|
15
|
+
@root = TEST_APP_ROOT
|
16
|
+
|
17
|
+
get '/test.html' do
|
18
|
+
'you should not see this'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'serves static files for gets' do
|
24
|
+
get '/test.css'
|
25
|
+
expect(last_response.status).to be(200)
|
26
|
+
expect(last_response.headers['Content-Type']).to eq('text/css')
|
27
|
+
expect(last_response.headers['Content-Disposition']).to eq('attachment; filename=test.css')
|
28
|
+
expect(last_response.headers['Content-Length']).to eq('116')
|
29
|
+
expect(last_response.headers['Etag']).to eq(test_css_etag)
|
30
|
+
expect(last_response.body.length).to be(116)
|
31
|
+
expect(last_response.body).to eq(File.read(File.join TEST_APP_ROOT, 'public', 'test.css'))
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'serves headers for static files on head' do
|
35
|
+
head '/test.css'
|
36
|
+
expect(last_response.status).to be(200)
|
37
|
+
expect(last_response.headers['Content-Type']).to eq('text/css')
|
38
|
+
expect(last_response.headers['Content-Disposition']).to eq('attachment; filename=test.css')
|
39
|
+
expect(last_response.headers['Content-Length']).to eq('116')
|
40
|
+
expect(last_response.headers['Etag']).to eq(test_css_etag)
|
41
|
+
expect(last_response.body.length).to be(0)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'serves static file over route' do
|
45
|
+
get '/test.html'
|
46
|
+
expect(last_response.status).to be(200)
|
47
|
+
expect(last_response.headers['Content-Type']).to eq('text/html')
|
48
|
+
expect(last_response.headers['Content-Disposition']).to eq('attachment; filename=test.html')
|
49
|
+
expect(last_response.body).to eq(File.read(File.join TEST_APP_ROOT, 'public', 'test.html'))
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'not modifieds when if-none-match matched etag' do
|
53
|
+
get '/test.css', {}, {'If-None-Match' => test_css_etag}
|
54
|
+
expect(last_response.status).to be(304)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
this is a different story
|
@@ -0,0 +1 @@
|
|
1
|
+
setTimeout(function(){ alert('hi'); }, 3000);
|
Binary file
|
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: angelo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenichi Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: reel
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mime-types
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
description: A Sinatra-esque DSL for Reel
|
28
42
|
email:
|
29
43
|
- kenichi.nakamura@gmail.com
|
@@ -51,11 +65,16 @@ files:
|
|
51
65
|
- spec/angelo/erb_spec.rb
|
52
66
|
- spec/angelo/mustermann_spec.rb
|
53
67
|
- spec/angelo/params_spec.rb
|
54
|
-
- spec/angelo/
|
55
|
-
- spec/angelo/views/layout.html.erb
|
68
|
+
- spec/angelo/static_spec.rb
|
56
69
|
- spec/angelo/websocket_spec.rb
|
57
70
|
- spec/angelo_spec.rb
|
58
71
|
- spec/spec_helper.rb
|
72
|
+
- spec/test_app_root/public/test.css
|
73
|
+
- spec/test_app_root/public/test.html
|
74
|
+
- spec/test_app_root/public/test.js
|
75
|
+
- spec/test_app_root/public/what.png
|
76
|
+
- spec/test_app_root/views/index.html.erb
|
77
|
+
- spec/test_app_root/views/layout.html.erb
|
59
78
|
homepage: https://github.com/kenichi/angelo
|
60
79
|
licenses:
|
61
80
|
- apache
|
@@ -84,9 +103,13 @@ test_files:
|
|
84
103
|
- spec/angelo/erb_spec.rb
|
85
104
|
- spec/angelo/mustermann_spec.rb
|
86
105
|
- spec/angelo/params_spec.rb
|
87
|
-
- spec/angelo/
|
88
|
-
- spec/angelo/views/layout.html.erb
|
106
|
+
- spec/angelo/static_spec.rb
|
89
107
|
- spec/angelo/websocket_spec.rb
|
90
108
|
- spec/angelo_spec.rb
|
91
109
|
- spec/spec_helper.rb
|
92
|
-
|
110
|
+
- spec/test_app_root/public/test.css
|
111
|
+
- spec/test_app_root/public/test.html
|
112
|
+
- spec/test_app_root/public/test.js
|
113
|
+
- spec/test_app_root/public/what.png
|
114
|
+
- spec/test_app_root/views/index.html.erb
|
115
|
+
- spec/test_app_root/views/layout.html.erb
|