Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 07b4e9d

Browse files
committedJun 19, 2015
http/gateway: first tab at integrating @krl's new index page
1 parent 370df8f commit 07b4e9d

File tree

2 files changed

+160
-51
lines changed

2 files changed

+160
-51
lines changed
 

‎core/corehttp/gateway_handler.go

+2-51
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,6 @@ const (
2727
ipnsPathPrefix = "/ipns/"
2828
)
2929

30-
// shortcut for templating
31-
type webHandler map[string]interface{}
32-
33-
// struct for directory listing
34-
type directoryItem struct {
35-
Size uint64
36-
Name string
37-
Path string
38-
}
39-
4030
// gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/<path>)
4131
// (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link)
4232
type gatewayHandler struct {
@@ -50,23 +40,9 @@ func newGatewayHandler(node *core.IpfsNode, conf GatewayConfig) (*gatewayHandler
5040
node: node,
5141
config: conf,
5242
}
53-
err := i.loadTemplate()
54-
if err != nil {
55-
return nil, err
56-
}
5743
return i, nil
5844
}
5945

60-
// Load the directroy list template
61-
func (i *gatewayHandler) loadTemplate() error {
62-
t, err := template.New("dir").Parse(listingTemplate)
63-
if err != nil {
64-
return err
65-
}
66-
i.dirList = t
67-
return nil
68-
}
69-
7046
// TODO(cryptix): find these helpers somewhere else
7147
func (i *gatewayHandler) newDagFromReader(r io.Reader) (*dag.Node, error) {
7248
// TODO(cryptix): change and remove this helper once PR1136 is merged
@@ -205,14 +181,9 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
205181
}
206182

