Merge branch 'bzz' of github.com:ethersphere/go-ethereum into bzz

This commit is contained in:
zelig 2015-02-11 12:12:41 +01:00
commit 2c27a7753d
2 changed files with 71 additions and 2 deletions

View file

@ -4,6 +4,7 @@ A simple http server interface to Swarm
package bzz package bzz
import ( import (
"encoding/json"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"io" "io"
@ -17,7 +18,9 @@ const (
) )
var ( var (
uriMatcher = regexp.MustCompile("^/raw/[0-9A-Fa-f]{64}$") uriMatcher = regexp.MustCompile("^/raw/[0-9A-Fa-f]{64}$")
manifestMatcher = regexp.MustCompile("^/[0-9A-Fa-f]{64}")
hashMatcher = regexp.MustCompile("^[0-9A-Fa-f]{64}$")
) )
type sequentialReader struct { type sequentialReader struct {
@ -26,6 +29,13 @@ type sequentialReader struct {
ahead map[int64](chan bool) ahead map[int64](chan bool)
} }
type manifestEntry struct {
Path string
Hash string
Content_type string
Status int16
}
func (self *sequentialReader) ReadAt(target []byte, off int64) (n int, err error) { func (self *sequentialReader) ReadAt(target []byte, off int64) (n int, err error) {
if self.pos != off { if self.pos != off {
dpaLogger.Debugf("Swarm: deferred read in POST at position %d, offset %d.", dpaLogger.Debugf("Swarm: deferred read in POST at position %d, offset %d.",
@ -80,9 +90,68 @@ func handler(w http.ResponseWriter, r *http.Request, dpa *DPA) {
} }
case r.Method == "GET": case r.Method == "GET":
if uriMatcher.MatchString(uri) { if uriMatcher.MatchString(uri) {
dpaLogger.Debugf("Swarm: Raw GET request %s received", uri)
name := uri[5:] name := uri[5:]
key := ethutil.Hex2Bytes(name) key := ethutil.Hex2Bytes(name)
http.ServeContent(w, r, name+".bin", time.Unix(0, 0), dpa.Retrieve(key)) http.ServeContent(w, r, name+".bin", time.Unix(0, 0), dpa.Retrieve(key))
dpaLogger.Debugf("Swarm: Object %s returned.", name)
} else if manifestMatcher.MatchString(uri) {
dpaLogger.Debugf("Swarm: Structured GET request %s received.", uri)
name := uri[1:65]
path := uri[65:] // typically begins with a /
key := ethutil.Hex2Bytes(name)
manifestReader := dpa.Retrieve(key)
// TODO check size for oversized manifests
manifest := make([]byte, manifestReader.Size())
n, err := manifestReader.Read(manifest)
if err != nil {
dpaLogger.Debugf("Swarm: Manifest %s not found.", name)
http.Error(w, err.Error(), http.StatusNotFound)
return
}
dpaLogger.Debugf("Swarm: Manifest %s retrieved.")
manifestEntries := make([]manifestEntry, 0)
err = json.Unmarshal(manifest, &manifestEntries)
if err != nil {
dpaLogger.Debugf("Swarm: Manifest %s is malformed.", name)
http.Error(w, err.Error(), http.StatusNotFound)
return
} else {
dpaLogger.Debugf("Swarm: Manifest %s has %d entries.", name, len(manifestEntries))
}
var mimeType string
key = nil
prefix := 0
status := int16(404)
for i, entry := range manifestEntries {
if !hashMatcher.MatchString(entry.Hash) {
// hash is mandatory
break
}
if entry.Content_type == "" {
// content type defaults to manifest
entry.Content_type = "application/bzz-manifest+json"
}
if entry.Status == 0 {
// status defaults to 200
entry.Status = 200
}
pathLen := len(entry.Path)
if len(path) >= pathLen && path[:pathLen] == entry.Path && prefix < pathLen {
prefix = pathLen
key = ethutil.Hex2Bytes(entry.Hash)
mimeType = entry.Content_type
status = entry.Status
}
}
if key == nil {
http.Error(w, "Object "+uri+" not found.", http.StatusNotFound)
} else {
w.Header().Set("Content-Type", mimeType)
w.WriteHeader(int(status))
http.ServeContent(w, r, "", time.Unix(0, 0), dpa.Retrieve(key))
dpaLogger.Debugf("Swarm: Served %s as %s.", mimeType, uri)
}
} else { } else {
http.Error(w, "Object "+uri+" not found.", http.StatusNotFound) http.Error(w, "Object "+uri+" not found.", http.StatusNotFound)
} }

View file

@ -148,7 +148,7 @@ func New(config *Config) (*Ethereum, error) {
ChunkStore: netStore, ChunkStore: netStore,
} }
dpa.Start() dpa.Start()
bzz.StartHttpServer(dpa) go bzz.StartHttpServer(dpa)
nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway) nat, err := p2p.ParseNAT(config.NATType, config.PMPGateway)
if err != nil { if err != nil {