diff --git a/server/go/Makefile b/server/go/Makefile
new file mode 100644
index 000000000..d52cb1eaf
--- /dev/null
+++ b/server/go/Makefile
@@ -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
diff --git a/server/go/auth/Makefile b/server/go/auth/Makefile
new file mode 100644
index 000000000..a69e53cba
--- /dev/null
+++ b/server/go/auth/Makefile
@@ -0,0 +1,7 @@
+include $(GOROOT)/src/Make.inc
+
+TARG=auth
+GOFILES=\
+ auth.go
+
+include $(GOROOT)/src/Make.pkg
diff --git a/server/go/blobserver/auth.go b/server/go/auth/auth.go
similarity index 83%
rename from server/go/blobserver/auth.go
rename to server/go/auth/auth.go
index 77f39f390..472164394 100644
--- a/server/go/blobserver/auth.go
+++ b/server/go/auth/auth.go
@@ -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")
diff --git a/server/go/blobserver/Makefile b/server/go/blobserver/Makefile
index b3267912e..9a1c26ee1 100644
--- a/server/go/blobserver/Makefile
+++ b/server/go/blobserver/Makefile
@@ -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
-
diff --git a/server/go/blobserver/camlistored.go b/server/go/blobserver/camlistored.go
index f2a904a39..08592bef4 100644
--- a/server/go/blobserver/camlistored.go
+++ b/server/go/blobserver/camlistored.go
@@ -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)
diff --git a/server/go/blobserver/get.go b/server/go/blobserver/get.go
index c76a8cb29..b2ecb86fb 100644
--- a/server/go/blobserver/get.go
+++ b/server/go/blobserver/get.go
@@ -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
}
}
diff --git a/server/go/blobserver/preupload.go b/server/go/blobserver/preupload.go
index 5083eb015..3e28e3790 100644
--- a/server/go/blobserver/preupload.go
+++ b/server/go/blobserver/preupload.go
@@ -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)
}
diff --git a/server/go/blobserver/temp_testing.go b/server/go/blobserver/temp_testing.go
index be78f7307..a0799e310 100644
--- a/server/go/blobserver/temp_testing.go
+++ b/server/go/blobserver/temp_testing.go
@@ -4,6 +4,7 @@ import (
"crypto/sha1"
"fmt"
"http"
+ "http_util"
"io"
)
@@ -27,13 +28,13 @@ Image png:
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
}
diff --git a/server/go/blobserver/upload.go b/server/go/blobserver/upload.go
index 5c1a7f61c..8817f1563 100644
--- a/server/go/blobserver/upload.go
+++ b/server/go/blobserver/upload.go
@@ -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
}
diff --git a/server/go/http_util/Makefile b/server/go/http_util/Makefile
new file mode 100644
index 000000000..2b74c46a3
--- /dev/null
+++ b/server/go/http_util/Makefile
@@ -0,0 +1,7 @@
+include $(GOROOT)/src/Make.inc
+
+TARG=http_util
+GOFILES=\
+ http_util.go
+
+include $(GOROOT)/src/Make.pkg
diff --git a/server/go/blobserver/http_util.go b/server/go/http_util/http_util.go
similarity index 62%
rename from server/go/blobserver/http_util.go
rename to server/go/http_util/http_util.go
index ef8c687ca..e87a62433 100644
--- a/server/go/blobserver/http_util.go
+++ b/server/go/http_util/http_util.go
@@ -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
}