Skip to content

Commit 683e58a

Browse files
committed
improve app layout dir resolution - e.g. FS public path should resolve app root relative
1 parent 2fd826b commit 683e58a

File tree

2 files changed

+76
-43
lines changed

2 files changed

+76
-43
lines changed

src/main/ruby/jruby/rack/app_layout.rb

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,52 +15,57 @@ module Rack
1515
# only need to accept a rack context in your initializer and
1616
# provide the three *_uri methods.
1717
class AppLayout
18-
19-
attr_reader :app_uri, :public_uri, :gem_uri
2018

2119
def initialize(rack_context)
2220
@rack_context = rack_context
2321
end
2422

25-
%w( app_path gem_path public_path ).each do |path|
26-
# def app_path; @app_path ||= real_path(app_uri); end
27-
# def app_path=(v); @app_path = v; end
28-
class_eval "def #{path}; @#{path} ||= real_path(#{path.sub('path', 'uri')}); end"
29-
class_eval "def #{path}=(path); @#{path} = path; end"
30-
end
23+
attr_reader :app_uri, :gem_uri, :public_uri
3124

32-
def real_path(path)
33-
if rpath = @rack_context.getRealPath(path)
25+
def app_path; @app_path ||= real_path(app_uri) end
26+
def gem_path; @gem_path ||= real_path(gem_uri) end
27+
def public_path; @public_path ||= real_path(public_uri) end
28+
29+
attr_writer :app_path, :gem_path, :public_path
30+
31+
def expand_path(path)
32+
if real_path = self.real_path(path)
3433
# protect windows paths from backrefs
35-
rpath.sub!(/\\([0-9])/, '\\\\\\\\\1')
36-
rpath.chomp!('/')
34+
real_path.sub!(/\\([0-9])/, '\\\\\\\\\1')
35+
real_path.chomp!('/')
3736
end
38-
rpath
37+
real_path
38+
end
39+
40+
def real_path(path)
41+
real_path = @rack_context.getRealPath(path)
42+
real_path.chomp!('/') if real_path
43+
real_path
3944
end
40-
45+
4146
end
4247

4348
class WebInfLayout < AppLayout
44-
49+
4550
def initialize(context)
4651
super
4752
$0 = File.join(app_path, 'web.xml')
4853
end
4954

5055
def app_uri
51-
@app_uri ||=
56+
@app_uri ||=
5257
@rack_context.getInitParameter('app.root') ||
5358
@rack_context.getInitParameter('rails.root') ||
5459
'/WEB-INF'
5560
end
56-
61+
5762
def gem_uri
5863
@gem_uri ||=
5964
@rack_context.getInitParameter('gem.path') ||
6065
@rack_context.getInitParameter('gem.home') ||
6166
'/WEB-INF/gems'
6267
end
63-
68+
6469
def public_uri
6570
@public_uri ||= begin
6671
path = @rack_context.getInitParameter('public.root') || '/'
@@ -70,26 +75,28 @@ def public_uri
7075
end
7176
end
7277