207183
if !foundIndex {
208-
// template and return directory listing
209-
hndlr := webHandler{
210-
"listing": dirListing,
211-
"path": urlPath,
212-
}
213-
214184
if r.Method != "HEAD" {
215-
if err := i.dirList.Execute(w, hndlr); err != nil {
185+
err := listingTemplate.Execute(w, listingTemplateData{dirListing, urlPath})
186+
if err != nil {
216187
internalWebError(w, err)
217188
return
218189
}
@@ -441,23 +412,3 @@ func webErrorWithCode(w http.ResponseWriter, message string, err error, code int
441412
func internalWebError(w http.ResponseWriter, err error) {
442413
webErrorWithCode(w, "internalWebError", err, http.StatusInternalServerError)
443414
}
444-
445-
// Directory listing template
446-
var listingTemplate = `
447-
<!DOCTYPE html>
448-
<html>
449-
<head>
450-
<meta charset="utf-8" />
451-
<title>{{ .path }}</title>
452-
</head>
453-
<body>
454-
<h2>Index of {{ .path }}</h2>
455-
<ul>
456-
<li><a href="./..">..</a></li>
457-
{{ range .listing }}
458-
<li><a href="{{ .Path }}">{{ .Name }}</a> - {{ .Size }} bytes</li>
459-
{{ end }}
460-
</ul>
461-
</body>
462-
</html>
463-
`

‎core/corehttp/gateway_indexPage.go

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package corehttp
2+
3+
import (
4+
"html/template"
5+
"path"
6+
)
7+
8+
// structs for directory listing
9+
type listingTemplateData struct {
10+
Listing []directoryItem
11+
Path string
12+
}
13+
14+
type directoryItem struct {
15+
Size uint64
16+
Name string
17+
Path string
18+
}
19+
20+
// Directory listing template
21+
var listingTemplate = template.Must(template.New("dir").Funcs(template.FuncMap{"iconFromExt": iconFromExt}).Parse(`
22+
<!DOCTYPE html>
23+
<html>
24+
<head>
25+
<meta charset="utf-8" />
26+
<link rel="stylesheet" href="/ipfs/QmXB7PLRWH6bCiwrGh2MrBBjNkLv3mY3JdYXCikYZSwLED/bootstrap.min.css"/>
27+
<link rel="stylesheet" href="/ipfs/QmXB7PLRWH6bCiwrGh2MrBBjNkLv3mY3JdYXCikYZSwLED/icons.css">
28+
<style>
29+
.narrow {width: 0px;}
30+
.padding { margin: 100px;}
31+
#header {
32+
background: #000;
33+
}
34+
#logo {
35+
height: 25px;
36+
margin: 10px;
37+
}
38+
.ipfs-icon {
39+
width:16px;
40+
}
41+
</style>
42+
<title>{{ .Path }}</title>
43+
</head>
44+
<body>
45+
<div id="header" class="row">
46+
<div class="col-xs-2">
47+
<div id="logo" class="ipfs-logo">&nbsp;</div>
48+
</div>
49+
</div>
50+
<br/>
51+
<div class="col-xs-12">
52+
<div class="panel panel-default">
53+
<div class="panel-heading">
54+
<strong>Index of {{ .Path }}</strong>
55+
</div>
56+
<table class="table table-striped">
57+
<tr>
58+
<td class="narrow">
59+
<div class="ipfs-icon ipfs-_blank">&nbsp;</div>
60+
</td>
61+
<td class="padding">
62+
<a href="./..">..</a>
63+
</td>
64+
<td></td>
65+
</tr>
66+
{{ range .Listing }}
67+
<tr>
68+
<td>
69+
<div class="ipfs-icon {{iconFromExt .Name}}">&nbsp;</div>
70+
</td>
71+
<td>
72+
<a href="{{ .Path }}">{{ .Name }}</a>
73+
</td>
74+
<td>{{ .Size }} bytes</td>
75+
</tr>
76+
{{ end }}
77+
</table>
78+
</div>
79+
</div>
80+
</body>
81+
</html>
82+
`))
83+
84+
// helper to guess the type/icon for it by the extension name
85+
func iconFromExt(name string) string {
86+
ext := path.Ext(name)
87+
_, ok := knownIcons[ext]
88+
if !ok {
89+
log.Errorf("No icon for %q %q", name, ext)
90+
// default blank icon
91+
return "ipfs-_blank"
92+
}
93+
return "ipfs-" + ext[1:] // slice of the first dot
94+
}
95+
96+
var knownIcons = map[string]bool{
97+
".aac": true,
98+
".aiff": true,
99+
".ai": true,
100+
".avi": true,
101+
".bmp": true,
102+
".c": true,
103+
".cpp": true,
104+
".css": true,
105+
".dat": true,
106+
".dmg": true,
107+
".doc": true,
108+
".dotx": true,
109+
".dwg": true,
110+
".dxf": true,
111+
".eps": true,
112+
".exe": true,
113+
".flv": true,
114+
".gif": true,
115+
".h": true,
116+
".hpp": true,
117+
".html": true,
118+
".ics": true,
119+
".iso": true,
120+
".java": true,
121+
".jpg": true,
122+
".js": true,
123+
".key": true,
124+
".less": true,
125+
".mid": true,
126+
".mp3": true,
127+
".mp4": true,
128+
".mpg": true,
129+
".odf": true,
130+
".ods": true,
131+
".odt": true,
132+
".otp": true,
133+
".ots": true,
134+
".ott": true,
135+
".pdf": true,
136+
".php": true,
137+
".png": true,
138+
".ppt": true,
139+
".psd": true,
140+
".py": true,
141+
".qt": true,
142+
".rar": true,
143+
".rb": true,
144+
".rtf": true,
145+
".sass": true,
146+
".scss": true,
147+
".sql": true,
148+
".tga": true,
149+
".tgz": true,
150+
".tiff": true,
151+
".txt": true,
152+
".wav": true,
153+
".xls": true,
154+
".xlsx": true,
155+
".xml": true,
156+
".yml": true,
157+
".zip": true,
158+
}

0 commit comments

Comments
 (0)
Please sign in to comment.