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 395b120

Browse files
committedJul 28, 2015
implement arbitrary HTTP header support
this commit adds the ability to specify arbitrary HTTP headers for either the Gateway or the API. simply set the desired headers on the config: ipfs config --json API.HTTPHeaders.X-MyHdr '["meow :)"]' ipfs config --json Gateway.HTTPHeaders.X-MyHdr '["meow :)"]' License: MIT Signed-off-by: Juan Batiz-Benet <juan@benet.ai>
1 parent 63808cd commit 395b120

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed
 

‎commands/http/handler.go

+22-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var log = u.Logger("commands/http")
2121
type internalHandler struct {
2222
ctx cmds.Context
2323
root *cmds.Command
24+
cfg *ServerConfig
2425
}
2526

2627
// The Handler struct is funny because we want to wrap our internal handler
@@ -60,14 +61,24 @@ var mimeTypes = map[string]string{
6061
}
6162

6263
type ServerConfig struct {
63-
// AddHeaders is an optional function that gets to write additional
64-
// headers to HTTP responses to the API requests.
65-
AddHeaders func(http.Header)
64+
// Headers is an optional map of headers that is written out.
65+
Headers map[string][]string
6666

6767
// CORSOpts is a set of options for CORS headers.
6868
CORSOpts *cors.Options
6969
}
7070

71+
func skipAPIHeader(h string) bool {
72+
switch h {
73+
default:
74+
return false
75+
case "Access-Control-Allow-Origin":
76+
case "Access-Control-Allow-Methods":
77+
case "Access-Control-Allow-Credentials":
78+
}
79+
return true
80+
}
81+
7182
func NewHandler(ctx cmds.Context, root *cmds.Command, cfg *ServerConfig) *Handler {
7283
if cfg == nil {
7384
cfg = &ServerConfig{}
@@ -86,7 +97,7 @@ func NewHandler(ctx cmds.Context, root *cmds.Command, cfg *ServerConfig) *Handle
8697

8798
// Wrap the internal handler with CORS handling-middleware.
8899
// Create a handler for the API.
89-
internal := internalHandler{ctx, root}
100+
internal := internalHandler{ctx, root, cfg}
90101
c := cors.New(*cfg.CORSOpts)
91102
return &Handler{internal, c.Handler(internal)}
92103
}
@@ -129,6 +140,13 @@ func (i internalHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
129140
// call the command
130141
res := i.root.Call(req)
131142

143+
// set user's headers first.
144+
for k, v := range i.cfg.Headers {
145+
if !skipAPIHeader(k) {
146+
w.Header()[k] = v
147+
}
148+
}
149+
132150
// now handle responding to the client properly
133151
sendResponse(w, r, req, res)
134152
}

‎core/corehttp/commands.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func addCORSFromEnv(c *cmdsHttp.ServerConfig) {
3939
}
4040
}
4141

42-
func addCORSFromConfig(c *cmdsHttp.ServerConfig, nc *config.Config) {
42+
func addHeadersFromConfig(c *cmdsHttp.ServerConfig, nc *config.Config) {
4343
log.Info("Using API.HTTPHeaders:", nc.API.HTTPHeaders)
4444

4545
if acao := nc.API.HTTPHeaders["Access-Control-Allow-Origin"]; acao != nil {
@@ -53,6 +53,8 @@ func addCORSFromConfig(c *cmdsHttp.ServerConfig, nc *config.Config) {
5353
c.CORSOpts.AllowCredentials = (strings.ToLower(v) == "true")
5454
}
5555
}
56+
57+
c.Headers = nc.API.HTTPHeaders
5658
}
5759

5860
func CommandsOption(cctx commands.Context) ServeOption {
@@ -64,7 +66,7 @@ func CommandsOption(cctx commands.Context) ServeOption {
6466
},
6567
}
6668

67-
addCORSFromConfig(cfg, n.Repo.Config())
69+
addHeadersFromConfig(cfg, n.Repo.Config())
6870
addCORSFromEnv(cfg)
6971

7072
cmdHandler := cmdsHttp.NewHandler(cctx, corecommands.Root, cfg)

‎core/corehttp/gateway.go

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Gateway struct {
1515
}
1616

1717
type GatewayConfig struct {
18+
Headers map[string][]string
1819
BlockList *BlockList
1920
Writable bool
2021
}
@@ -27,6 +28,9 @@ func NewGateway(conf GatewayConfig) *Gateway {
2728

2829
func (g *Gateway) ServeOption() ServeOption {
2930
return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) {
31+
// pass user's HTTP headers
32+
g.Config.Headers = n.Repo.Config().Gateway.HTTPHeaders
33+
3034
gateway, err := newGatewayHandler(n, g.Config)
3135
if err != nil {
3236
return nil, err

‎core/corehttp/gateway_handler.go

+11
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
106106
return
107107
}
108108

109+
i.addUserHeaders(w) // ok, _now_ write user's headers.
109110
w.Header().Set("X-IPFS-Path", urlPath)
110111

111112
// Suborigin header, sandboxes apps from each other in the browser (even
@@ -229,6 +230,7 @@ func (i *gatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) {
229230
return
230231
}
231232

233+
i.addUserHeaders(w) // ok, _now_ write user's headers.
232234
w.Header().Set("IPFS-Hash", k.String())
233235
http.Redirect(w, r, ipfsPathPrefix+k.String(), http.StatusCreated)
234236
}
@@ -242,6 +244,7 @@ func (i *gatewayHandler) putEmptyDirHandler(w http.ResponseWriter, r *http.Reque
242244
return
243245
}
244246

247+
i.addUserHeaders(w) // ok, _now_ write user's headers.
245248
w.Header().Set("IPFS-Hash", key.String())
246249
http.Redirect(w, r, ipfsPathPrefix+key.String()+"/", http.StatusCreated)
247250
}
@@ -340,6 +343,7 @@ func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
340343
return
341344
}
342345

346+
i.addUserHeaders(w) // ok, _now_ write user's headers.
343347
w.Header().Set("IPFS-Hash", key.String())
344348
http.Redirect(w, r, ipfsPathPrefix+key.String()+"/"+strings.Join(components, "/"), http.StatusCreated)
345349
}
@@ -411,10 +415,17 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
411415
return
412416
}
413417

418+
i.addUserHeaders(w) // ok, _now_ write user's headers.
414419
w.Header().Set("IPFS-Hash", key.String())
415420
http.Redirect(w, r, ipfsPathPrefix+key.String()+"/"+strings.Join(components[:len(components)-1], "/"), http.StatusCreated)
416421
}
417422

423+
func (i *gatewayHandler) addUserHeaders(w http.ResponseWriter) {
424+
for k, v := range i.config.Headers {
425+
w.Header()[k] = v
426+
}
427+
}
428+
418429
func webError(w http.ResponseWriter, message string, err error, defaultCode int) {
419430
if _, ok := err.(path.ErrNoLink); ok {
420431
webErrorWithCode(w, message, err, http.StatusNotFound)

0 commit comments

Comments
 (0)
Please sign in to comment.