Merge branch 'master' of danga.com:camlistore

This commit is contained in:
Brad Fitzpatrick 2010-11-14 20:05:35 -08:00
commit 9e27b6c56d
11 changed files with 67 additions and 41 deletions

9
server/go/Makefile Normal file
View File

@ -0,0 +1,9 @@
all:
make -C auth install
make -C http_util install
make -C blobserver
clean:
make -C auth clean
make -C http_util clean
make -C blobserver clean

7
server/go/auth/Makefile Normal file
View File

@ -0,0 +1,7 @@
include $(GOROOT)/src/Make.inc
TARG=auth
GOFILES=\
auth.go
include $(GOROOT)/src/Make.pkg

View File

@ -1,4 +1,4 @@
package main
package auth
import (
"encoding/base64"
@ -10,9 +10,9 @@ import (
var kBasicAuthPattern *regexp.Regexp = regexp.MustCompile(`^Basic ([a-zA-Z0-9\+/=]+)`)
var accessPassword string
var AccessPassword string
func isAuthorized(req *http.Request) bool {
func IsAuthorized(req *http.Request) bool {
auth, present := req.Header["Authorization"]
if !present {
return false
@ -34,14 +34,14 @@ func isAuthorized(req *http.Request) bool {
return false
}
password := userpass[1] // username at index 0 is currently unused
return password != "" && password == accessPassword
return password != "" && password == AccessPassword
}
// requireAuth wraps a function with another function that enforces
// HTTP Basic Auth.
func requireAuth(handler func(conn http.ResponseWriter, req *http.Request)) func (conn http.ResponseWriter, req *http.Request) {
func RequireAuth(handler func(conn http.ResponseWriter, req *http.Request)) func (conn http.ResponseWriter, req *http.Request) {
return func (conn http.ResponseWriter, req *http.Request) {
if !isAuthorized(req) {
if !IsAuthorized(req) {
conn.SetHeader("WWW-Authenticate", "Basic realm=\"camlistored\"")
conn.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(conn, "Authentication required.\n")

View File

@ -3,15 +3,12 @@ include $(GOROOT)/src/Make.inc
TARG=camlistored
GOFILES=\
camlistored.go\
auth.go\
blobref.go\
enumerate.go\
get.go\
http_util.go\
preupload.go\
temp_testing.go\
range.go\
upload.go\
include $(GOROOT)/src/Make.cmd

View File

@ -5,9 +5,11 @@
package main
import (
"auth"
"flag"
"fmt"
"http"
"http_util"
"os"
)
@ -17,29 +19,29 @@ var stealthMode *bool = flag.Bool("stealth", true, "Run in stealth mode.")
func handleCamli(conn http.ResponseWriter, req *http.Request) {
handler := func (conn http.ResponseWriter, req *http.Request) {
badRequestError(conn, "Unsupported path or method.")
http_util.BadRequestError(conn, "Unsupported path or method.")
}
switch req.Method {
case "GET":
switch req.URL.Path {
case "/camli/enumerate-blobs":
handler = requireAuth(handleEnumerateBlobs)
handler = auth.RequireAuth(handleEnumerateBlobs)
default:
handler = requireAuth(handleGet)
handler = auth.RequireAuth(handleGet)
}
case "POST":
switch req.URL.Path {
case "/camli/preupload":
handler = requireAuth(handlePreUpload)
handler = auth.RequireAuth(handlePreUpload)
case "/camli/upload":
handler = requireAuth(handleMultiPartUpload)
handler = auth.RequireAuth(handleMultiPartUpload)
case "/camli/testform": // debug only
handler = handleTestForm
case "/camli/form": // debug only
handler = handleCamliForm
}
case "PUT": // no longer part of spec
handler = requireAuth(handlePut)
handler = auth.RequireAuth(handlePut)
}
handler(conn, req)
}
@ -56,8 +58,8 @@ func handleRoot(conn http.ResponseWriter, req *http.Request) {
func main() {
flag.Parse()
accessPassword = os.Getenv("CAMLI_PASSWORD")
if len(accessPassword) == 0 {
auth.AccessPassword = os.Getenv("CAMLI_PASSWORD")
if len(auth.AccessPassword) == 0 {
fmt.Fprintf(os.Stderr,
"No CAMLI_PASSWORD environment variable set.\n")
os.Exit(1)

View File

@ -3,6 +3,7 @@ package main
import (
"fmt"
"http"
"http_util"
"os"
"io"
)
@ -10,7 +11,7 @@ import (
func handleGet(conn http.ResponseWriter, req *http.Request) {
blobRef := ParsePath(req.URL.Path)
if blobRef == nil {
badRequestError(conn, "Malformed GET URL.")
http_util.BadRequestError(conn, "Malformed GET URL.")
return
}
fileName := blobRef.FileName()
@ -21,12 +22,12 @@ func handleGet(conn http.ResponseWriter, req *http.Request) {
return
}
if err != nil {
serverError(conn, err)
http_util.ServerError(conn, err)
return
}
file, err := os.Open(fileName, os.O_RDONLY, 0)
if err != nil {
serverError(conn, err)
http_util.ServerError(conn, err)
return
}
@ -34,7 +35,7 @@ func handleGet(conn http.ResponseWriter, req *http.Request) {
if reqRange.SkipBytes != 0 {
_, err = file.Seek(reqRange.SkipBytes, 0)
if err != nil {
serverError(conn, err)
http_util.ServerError(conn, err)
return
}
}

View File

@ -1,22 +1,23 @@
package main
import (
"http"
"container/vector"
"fmt"
"http"
"http_util"
"os"
)
func handlePreUpload(conn http.ResponseWriter, req *http.Request) {
if !(req.Method == "POST" && req.URL.Path == "/camli/preupload") {
badRequestError(conn, "Inconfigured handler.")
http_util.BadRequestError(conn, "Inconfigured handler.")
return
}
req.ParseForm()
camliVersion := req.FormValue("camliversion")
if camliVersion == "" {
badRequestError(conn, "No camliversion")
http_util.BadRequestError(conn, "No camliversion")
return
}
n := 0
@ -31,11 +32,11 @@ func handlePreUpload(conn http.ResponseWriter, req *http.Request) {
}
ref := ParseBlobRef(value)
if ref == nil {
badRequestError(conn, "Bogus blobref for key "+key)
http_util.BadRequestError(conn, "Bogus blobref for key "+key)
return
}
if !ref.IsSupported() {
badRequestError(conn, "Unsupported or bogus blobref "+key)
http_util.BadRequestError(conn, "Unsupported or bogus blobref "+key)
}
n++
@ -67,6 +68,6 @@ func handlePreUpload(conn http.ResponseWriter, req *http.Request) {
ret := commonUploadResponse(req)
ret["alreadyHave"] = haveVector.Copy()
returnJson(conn, ret)
http_util.ReturnJson(conn, ret)
}

View File

@ -4,6 +4,7 @@ import (
"crypto/sha1"
"fmt"
"http"
"http_util"
"io"
)
@ -27,13 +28,13 @@ Image png: <input type="file" name="image-png"><br>
func handleTestForm(conn http.ResponseWriter, req *http.Request) {
if !(req.Method == "POST" && req.URL.Path == "/camli/testform") {
badRequestError(conn, "Inconfigured handler.")
http_util.BadRequestError(conn, "Inconfigured handler.")
return
}
multipart, err := req.MultipartReader()
if multipart == nil {
badRequestError(conn, fmt.Sprintf("Expected multipart/form-data POST request; %v", err))
http_util.BadRequestError(conn, fmt.Sprintf("Expected multipart/form-data POST request; %v", err))
return
}

View File

@ -1,8 +1,9 @@
package main
import (
"http"
"fmt"
"http"
"http_util"
"io"
"io/ioutil"
"os"
@ -15,7 +16,7 @@ type receivedBlob struct {
func handleMultiPartUpload(conn http.ResponseWriter, req *http.Request) {
if !(req.Method == "POST" && req.URL.Path == "/camli/upload") {
badRequestError(conn, "Inconfigured handler.")
http_util.BadRequestError(conn, "Inconfigured handler.")
return
}
@ -23,7 +24,7 @@ func handleMultiPartUpload(conn http.ResponseWriter, req *http.Request) {
multipart, err := req.MultipartReader()
if multipart == nil {
badRequestError(conn, fmt.Sprintf(
http_util.BadRequestError(conn, fmt.Sprintf(
"Expected multipart/form-data POST request; %v", err))
return
}
@ -62,7 +63,7 @@ func handleMultiPartUpload(conn http.ResponseWriter, req *http.Request) {
// TODO: put the blobs in the JSON here
ret := commonUploadResponse(req)
returnJson(conn, ret)
http_util.ReturnJson(conn, ret)
}
func commonUploadResponse(req *http.Request) map[string]interface{} {
@ -132,18 +133,18 @@ func receiveBlob(blobRef *BlobRef, source io.Reader) (blobGot *receivedBlob, err
func handlePut(conn http.ResponseWriter, req *http.Request) {
blobRef := ParsePath(req.URL.Path)
if blobRef == nil {
badRequestError(conn, "Malformed PUT URL.")
http_util.BadRequestError(conn, "Malformed PUT URL.")
return
}
if !blobRef.IsSupported() {
badRequestError(conn, "unsupported object hash function")
http_util.BadRequestError(conn, "unsupported object hash function")
return
}
_, err := receiveBlob(blobRef, req.Body)
if err != nil {
serverError(conn, err)
http_util.ServerError(conn, err)
return
}

View File

@ -0,0 +1,7 @@
include $(GOROOT)/src/Make.inc
TARG=http_util
GOFILES=\
http_util.go
include $(GOROOT)/src/Make.pkg

View File

@ -1,4 +1,4 @@
package main
package http_util
import (
"fmt"
@ -7,20 +7,20 @@ import (
"os"
)
func badRequestError(conn http.ResponseWriter, errorMessage string) {
func BadRequestError(conn http.ResponseWriter, errorMessage string) {
conn.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(conn, "%s\n", errorMessage)
}
func serverError(conn http.ResponseWriter, err os.Error) {
func ServerError(conn http.ResponseWriter, err os.Error) {
conn.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(conn, "Server error: %s\n", err)
}
func returnJson(conn http.ResponseWriter, data interface{}) {
func ReturnJson(conn http.ResponseWriter, data interface{}) {
bytes, err := json.MarshalIndent(data, "", " ")
if err != nil {
badRequestError(conn, fmt.Sprintf(
BadRequestError(conn, fmt.Sprintf(
"JSON serialization error: %v", err))
return
}