Commit 0de13b07 authored by Juan Batiz-Benet's avatar Juan Batiz-Benet

Merge pull request #743 from jbenet/misc-2-2

Gateway Changes
parents 739abea3 0195c036
......@@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
"strings"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
cmds "github.com/jbenet/go-ipfs/commands"
......@@ -192,10 +193,21 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
}()
}
blocklist := &corehttp.BlockList{}
blocklist.SetDecider(func(s string) bool {
// only allow paths that begin with the WebUI path
return strings.HasPrefix(s, corehttp.WebUIPath)
})
gatewayConfig := corehttp.GatewayConfig{
Writable: true,
BlockList: blocklist,
}
gatewayOption := corehttp.NewGateway(gatewayConfig).ServeOption()
var opts = []corehttp.ServeOption{
corehttp.CommandsOption(*req.Context()),
corehttp.WebUIOption,
corehttp.GatewayOption(true),
gatewayOption,
}
if rootRedirect != nil {
opts = append(opts, rootRedirect)
......
......@@ -4,6 +4,7 @@ import (
"mime"
"mime/multipart"
"net/http"
"net/url"
)
const (
......@@ -67,7 +68,12 @@ func (f *MultipartFile) NextFile() (File, error) {
}
func (f *MultipartFile) FileName() string {
return f.Part.FileName()
filename, err := url.QueryUnescape(f.Part.FileName())
if err != nil {
// if there is a unescape error, just treat the name as unescaped
return f.Part.FileName()
}
return filename
}
func (f *MultipartFile) Read(p []byte) (int, error) {
......
......@@ -6,6 +6,7 @@ import (
"io"
"net/http"
"strconv"
"strings"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
......@@ -55,6 +56,20 @@ func (i Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Debug("Incoming API request: ", r.URL)
// error on external referers (to prevent CSRF attacks)
referer := r.Referer()
scheme := r.URL.Scheme
if len(scheme) == 0 {
scheme = "http"
}
host := fmt.Sprintf("%s://%s/", scheme, r.Host)
// empty string means the user isn't following a link (they are directly typing in the url)
if referer != "" && !strings.HasPrefix(referer, host) {
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("403 - Forbidden"))
return
}
if len(i.origin) > 0 {
w.Header().Set("Access-Control-Allow-Origin", i.origin)
}
......
......@@ -6,6 +6,7 @@ import (
"io"
"mime/multipart"
"net/textproto"
"net/url"
"sync"
files "github.com/jbenet/go-ipfs/commands/files"
......@@ -74,11 +75,12 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) {
// write the boundary and headers
header := make(textproto.MIMEHeader)
filename := url.QueryEscape(file.FileName())
if mfr.form {
contentDisposition := fmt.Sprintf("form-data; name=\"file\"; filename=\"%s\"", file.FileName())
contentDisposition := fmt.Sprintf("form-data; name=\"file\"; filename=\"%s\"", filename)
header.Set("Content-Disposition", contentDisposition)
} else {
header.Set("Content-Disposition", fmt.Sprintf("file; filename=\"%s\"", file.FileName()))
header.Set("Content-Disposition", fmt.Sprintf("file; filename=\"%s\"", filename))
}
if file.IsDirectory() {
......
......@@ -47,7 +47,6 @@ func GatewayOption(writable bool) ServeOption {
type Decider func(string) bool
type BlockList struct {
mu sync.RWMutex
d Decider
}
......
......@@ -48,15 +48,15 @@ type directoryItem struct {
// gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/<path>)
// (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link)
type gatewayHandler struct {
node *core.IpfsNode
dirList *template.Template
config GatewayConfig
node *core.IpfsNode
dirList *template.Template
config GatewayConfig
}
func newGatewayHandler(node *core.IpfsNode, conf GatewayConfig) (*gatewayHandler, error) {
i := &gatewayHandler{
node: node,
config: conf,
node: node,
config: conf,
}
err := i.loadTemplate()
if err != nil {
......@@ -167,7 +167,8 @@ func (i *gatewayHandler) getHandler(w http.ResponseWriter, r *http.Request) {
urlPath := r.URL.Path
if i.config.BlockList != nil && i.config.BlockList.ShouldBlock(urlPath) {
w.WriteHeader(http.StatusNotFound)
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("403 - Forbidden"))
return
}
......@@ -193,6 +194,12 @@ func (i *gatewayHandler) getHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-IPFS-Path", p)
// Suborigin header, sandboxes apps from each other in the browser (even
// though they are served from the same gateway domain). NOTE: This is not
// yet widely supported by browsers.
pathRoot := strings.SplitN(urlPath, "/", 4)[2]
w.Header().Set("Suborigin", pathRoot)
dr, err := i.NewDagReader(nd)
if err != nil && err != uio.ErrIsDir {
// not a directory and still an error
......
package corehttp
// TODO: move to IPNS
const webuiPath = "/ipfs/QmctngrQAt9fjpQUZr7Bx3BsXUcif52eZGTizWhvcShsjz"
const WebUIPath = "/ipfs/QmSHDxWsMPuJQKWmVA1rB5a3NX2Eme5fPqNb63qwaqiqSp"
var WebUIOption = RedirectOption("webui", webuiPath)
var WebUIOption = RedirectOption("webui", WebUIPath)
......@@ -35,7 +35,8 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
"/ip4/0.0.0.0/tcp/4001",
// "/ip4/0.0.0.0/udp/4002/utp", // disabled for now.
},
API: "/ip4/127.0.0.1/tcp/5001",
API: "/ip4/127.0.0.1/tcp/5001",
Gateway: "/ip4/127.0.0.1/tcp/8080",
},
Bootstrap: BootstrapPeerStrings(bootstrapPeers),
......
......@@ -22,7 +22,7 @@ test_launch_ipfs_daemon
test_expect_success "GET IPFS path succeeds" '
echo "Hello Worlds!" > expected &&
HASH=`ipfs add -q expected` &&
wget "http://127.0.0.1:5001/ipfs/$HASH" -O actual
wget "http://127.0.0.1:5002/ipfs/$HASH" -O actual
'
test_expect_success "GET IPFS path output looks good" '
......@@ -34,11 +34,11 @@ test_expect_success "GET IPFS directory path succeeds" '
mkdir dir &&
echo "12345" > dir/test &&
HASH2=`ipfs add -r -q dir | tail -n 1` &&
wget "http://127.0.0.1:5001/ipfs/$HASH2"
wget "http://127.0.0.1:5002/ipfs/$HASH2"
'
test_expect_success "GET IPFS directory file succeeds" '
wget "http://127.0.0.1:5001/ipfs/$HASH2/test" -O actual
wget "http://127.0.0.1:5002/ipfs/$HASH2/test" -O actual
'
test_expect_success "GET IPFS directory file output looks good" '
......@@ -48,7 +48,7 @@ test_expect_success "GET IPFS directory file output looks good" '
test_expect_failure "GET IPNS path succeeds" '
ipfs name publish "$HASH" &&
NAME=`ipfs config Identity.PeerID` &&
wget "http://127.0.0.1:5001/ipns/$NAME" -O actual
wget "http://127.0.0.1:5002/ipns/$NAME" -O actual
'
test_expect_failure "GET IPNS path output looks good" '
......@@ -56,11 +56,11 @@ test_expect_failure "GET IPNS path output looks good" '
'
test_expect_success "GET invalid IPFS path errors" '
test_must_fail wget http://127.0.0.1:5001/ipfs/12345
test_must_fail wget http://127.0.0.1:5002/ipfs/12345
'
test_expect_success "GET invalid path errors" '
test_must_fail wget http://127.0.0.1:5001/12345
test_must_fail wget http://127.0.0.1:5002/12345
'
test_kill_ipfs_daemon
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment