@@ -51,6 +51,31 @@ func (c Static) Serve(prefix, filepath string) revel.Result {
51
51
52
52
return serve (c , prefix , filepath )
53
53
}
54
+
55
+ // This method allows modules to serve binary files. The parameters are the same
56
+ // as Static.Serve with the additional module name pre-pended to the list of
57
+ // arguments.
58
+ func (c Static ) ServeModule (moduleName , prefix , filepath string ) revel.Result {
59
+ // Fix for #503.
60
+ prefix = c .Params .Fixed .Get ("prefix" )
61
+ if prefix == "" {
62
+ return c .NotFound ("" )
63
+ }
64
+
65
+ var basePath string
66
+ for _ , module := range revel .Modules {
67
+ if module .Name == moduleName {
68
+ basePath = module .Path
69
+ }
70
+ }
71
+
72
+ absPath := fpath .Join (basePath , fpath .FromSlash (prefix ))
73
+
74
+ return serve (c , absPath , filepath )
75
+ }
76
+
77
+
78
+ // This method allows static serving of application files in a verified manner.
54
79
func serve (c Static , prefix , filepath string ) revel.Result {
55
80
var basePath string
56
81
if ! fpath .IsAbs (prefix ) {
@@ -59,11 +84,13 @@ func serve(c Static, prefix, filepath string) revel.Result {
59
84
60
85
basePathPrefix := fpath .Join (basePath , fpath .FromSlash (prefix ))
61
86
fname := fpath .Join (basePathPrefix , fpath .FromSlash (filepath ))
87
+ // Verify the request file path is within the application's scope of access
62
88
if ! strings .HasPrefix (fname , basePathPrefix ) {
63
89
revel .WARN .Printf ("Attempted to read file outside of base path: %s" , fname )
64
90
return c .NotFound ("" )
65
91
}
66
92
93
+ // Verify file path is accessible
67
94
finfo , err := os .Stat (fname )
68
95
if err != nil {
69
96
if os .IsNotExist (err ) || err .(* os.PathError ).Err == syscall .ENOTDIR {
@@ -74,11 +101,13 @@ func serve(c Static, prefix, filepath string) revel.Result {
74
101
return c .RenderError (err )
75
102
}
76
103
104
+ // Disallow directory listing
77
105
if finfo .Mode ().IsDir () {
78
106
revel .WARN .Printf ("Attempted directory listing of %s" , fname )
79
107
return c .Forbidden ("Directory listing not allowed" )
80
108
}
81
109
110
+ // Open request file path
82
111
file , err := os .Open (fname )
83
112
if err != nil {
84
113
if os .IsNotExist (err ) {
@@ -90,25 +119,3 @@ func serve(c Static, prefix, filepath string) revel.Result {
90
119
}
91
120
return c .RenderFile (file , revel .Inline )
92
121
}
93
-
94
- // This method allows modules to serve binary files. The parameters are the same
95
- // as Static.Serve with the additional module name pre-pended to the list of
96
- // arguments.
97
- func (c Static ) ServeModule (moduleName , prefix , filepath string ) revel.Result {
98
- // Fix for #503.
99
- prefix = c .Params .Fixed .Get ("prefix" )
100
- if prefix == "" {
101
- return c .NotFound ("" )
102
- }
103
-
104
- var basePath string
105
- for _ , module := range revel .Modules {
106
- if module .Name == moduleName {
107
- basePath = module .Path
108
- }
109
- }
110
-
111
- absPath := fpath .Join (basePath , fpath .FromSlash (prefix ))
112
-
113
- return serve (c , absPath , filepath )
114
- }
0 commit comments