|
1 // Copyright © 2014 Steve Francia <spf@spf13.com>. |
|
2 // |
|
3 // Licensed under the Apache License, Version 2.0 (the "License"); |
|
4 // you may not use this file except in compliance with the License. |
|
5 // You may obtain a copy of the License at |
|
6 // http://www.apache.org/licenses/LICENSE-2.0 |
|
7 // |
|
8 // Unless required by applicable law or agreed to in writing, software |
|
9 // distributed under the License is distributed on an "AS IS" BASIS, |
|
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
11 // See the License for the specific language governing permissions and |
|
12 // limitations under the License. |
|
13 |
|
14 package afero |
|
15 |
|
16 import ( |
|
17 "errors" |
|
18 "net/http" |
|
19 "os" |
|
20 "path" |
|
21 "path/filepath" |
|
22 "strings" |
|
23 "time" |
|
24 ) |
|
25 |
|
26 type httpDir struct { |
|
27 basePath string |
|
28 fs HttpFs |
|
29 } |
|
30 |
|
31 func (d httpDir) Open(name string) (http.File, error) { |
|
32 if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 || |
|
33 strings.Contains(name, "\x00") { |
|
34 return nil, errors.New("http: invalid character in file path") |
|
35 } |
|
36 dir := string(d.basePath) |
|
37 if dir == "" { |
|
38 dir = "." |
|
39 } |
|
40 |
|
41 f, err := d.fs.Open(filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name)))) |
|
42 if err != nil { |
|
43 return nil, err |
|
44 } |
|
45 return f, nil |
|
46 } |
|
47 |
|
48 type HttpFs struct { |
|
49 source Fs |
|
50 } |
|
51 |
|
52 func NewHttpFs(source Fs) *HttpFs { |
|
53 return &HttpFs{source: source} |
|
54 } |
|
55 |
|
56 func (h HttpFs) Dir(s string) *httpDir { |
|
57 return &httpDir{basePath: s, fs: h} |
|
58 } |
|
59 |
|
60 func (h HttpFs) Name() string { return "h HttpFs" } |
|
61 |
|
62 func (h HttpFs) Create(name string) (File, error) { |
|
63 return h.source.Create(name) |
|
64 } |
|
65 |
|
66 func (h HttpFs) Chmod(name string, mode os.FileMode) error { |
|
67 return h.source.Chmod(name, mode) |
|
68 } |
|
69 |
|
70 func (h HttpFs) Chtimes(name string, atime time.Time, mtime time.Time) error { |
|
71 return h.source.Chtimes(name, atime, mtime) |
|
72 } |
|
73 |
|
74 func (h HttpFs) Mkdir(name string, perm os.FileMode) error { |
|
75 return h.source.Mkdir(name, perm) |
|
76 } |
|
77 |
|
78 func (h HttpFs) MkdirAll(path string, perm os.FileMode) error { |
|
79 return h.source.MkdirAll(path, perm) |
|
80 } |
|
81 |
|
82 func (h HttpFs) Open(name string) (http.File, error) { |
|
83 f, err := h.source.Open(name) |
|
84 if err == nil { |
|
85 if httpfile, ok := f.(http.File); ok { |
|
86 return httpfile, nil |
|
87 } |
|
88 } |
|
89 return nil, err |
|
90 } |
|
91 |
|
92 func (h HttpFs) OpenFile(name string, flag int, perm os.FileMode) (File, error) { |
|
93 return h.source.OpenFile(name, flag, perm) |
|
94 } |
|
95 |
|
96 func (h HttpFs) Remove(name string) error { |
|
97 return h.source.Remove(name) |
|
98 } |
|
99 |
|
100 func (h HttpFs) RemoveAll(path string) error { |
|
101 return h.source.RemoveAll(path) |
|
102 } |
|
103 |
|
104 func (h HttpFs) Rename(oldname, newname string) error { |
|
105 return h.source.Rename(oldname, newname) |
|
106 } |
|
107 |
|
108 func (h HttpFs) Stat(name string) (os.FileInfo, error) { |
|
109 return h.source.Stat(name) |
|
110 } |