Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2)

Side by Side Diff: src/pkg/http/fs.go

Issue 4789042: code review 4789042: http: make serveFile redirects relative to work with St... (Closed)
Patch Set: diff -r 6a3ad528f59d https://go.googlecode.com/hg/ Created 13 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/pkg/http/fs_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // HTTP file system request handler 5 // HTTP file system request handler
6 6
7 package http 7 package http
8 8
9 import ( 9 import (
10 "fmt" 10 "fmt"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 } 95 }
96 fmt.Fprintf(w, "</pre>\n") 96 fmt.Fprintf(w, "</pre>\n")
97 } 97 }
98 98
99 // name is '/'-separated, not filepath.Separator. 99 // name is '/'-separated, not filepath.Separator.
100 func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec t bool) { 100 func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec t bool) {
101 const indexPage = "/index.html" 101 const indexPage = "/index.html"
102 102
103 // redirect .../index.html to .../ 103 // redirect .../index.html to .../
104 // can't use Redirect() because that would make the path absolute,
105 // which would be a problem running under StripPrefix
104 if strings.HasSuffix(r.URL.Path, indexPage) { 106 if strings.HasSuffix(r.URL.Path, indexPage) {
105 » » Redirect(w, r, r.URL.Path[0:len(r.URL.Path)-len(indexPage)+1], S tatusMovedPermanently) 107 » » localRedirect(w, r, "./")
106 return 108 return
107 } 109 }
108 110
109 f, err := fs.Open(name) 111 f, err := fs.Open(name)
110 if err != nil { 112 if err != nil {
111 // TODO expose actual error? 113 // TODO expose actual error?
112 NotFound(w, r) 114 NotFound(w, r)
113 return 115 return
114 } 116 }
115 defer f.Close() 117 defer f.Close()
116 118
117 d, err1 := f.Stat() 119 d, err1 := f.Stat()
118 if err1 != nil { 120 if err1 != nil {
119 // TODO expose actual error? 121 // TODO expose actual error?
120 NotFound(w, r) 122 NotFound(w, r)
121 return 123 return
122 } 124 }
123 125
124 if redirect { 126 if redirect {
125 // redirect to canonical path: / at end of directory url 127 // redirect to canonical path: / at end of directory url
126 // r.URL.Path always begins with / 128 // r.URL.Path always begins with /
127 url := r.URL.Path 129 url := r.URL.Path
128 if d.IsDirectory() { 130 if d.IsDirectory() {
129 if url[len(url)-1] != '/' { 131 if url[len(url)-1] != '/' {
130 » » » » Redirect(w, r, url+"/", StatusMovedPermanently) 132 » » » » localRedirect(w, r, path.Base(url)+"/")
131 return 133 return
132 } 134 }
133 } else { 135 } else {
134 if url[len(url)-1] == '/' { 136 if url[len(url)-1] == '/' {
135 » » » » Redirect(w, r, url[0:len(url)-1], StatusMovedPer manently) 137 » » » » localRedirect(w, r, "../"+path.Base(url))
136 return 138 return
137 } 139 }
138 } 140 }
139 } 141 }
140 142
141 if t, _ := time.Parse(TimeFormat, r.Header.Get("If-Modified-Since")); t != nil && d.Mtime_ns/1e9 <= t.Seconds() { 143 if t, _ := time.Parse(TimeFormat, r.Header.Get("If-Modified-Since")); t != nil && d.Mtime_ns/1e9 <= t.Seconds() {
142 w.WriteHeader(StatusNotModified) 144 w.WriteHeader(StatusNotModified)
143 return 145 return
144 } 146 }
145 w.Header().Set("Last-Modified", time.SecondsToUTC(d.Mtime_ns/1e9).Format (TimeFormat)) 147 w.Header().Set("Last-Modified", time.SecondsToUTC(d.Mtime_ns/1e9).Format (TimeFormat))
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 w.Header().Set("Content-Length", strconv.Itoa64(size)) 215 w.Header().Set("Content-Length", strconv.Itoa64(size))
214 } 216 }
215 217
216 w.WriteHeader(code) 218 w.WriteHeader(code)
217 219
218 if r.Method != "HEAD" { 220 if r.Method != "HEAD" {
219 io.Copyn(w, f, size) 221 io.Copyn(w, f, size)
220 } 222 }
221 } 223 }
222 224
225 // localRedirect gives a Moved Permanently response.
226 // It does not convert relative paths to absolute paths like Redirect does.
227 func localRedirect(w ResponseWriter, r *Request, newPath string) {
228 if q := r.URL.RawQuery; q != "" {
229 newPath += "?" + q
230 }
231 w.Header().Set("Location", newPath)
232 w.WriteHeader(StatusMovedPermanently)
233 }
234
223 // ServeFile replies to the request with the contents of the named file or direc tory. 235 // ServeFile replies to the request with the contents of the named file or direc tory.
224 func ServeFile(w ResponseWriter, r *Request, name string) { 236 func ServeFile(w ResponseWriter, r *Request, name string) {
225 dir, file := filepath.Split(name) 237 dir, file := filepath.Split(name)
226 serveFile(w, r, Dir(dir), file, false) 238 serveFile(w, r, Dir(dir), file, false)
227 } 239 }
228 240
229 type fileHandler struct { 241 type fileHandler struct {
230 root FileSystem 242 root FileSystem
231 } 243 }
232 244
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 if i >= size { 313 if i >= size {
302 i = size - 1 314 i = size - 1
303 } 315 }
304 r.length = i - r.start + 1 316 r.length = i - r.start + 1
305 } 317 }
306 } 318 }
307 ranges = append(ranges, r) 319 ranges = append(ranges, r)
308 } 320 }
309 return ranges, nil 321 return ranges, nil
310 } 322 }
OLDNEW
« no previous file with comments | « no previous file | src/pkg/http/fs_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b