mirror of https://github.com/perkeep/perkeep.git
Merge branch 'master' of danga.com:camlistore
This commit is contained in:
commit
9e27b6c56d
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
include $(GOROOT)/src/Make.inc
|
||||
|
||||
TARG=auth
|
||||
GOFILES=\
|
||||
auth.go
|
||||
|
||||
include $(GOROOT)/src/Make.pkg
|
|
@ -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")
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
include $(GOROOT)/src/Make.inc
|
||||
|
||||
TARG=http_util
|
||||
GOFILES=\
|
||||
http_util.go
|
||||
|
||||
include $(GOROOT)/src/Make.pkg
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue