core/corehttp: Support Range requests in gateway handler
Matt Bell committed
Jan 26, 2015 at 22:00 UTC
d338a81eca5260ad6b587b3a7905ef316448c891
1 file changed
+16
-22
core/corehttp/gateway_handler.go
+16
-22
@@ -3,9 +3,9 @@ package corehttp
3
import (
4
"html/template"
5
"io"
6
- "mime"
6
"net/http"
8
- "strings"
7
+ "path"
8
+ "time"
9
10
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
11
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
@@ -23,7 +23,7 @@ type gateway interface {
23
ResolvePath(string) (*dag.Node, error)
24
NewDagFromReader(io.Reader) (*dag.Node, error)
25
AddNodeToDAG(nd *dag.Node) (u.Key, error)
26
- NewDagReader(nd *dag.Node) (io.Reader, error)
26
+ NewDagReader(nd *dag.Node) (io.ReadSeeker, error)
27
}
28
29
// shortcut for templating
@@ -63,8 +63,8 @@ func (i *gatewayHandler) loadTemplate() error {
63
return nil
64
}
65
66
-func (i *gatewayHandler) ResolvePath(path string) (*dag.Node, error) {
67
- return i.node.Resolver.ResolvePath(path)
66
+func (i *gatewayHandler) ResolvePath(p string) (*dag.Node, error) {
67
+ return i.node.Resolver.ResolvePath(p)
68
}
69
70
func (i *gatewayHandler) NewDagFromReader(r io.Reader) (*dag.Node, error) {
@@ -76,14 +76,14 @@ func (i *gatewayHandler) AddNodeToDAG(nd *dag.Node) (u.Key, error) {
76
return i.node.DAG.Add(nd)
77
}
78
79
-func (i *gatewayHandler) NewDagReader(nd *dag.Node) (io.Reader, error) {
79
+func (i *gatewayHandler) NewDagReader(nd *dag.Node) (io.ReadSeeker, error) {
80
return uio.NewDagReader(i.node.Context(), nd, i.node.DAG)
81
}
82
83
func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
84
- path := r.URL.Path[5:]
84
+ urlPath := r.URL.Path[5:]
85
86
- nd, err := i.ResolvePath(path)
86
+ nd, err := i.ResolvePath(urlPath)
87
if err != nil {
88
if err == routing.ErrNotFound {
89
w.WriteHeader(http.StatusNotFound)
@@ -98,18 +98,12 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
98
return
99
}
100
101
- extensionIndex := strings.LastIndex(path, ".")
102
- if extensionIndex != -1 {
103
- extension := path[extensionIndex:]
104
- mimeType := mime.TypeByExtension(extension)
105
- if len(mimeType) > 0 {
106
- w.Header().Add("Content-Type", mimeType)
107
- }
108
- }
109
-
101
dr, err := i.NewDagReader(nd)
102
if err == nil {
112
- io.Copy(w, dr)
103
+ _, name := path.Split(urlPath)
104
+ // set modtime to a really long time ago, since files are immutable and should stay cached
105
+ modtime := time.Unix(1, 0)
106
+ http.ServeContent(w, r, name, modtime, dr)
107
return
108
}
109
@@ -120,9 +114,9 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
114
}
115
116
log.Debug("listing directory")
123
- if path[len(path)-1:] != "/" {
117
+ if urlPath[len(urlPath)-1:] != "/" {
118
log.Debug("missing trailing slash, redirect")
125
- http.Redirect(w, r, "/ipfs/"+path+"/", 307)
119
+ http.Redirect(w, r, "/ipfs/"+urlPath+"/", 307)
120
return
121
}
122
@@ -135,7 +129,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
129
log.Debug("found index")
130
foundIndex = true
131
// return index page instead.
138
- nd, err := i.ResolvePath(path + "/index.html")
132
+ nd, err := i.ResolvePath(urlPath + "/index.html")
133
if err != nil {
134
internalWebError(w, err)
135
return
@@ -155,7 +149,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
149
150
if !foundIndex {
151
// template and return directory listing
158
- hndlr := webHandler{"listing": dirListing, "path": path}
152
+ hndlr := webHandler{"listing": dirListing, "path": urlPath}
153
if err := i.dirList.Execute(w, hndlr); err != nil {
154
internalWebError(w, err)
155
return