73-
def real_path(path)
74-
app_regex = Regexp.quote(app_uri) # app_uri = '/WEB-INF'
75-
if path =~ /^#{app_regex}\// # gem_path = '/WEB-INF/gems'
76-
path.sub(/^#{app_regex}/, app_path) # '[app_path]/gems'
78+
def expand_path(path)
79+
if path.start_with?(app_uri) # gem_path = '/WEB-INF/gems'
80+
path = path.dup; path[0, app_uri.size] = app_path; path # '[app_path]/gems'
81+
path
82+
elsif path[0, 1] != '/' # expand relative paths
83+
File.join(app_path, path)
7784
else
7885
super
7986
end
8087
end
81-
88+
8289
end
8390

8491
RailsWebInfLayout = WebInfLayout
8592

8693
# #deprecated will be removed (with Merb support)
8794
class MerbWebInfLayout < WebInfLayout
88-
95+
8996
def app_uri
9097
@app_uri ||= @rack_context.getInitParameter('merb.root') || '/WEB-INF'
9198
end
92-
99+
93100
end
94101

95102
class FileSystemLayout < AppLayout
@@ -106,20 +113,24 @@ def gem_uri
106113
@rack_context.getInitParameter('gem.path') ||
107114
@rack_context.getInitParameter('gem.home')
108115
end
109-
116+
110117
def public_uri
111118
@public_uri ||=
112-
@rack_context.getInitParameter('public.root') || './public'
119+
@rack_context.getInitParameter('public.root') || 'public'
113120
end
114121

115122
def real_path(path)
116-
path.nil? ? nil : File.expand_path(path)
123+
expand_path(super)
117124
end
118-
125+
126+
def expand_path(path)
127+
path.nil? ? nil : File.expand_path(path, app_uri)
128+
end
129+
119130
end
120-
131+
121132
RailsFileSystemLayout = FileSystemLayout
122133
RailsFilesystemLayout = FileSystemLayout # backwards compatibility
123-
134+
124135
end
125136
end

src/spec/ruby/jruby/rack/app_layout_spec.rb

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,27 @@
2929
it "defaults gem uri to /WEB-INF/gems" do
3030
expect( layout.gem_uri ).to eq '/WEB-INF/gems'
3131

32-
layout.stub(:app_uri).and_return '/WEB-INF'
32+
@rack_context.should_receive(:getRealPath).with("/WEB-INF/gems").and_return "/gems"
33+
3334
expect( layout.gem_path ).to eq '/gems'
3435
end
3536

3637
it "sets gem path based on gem.path context init param" do
3738
@rack_context.should_receive(:getInitParameter).with("gem.path").and_return "/WEB-INF/.gems"
3839
expect( layout.gem_uri ).to eq "/WEB-INF/.gems"
3940

40-
layout.instance_variable_set :@app_uri, "/WEB-INF"
41-
expect( layout.gem_path ).to eq "/.gems"
41+
@rack_context.should_receive(:getRealPath).with("/WEB-INF/.gems").and_return "file:/tmp/WEB-INF/.gems"
42+
43+
expect( layout.gem_path ).to eq "file:/tmp/WEB-INF/.gems"
4244
end
4345

4446
it "handles gem path correctly when app uri ends with /" do
47+
layout.instance_variable_set :@app_uri, "/WEB-INF/"
4548
layout.instance_variable_set :@gem_uri, "/WEB-INF/.gems"
46-
expect( layout.gem_path ).to eq "/.gems"
49+
50+
@rack_context.should_receive(:getRealPath).with("/WEB-INF/.gems").and_return ".gems"
51+
52+
expect( layout.gem_path ).to eq ".gems"
4753
end
4854

4955
it "handles gem path correctly when app uri not relative" do
@@ -63,15 +69,16 @@
6369

6470
shared_examples "FileSystemLayout" do
6571

66-
it "sets app and public uri defaults based on a typical Rails app" do
72+
it "sets app and public uri defaults based on a typical (Rails/Rack) app" do
6773
expect( layout.app_uri ).to eq '.'
68-
expect( layout.public_uri ).to eq './public'
74+
expect( layout.public_uri ).to eq 'public'
6975

7076
expect( layout.app_path ).to eq Dir.pwd
7177
expect( layout.public_path ).to eq "#{Dir.pwd}/public"
7278
end
7379

7480
it "sets public uri using context param" do
81+
@rack_context.should_receive(:getRealPath).with("static").and_return File.expand_path("static")
7582
@rack_context.should_receive(:getInitParameter).with("public.root").and_return "static"
7683
expect( layout.public_uri ).to eq 'static'
7784
expect( layout.public_path ).to eq "#{Dir.pwd}/static"
@@ -84,6 +91,7 @@
8491
end
8592

8693
it "sets gem path based on gem.home context init param" do
94+
@rack_context.should_receive(:getRealPath).with("gem/home").and_return File.expand_path("gem/home")
8795
@rack_context.should_receive(:getInitParameter).with("gem.home").and_return "gem/home"
8896
expect( layout.gem_uri ).to eq "gem/home"
8997
expect( layout.gem_path ).to eq File.expand_path("gem/home")
@@ -96,11 +104,24 @@
96104
expect( layout.gem_path ).to be nil
97105
end
98106

107+
it "expands public path relative to application root" do
108+
layout.instance_variable_set :@app_uri, '/opt/deploys/main'
109+
expect( layout.public_path ).to eq "/opt/deploys/main/public"
110+
end
111+
112+
it "expands public path relative to application root (unless absolute)" do
113+
@rack_context.should_receive(:getInitParameter).with("public.root").and_return "/home/public/root"
114+
expect( layout.public_path ).to eq "/home/public/root"
115+
end
116+
99117
end
100118

101119
describe JRuby::Rack::FileSystemLayout do
102120

103-
let(:layout) { JRuby::Rack::FileSystemLayout.new(@rack_context) }
121+
let(:layout) do
122+
@rack_context.stub(:getRealPath) { |path| path }
123+
JRuby::Rack::FileSystemLayout.new(@rack_context)
124+
end
104125

105126
it_behaves_like "FileSystemLayout"
106127

@@ -113,9 +134,7 @@
113134
describe "deprecated-constant" do
114135

115136
it "still works" do
116-
expect(lambda {
117-
expect(JRuby::Rack::RailsFilesystemLayout).to be JRuby::Rack::FileSystemLayout
118-
}).to_not raise_error
137+
expect(JRuby::Rack::RailsFilesystemLayout).to be JRuby::Rack::FileSystemLayout
119138
end
120139

121140
end
@@ -124,7 +143,10 @@
124143

125144
describe JRuby::Rack::RailsFileSystemLayout do
126145

127-
let(:layout) { JRuby::Rack::RailsFileSystemLayout.new(@rack_context) }
146+
let(:layout) do
147+
@rack_context.stub(:getRealPath) { |path| path }
148+
JRuby::Rack::RailsFileSystemLayout.new(@rack_context)
149+
end
128150

129151
it_behaves_like "FileSystemLayout"
130152

@@ -134,4 +156,4 @@
134156
expect( layout.app_path ).to eq File.expand_path("../rails", Dir.pwd)
135157
end
136158

137-
end
159+
end if defined? JRuby::Rack::RailsFileSystemLayout

0 commit comments

Comments
 (0)