mirror of
https://github.com/ipfs/kubo.git
synced 2026-03-10 10:47:51 +08:00
commit
0de13b071d
@ -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
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user