[ARVADOS] updated: 40ec18b8fc06ee9c37e88be8c55e9c46af546efd

git at public.curoverse.com git at public.curoverse.com
Wed Jun 17 02:24:13 EDT 2015


Summary of changes:
 sdk/go/arvadosclient/collectionreader.go | 24 +++++++++++++
 services/arv-git-httpd/auth_handler.go   |  2 +-
 services/arv-git-httpd/server.go         |  1 +
 services/keepdl/handler.go               |  5 ++-
 services/keepdl/server.go                |  1 +
 services/keepdl/server_test.go           | 60 +++++++++++++++++---------------
 6 files changed, 63 insertions(+), 30 deletions(-)
 create mode 100644 sdk/go/arvadosclient/collectionreader.go

  discards  0e244ff2826dee32b92fd007c65a84d065740b4c (commit)
  discards  0c9a309ac1fa0466b6e6bf07b8dcd3b554ae4425 (commit)
  discards  efbd939ea473a056d71874104bda054bde95cc0e (commit)
  discards  3c1dc695b209a9b1f4a95e72e39efb67080ce2e8 (commit)
       via  40ec18b8fc06ee9c37e88be8c55e9c46af546efd (commit)
       via  e48e9554fb8b90ef03c037ea6f0135160258997d (commit)
       via  1ce1b0a4e586bb8d665f63c05a11de1332ac2ba3 (commit)
       via  e7edfc19e29bb61aa077b76b6857653e2eaaf5d3 (commit)
       via  7b8223b2b7ec8ba611bfc5250d3183cf297a0ebe (commit)

This update added new revisions after undoing existing revisions.  That is
to say, the old revision is not a strict subset of the new revision.  This
situation occurs when you --force push a change and generate a repository
containing something like this:

 * -- * -- B -- O -- O -- O (0e244ff2826dee32b92fd007c65a84d065740b4c)
            \
             N -- N -- N (40ec18b8fc06ee9c37e88be8c55e9c46af546efd)

When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 40ec18b8fc06ee9c37e88be8c55e9c46af546efd
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Jun 17 02:23:36 2015 -0400

    5824: Add keepdl.

diff --git a/sdk/go/arvadosclient/arvadosclient.go b/sdk/go/arvadosclient/arvadosclient.go
index bb06126..d2d76e9 100644
--- a/sdk/go/arvadosclient/arvadosclient.go
+++ b/sdk/go/arvadosclient/arvadosclient.go
@@ -270,6 +270,21 @@ func (this ArvadosClient) Update(resource string, uuid string, parameters Dict,
 	return this.Call("PUT", resource, uuid, "", parameters, output)
 }
 
+// Get a resource.
+func (c ArvadosClient) Get(resource string, uuid string, parameters Dict, output interface{}) (err error) {
+	if uuid == "" {
+		// There's no endpoint for that because GET /type/ is
+		// the List API. If there were an endpoint, the
+		// response would be 404: no object has uuid == "".
+		return APIServerError{
+			ServerAddress:     c.ApiServer,
+			HttpStatusCode:    404,
+			HttpStatusMessage: "Not Found",
+		}
+	}
+	return c.Call("GET", resource, uuid, "", parameters, output)
+}
+
 // List the instances of a resource
 //
 //   resource - the arvados resource on which to list
diff --git a/sdk/go/arvadosclient/arvadosclient_test.go b/sdk/go/arvadosclient/arvadosclient_test.go
index 6a9e13b..c2cf83e 100644
--- a/sdk/go/arvadosclient/arvadosclient_test.go
+++ b/sdk/go/arvadosclient/arvadosclient_test.go
@@ -62,6 +62,13 @@ func (s *ServerRequiredSuite) TestCreatePipelineTemplate(c *C) {
 	c.Assert(getback["components"].(map[string]interface{})["c2"].(map[string]interface{})["script"], Equals, "script2")
 
 	uuid := getback["uuid"].(string)
+
+	getback = make(Dict)
+	err = arv.Get("pipeline_templates", uuid, nil, &getback)
+	c.Assert(err, Equals, nil)
+	c.Assert(getback["name"], Equals, "tmp")
+	c.Assert(getback["components"].(map[string]interface{})["c1"].(map[string]interface{})["script"], Equals, "script1")
+
 	getback = make(Dict)
 	err = arv.Update("pipeline_templates", uuid,
 		Dict{
diff --git a/sdk/go/arvadosclient/collectionreader.go b/sdk/go/arvadosclient/collectionreader.go
new file mode 100644
index 0000000..c04914b
--- /dev/null
+++ b/sdk/go/arvadosclient/collectionreader.go
@@ -0,0 +1,24 @@
+package arvadosclient
+
+import (
+	"errors"
+	"io"
+	"os"
+	"strings"
+)
+
+var (
+	ErrNoManifest = errors.New("Collection has no manifest")
+	ErrNotImplemented = errors.New("Not implemented")
+)
+
+func CollectionFileReader(collection map[string]interface{}, filename string) (io.Reader, error) {
+	m, ok := collection["manifest_text"].(string)
+	if !ok {
+		return nil, ErrNoManifest
+	}
+	if filename == "" || !strings.Contains(m, ":"+strings.Replace(filename, " ", `\040`, -1)) {
+		return nil, os.ErrNotExist
+	}
+	return nil, ErrNotImplemented
+}
diff --git a/services/keepdl/.gitignore b/services/keepdl/.gitignore
new file mode 100644
index 0000000..173e306
--- /dev/null
+++ b/services/keepdl/.gitignore
@@ -0,0 +1 @@
+keepdl
diff --git a/services/keepdl/handler.go b/services/keepdl/handler.go
new file mode 100644
index 0000000..bbcd53c
--- /dev/null
+++ b/services/keepdl/handler.go
@@ -0,0 +1,153 @@
+package main
+
+import (
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"strings"
+
+	"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
+	"git.curoverse.com/arvados.git/sdk/go/auth"
+	"git.curoverse.com/arvados.git/sdk/go/httpserver"
+)
+
+var clientPool = arvadosclient.MakeClientPool()
+
+var anonymousTokens []string
+
+type handler struct{}
+
+func init() {
+	// TODO(TC): Get anonymousTokens from flags
+	anonymousTokens = []string{}
+}
+
+func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
+	var statusCode int
+	var statusText string
+
+	w := httpserver.WrapResponseWriter(wOrig)
+	defer func() {
+		if statusCode > 0 {
+			if w.WroteStatus() == 0 {
+				w.WriteHeader(statusCode)
+			} else {
+				httpserver.Log(r.RemoteAddr, "WARNING",
+					fmt.Sprintf("Our status changed from %d to %d after we sent headers", w.WroteStatus(), statusCode))
+			}
+		}
+		if statusText == "" {
+			statusText = http.StatusText(statusCode)
+		}
+		httpserver.Log(r.RemoteAddr, statusCode, statusText, w.WroteBodyBytes(), r.Method, r.URL.Path)
+	}()
+
+	arv := clientPool.Get()
+	if arv == nil {
+		statusCode, statusText = http.StatusInternalServerError, "Pool failed: "+clientPool.Err().Error()
+		return
+	}
+	defer clientPool.Put(arv)
+
+	pathParts := strings.Split(r.URL.Path[1:], "/")
+
+	if len(pathParts) < 3 || pathParts[0] != "collections" || pathParts[1] == "" || pathParts[2] == "" {
+		statusCode = http.StatusNotFound
+		return
+	}
+
+	var targetId string
+	var targetPath []string
+	var tokens []string
+	var reqTokens []string
+	var pathToken bool
+	if len(pathParts) >= 5 && pathParts[1] == "download" {
+		// "/collections/download/{id}/{token}/path..." form:
+		// Don't use our configured anonymous tokens,
+		// Authorization headers, etc.  Just use the token in
+		// the path.
+		targetId = pathParts[2]
+		tokens = []string{pathParts[3]}
+		targetPath = pathParts[4:]
+		pathToken = true
+	} else {
+		// "/collections/{id}/path..." form
+		targetId = pathParts[1]
+		reqTokens = auth.NewCredentialsFromHTTPRequest(r).Tokens
+		tokens = append(reqTokens, anonymousTokens...)
+		targetPath = pathParts[2:]
+	}
+
+	tokenResult := make(map[string]int)
+	collection := make(map[string]interface{})
+	found := false
+	for _, arv.ApiToken = range tokens {
+		err := arv.Get("collections", targetId, nil, &collection)
+		httpserver.Log(err)
+		if err == nil {
+			// Success
+			found = true
+			break
+		}
+		if srvErr, ok := err.(arvadosclient.APIServerError); ok {
+			switch srvErr.HttpStatusCode {
+			case 404, 401:
+				// Token broken or insufficient to
+				// retrieve collection
+				tokenResult[arv.ApiToken] = srvErr.HttpStatusCode
+				continue
+			}
+		}
+		// Something more serious is wrong
+		statusCode, statusText = http.StatusInternalServerError, err.Error()
+		return
+	}
+	if !found {
+		if pathToken {
+			// The URL is a "secret sharing link", but it
+			// didn't work out. Asking the client for
+			// additional credentials would just be
+			// confusing.
+			statusCode = http.StatusNotFound
+			return
+		}
+		for _, t := range reqTokens {
+			if tokenResult[t] == 404 {
+				// The client provided valid token(s), but the
+				// collection was not found.
+				statusCode = http.StatusNotFound
+				return
+			}
+		}
+		// The client's token was invalid (e.g., expired), or
+		// the client didn't even provide one.  Propagate the
+		// 401 to encourage the client to use a [different]
+		// token.
+		//
+		// TODO(TC): This response would be confusing to
+		// someone trying (anonymously) to download public
+		// data that has been deleted.  Allow a referrer to
+		// provide this context somehow?
+		statusCode = http.StatusUnauthorized
+		w.Header().Add("WWW-Authenticate", "Basic realm=\"dl\"")
+		return
+	}
+
+	filename := strings.Join(targetPath, "/")
+	rdr, err := arvadosclient.CollectionFileReader(collection, filename)
+	if os.IsNotExist(err) {
+		statusCode = http.StatusNotFound
+		return
+	} else if err == arvadosclient.ErrNotImplemented {
+		statusCode = http.StatusNotImplemented
+		return
+	} else if err != nil {
+		statusCode, statusText = http.StatusBadGateway, err.Error()
+		return
+	}
+	_, err = io.Copy(w, rdr)
+	if err != nil {
+		statusCode, statusText = http.StatusBadGateway, err.Error()
+	}
+}
diff --git a/services/keepdl/main.go b/services/keepdl/main.go
new file mode 100644
index 0000000..d780cc3
--- /dev/null
+++ b/services/keepdl/main.go
@@ -0,0 +1,28 @@
+package main
+
+import (
+	"flag"
+	"log"
+	"os"
+)
+
+func init() {
+	// MakeArvadosClient returns an error if this env var isn't
+	// available as a default token (even if we explicitly set a
+	// different token before doing anything with the client). We
+	// set this dummy value during init so it doesn't clobber the
+	// one used by "run test servers".
+	os.Setenv("ARVADOS_API_TOKEN", "xxx")
+}
+
+func main() {
+	flag.Parse()
+	srv := &server{}
+	if err := srv.Start(); err != nil {
+		log.Fatal(err)
+	}
+	log.Println("Listening at", srv.Addr)
+	if err := srv.Wait(); err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/services/keepdl/server.go b/services/keepdl/server.go
new file mode 100644
index 0000000..44da00f
--- /dev/null
+++ b/services/keepdl/server.go
@@ -0,0 +1,27 @@
+package main
+
+import (
+	"flag"
+	"net/http"
+
+	"git.curoverse.com/arvados.git/sdk/go/httpserver"
+)
+
+var address string
+
+func init() {
+	flag.StringVar(&address, "address", "0.0.0.0:80",
+		"Address to listen on, \"host:port\".")
+}
+
+type server struct {
+	httpserver.Server
+}
+
+func (srv *server) Start() error {
+	mux := http.NewServeMux()
+	mux.Handle("/", &handler{})
+	srv.Handler = mux
+	srv.Addr = address
+	return srv.Server.Start()
+}
diff --git a/services/keepdl/server_test.go b/services/keepdl/server_test.go
new file mode 100644
index 0000000..1c36f98
--- /dev/null
+++ b/services/keepdl/server_test.go
@@ -0,0 +1,170 @@
+package main
+
+import (
+	"crypto/md5"
+	"fmt"
+	"os/exec"
+	"strings"
+	"testing"
+
+	"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
+	"git.curoverse.com/arvados.git/sdk/go/arvadostest"
+	"git.curoverse.com/arvados.git/sdk/go/keepclient"
+	check "gopkg.in/check.v1"
+)
+
+var _ = check.Suite(&IntegrationSuite{})
+
+const (
+	spectatorToken  = "zw2f4gwx8hw8cjre7yp6v1zylhrhn3m5gvjq73rtpwhmknrybu"
+	activeToken     = "3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi"
+	anonymousToken  = "4kg6k6lzmp9kj4cpkcoxie964cmvjahbt4fod9zru44k4jqdmi"
+	fooCollection   = "zzzzz-4zz18-fy296fx3hot09f7"
+	bogusCollection = "zzzzz-4zz18-totallynotexist"
+	hwCollection    = "zzzzz-4zz18-4en62shvi99lxd4"
+)
+
+// IntegrationSuite tests need an API server and an arv-git-httpd server
+type IntegrationSuite struct {
+	testServer *server
+}
+
+func (s *IntegrationSuite) TestNoToken(c *check.C) {
+	for _, token := range []string{
+		"",
+		"bogustoken",
+	} {
+		hdr, body := s.runCurl(c, token, "/collections/"+fooCollection+"/foo")
+		c.Check(hdr, check.Matches, `(?s)HTTP/1.1 401 Unauthorized\r\n.*`)
+		c.Check(body, check.Equals, "")
+
+		if token != "" {
+			hdr, body = s.runCurl(c, token, "/collections/download/"+fooCollection+"/"+token+"/foo")
+			c.Check(hdr, check.Matches, `(?s)HTTP/1.1 404 Not Found\r\n.*`)
+			c.Check(body, check.Equals, "")
+		}
+
+		hdr, body = s.runCurl(c, token, "/bad-route")
+		c.Check(hdr, check.Matches, `(?s)HTTP/1.1 404 Not Found\r\n.*`)
+		c.Check(body, check.Equals, "")
+	}
+}
+
+// TODO: Move most cases to functional tests -- at least use Go's own
+// http client instead of forking curl. Just leave enough of an
+// integration test to assure that the documented way of invoking curl
+// really works against the server.
+func (s *IntegrationSuite) Test404(c *check.C) {
+	for _, uri := range []string{
+		// Routing errors
+		"/",
+		"/foo",
+		"/download",
+		"/collections",
+		"/collections/",
+		"/collections/" + fooCollection,
+		"/collections/" + fooCollection + "/",
+		// Non-existent file in collection
+		"/collections/" + fooCollection + "/theperthcountyconspiracy",
+		"/collections/download/" + fooCollection + "/" + activeToken + "/theperthcountyconspiracy",
+		// Non-existent collection
+		"/collections/" + bogusCollection,
+		"/collections/" + bogusCollection + "/",
+		"/collections/" + bogusCollection + "/theperthcountyconspiracy",
+		"/collections/download/" + bogusCollection + "/" + activeToken + "/theperthcountyconspiracy",
+	} {
+		hdr, body := s.runCurl(c, activeToken, uri)
+		c.Check(hdr, check.Matches, "(?s)HTTP/1.1 404 Not Found\r\n.*")
+		c.Check(body, check.Equals, "")
+	}
+}
+
+func (s *IntegrationSuite) Test200(c *check.C) {
+	anonymousTokens = []string{anonymousToken}
+	arv, err := arvadosclient.MakeArvadosClient()
+	c.Assert(err, check.Equals, nil)
+	arv.ApiToken = activeToken
+	kc, err := keepclient.MakeKeepClient(&arv)
+	c.Assert(err, check.Equals, nil)
+	kc.PutB([]byte("Hello world\n"))
+	kc.PutB([]byte("foo"))
+	for _, spec := range [][]string{
+		// My collection
+		{activeToken, "/collections/" + fooCollection + "/foo", "acbd18db4cc2f85cedef654fccc4a4d8"},
+		{"", "/collections/download/" + fooCollection + "/" + activeToken + "/foo", "acbd18db4cc2f85cedef654fccc4a4d8"},
+		{"tokensobogus", "/collections/download/" + fooCollection + "/" + activeToken + "/foo", "acbd18db4cc2f85cedef654fccc4a4d8"},
+		{activeToken, "/collections/download/" + fooCollection + "/" + activeToken + "/foo", "acbd18db4cc2f85cedef654fccc4a4d8"},
+		{anonymousToken, "/collections/download/" + fooCollection + "/" + activeToken + "/foo", "acbd18db4cc2f85cedef654fccc4a4d8"},
+		// Anonymously accessible user agreement. These should
+		// start working when CollectionFileReader provides
+		// real data instead of fake/stub data.
+		{"", "/collections/"+hwCollection+"/Hello%20world.txt", "f0ef7081e1539ac00ef5b761b4fb01b3"},
+		{activeToken, "/collections/"+hwCollection+"/Hello%20world.txt", "f0ef7081e1539ac00ef5b761b4fb01b3"},
+		{spectatorToken, "/collections/"+hwCollection+"/Hello%20world.txt", "f0ef7081e1539ac00ef5b761b4fb01b3"},
+		{spectatorToken, "/collections/download/"+hwCollection+"/"+spectatorToken+"/Hello%20world.txt", "f0ef7081e1539ac00ef5b761b4fb01b3"},
+	} {
+		hdr, body := s.runCurl(c, spec[0], spec[1])
+		if strings.HasPrefix(hdr, "HTTP/1.1 501 Not Implemented\r\n") && body == "" {
+			c.Log("Not implemented!")
+			continue
+		}
+		c.Check(hdr, check.Matches, `(?s)HTTP/1.1 200 OK\r\n.*`)
+		c.Check(fmt.Sprintf("%x", md5.Sum([]byte(body))), check.Equals, spec[2])
+	}
+}
+
+// Return header block and body.
+func (s *IntegrationSuite) runCurl(c *check.C, token, uri string, args ...string) (hdr, body string) {
+	curlArgs := []string{"--silent", "--show-error", "--include"}
+	if token != "" {
+		curlArgs = append(curlArgs, "-H", "Authorization: OAuth2 "+token)
+	}
+	curlArgs = append(curlArgs, args...)
+	curlArgs = append(curlArgs, "http://"+s.testServer.Addr+uri)
+	c.Log(fmt.Sprintf("curlArgs == %#v", curlArgs))
+	output, err := exec.Command("curl", curlArgs...).CombinedOutput()
+	// Without "-f", curl exits 0 as long as it gets a valid HTTP
+	// response from the server, even if the response status
+	// indicates that the request failed. In our test suite, we
+	// always expect a valid HTTP response, and we parse the
+	// headers ourselves. If curl exits non-zero, our testing
+	// environment is broken.
+	c.Assert(err, check.Equals, nil)
+	hdrsAndBody := strings.SplitN(string(output), "\r\n\r\n", 2)
+	c.Assert(len(hdrsAndBody), check.Equals, 2)
+	hdr = hdrsAndBody[0]
+	body = hdrsAndBody[1]
+	return
+}
+
+func (s *IntegrationSuite) SetUpSuite(c *check.C) {
+	arvadostest.StartAPI()
+	arvadostest.StartKeep()
+}
+
+func (s *IntegrationSuite) TearDownSuite(c *check.C) {
+	arvadostest.StopKeep()
+	arvadostest.StopAPI()
+}
+
+func (s *IntegrationSuite) SetUpTest(c *check.C) {
+	arvadostest.ResetEnv()
+	s.testServer = &server{}
+	var err error
+	address = "127.0.0.1:0"
+	err = s.testServer.Start()
+	c.Assert(err, check.Equals, nil)
+}
+
+func (s *IntegrationSuite) TearDownTest(c *check.C) {
+	var err error
+	if s.testServer != nil {
+		err = s.testServer.Close()
+	}
+	c.Check(err, check.Equals, nil)
+}
+
+// Gocheck boilerplate
+func Test(t *testing.T) {
+	check.TestingT(t)
+}

commit e48e9554fb8b90ef03c037ea6f0135160258997d
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Jun 17 00:47:12 2015 -0400

    Shut down API server after suite (noticed during 5824, otherwise no issue #)

diff --git a/services/arv-git-httpd/server_test.go b/services/arv-git-httpd/server_test.go
index e5ddc29..318ba8a 100644
--- a/services/arv-git-httpd/server_test.go
+++ b/services/arv-git-httpd/server_test.go
@@ -74,6 +74,10 @@ func (s *IntegrationSuite) SetUpSuite(c *check.C) {
 	arvadostest.StartAPI()
 }
 
+func (s *IntegrationSuite) TearDownSuite(c *check.C) {
+	arvadostest.StopAPI()
+}
+
 func (s *IntegrationSuite) SetUpTest(c *check.C) {
 	arvadostest.ResetEnv()
 	s.testServer = &server{}

commit 1ce1b0a4e586bb8d665f63c05a11de1332ac2ba3
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Jun 12 02:43:19 2015 -0400

    5824: Move client pool to SDK.

diff --git a/sdk/go/arvadosclient/pool.go b/sdk/go/arvadosclient/pool.go
new file mode 100644
index 0000000..1c5893a
--- /dev/null
+++ b/sdk/go/arvadosclient/pool.go
@@ -0,0 +1,39 @@
+package arvadosclient
+
+import (
+	"sync"
+)
+
+type ClientPool struct {
+	sync.Pool
+	lastErr error
+}
+
+func MakeClientPool() *ClientPool {
+	p := &ClientPool{}
+	p.Pool = sync.Pool{New: func() interface{} {
+		arv, err := MakeArvadosClient()
+		if err != nil {
+			p.lastErr = err
+			return nil
+		}
+		return &arv
+	}}
+	return p
+}
+
+func (p *ClientPool) Err() error {
+	return p.lastErr
+}
+
+func (p *ClientPool) Get() *ArvadosClient {
+	c, ok := p.Pool.Get().(*ArvadosClient)
+	if !ok {
+		return nil
+	}
+	return c
+}
+
+func (p *ClientPool) Put(c *ArvadosClient) {
+	p.Pool.Put(c)
+}
diff --git a/services/arv-git-httpd/auth_handler.go b/services/arv-git-httpd/auth_handler.go
index d60f380..0fb1567 100644
--- a/services/arv-git-httpd/auth_handler.go
+++ b/services/arv-git-httpd/auth_handler.go
@@ -6,7 +6,6 @@ import (
 	"net/http/cgi"
 	"os"
 	"strings"
-	"sync"
 	"time"
 
 	"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
@@ -14,16 +13,7 @@ import (
 	"git.curoverse.com/arvados.git/sdk/go/httpserver"
 )
 
-func newArvadosClient() interface{} {
-	arv, err := arvadosclient.MakeArvadosClient()
-	if err != nil {
-		log.Println("MakeArvadosClient:", err)
-		return nil
-	}
-	return &arv
-}
-
-var connectionPool = &sync.Pool{New: newArvadosClient}
+var clientPool = arvadosclient.MakeClientPool()
 
 type authHandler struct {
 	handler *cgi.Handler
@@ -66,12 +56,12 @@ func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	repoName = pathParts[0]
 	repoName = strings.TrimRight(repoName, "/")
 
-	arv, ok := connectionPool.Get().(*arvadosclient.ArvadosClient)
-	if !ok || arv == nil {
-		statusCode, statusText = http.StatusInternalServerError, "connection pool failed"
+	arv := clientPool.Get()
+	if arv == nil {
+		statusCode, statusText = http.StatusInternalServerError, "connection pool failed: "+clientPool.Err().Error()
 		return
 	}
-	defer connectionPool.Put(arv)
+	defer clientPool.Put(arv)
 
 	// Ask API server whether the repository is readable using
 	// this token (by trying to read it!)

commit e7edfc19e29bb61aa077b76b6857653e2eaaf5d3
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Jun 12 01:53:05 2015 -0400

    5824: Move quoted-logging function to SDK.

diff --git a/sdk/go/httpserver/log.go b/sdk/go/httpserver/log.go
new file mode 100644
index 0000000..7bee887
--- /dev/null
+++ b/sdk/go/httpserver/log.go
@@ -0,0 +1,23 @@
+package httpserver
+
+import (
+	"log"
+	"strings"
+)
+
+var escaper = strings.NewReplacer("\"", "\\\"", "\\", "\\\\", "\n", "\\n")
+
+// Log calls log.Println but first transforms strings so they are
+// safer to write in logs (e.g., 'foo"bar' becomes
+// '"foo\"bar"'). Non-string args are left alone.
+func Log(args ...interface{}) {
+	newargs := make([]interface{}, len(args))
+	for i, arg := range args {
+		if s, ok := arg.(string); ok {
+			newargs[i] = "\"" + escaper.Replace(s) + "\""
+		} else {
+			newargs[i] = arg
+		}
+	}
+	log.Println(newargs...)
+}
diff --git a/services/arv-git-httpd/auth_handler.go b/services/arv-git-httpd/auth_handler.go
index ba36a46..d60f380 100644
--- a/services/arv-git-httpd/auth_handler.go
+++ b/services/arv-git-httpd/auth_handler.go
@@ -44,7 +44,7 @@ func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 			w.WriteHeader(statusCode)
 			w.Write([]byte(statusText))
 		}
-		log.Println(quoteStrings(r.RemoteAddr, apiToken, w.WroteStatus(), statusText, repoName, r.Method, r.URL.Path)...)
+		httpserver.Log(r.RemoteAddr, apiToken, w.WroteStatus(), statusText, repoName, r.Method, r.URL.Path)
 	}()
 
 	creds := auth.NewCredentialsFromHTTPRequest(r)
@@ -150,16 +150,3 @@ func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
 	handlerCopy.Env = append(handlerCopy.Env, "REMOTE_USER="+r.RemoteAddr) // Should be username
 	handlerCopy.ServeHTTP(&w, r)
 }
-
-var escaper = strings.NewReplacer("\"", "\\\"", "\\", "\\\\", "\n", "\\n")
-
-// Transform strings so they are safer to write in logs (e.g.,
-// 'foo"bar' becomes '"foo\"bar"'). Non-string args are left alone.
-func quoteStrings(args ...interface{}) []interface{} {
-	for i, arg := range args {
-		if s, ok := arg.(string); ok {
-			args[i] = "\"" + escaper.Replace(s) + "\""
-		}
-	}
-	return args
-}

commit 7b8223b2b7ec8ba611bfc5250d3183cf297a0ebe
Author: Tom Clegg <tom at curoverse.com>
Date:   Wed Jun 17 01:57:33 2015 -0400

    5824: gofmt

diff --git a/services/arv-git-httpd/auth_handler.go b/services/arv-git-httpd/auth_handler.go
index 5e63fb7..ba36a46 100644
--- a/services/arv-git-httpd/auth_handler.go
+++ b/services/arv-git-httpd/auth_handler.go
@@ -9,8 +9,8 @@ import (
 	"sync"
 	"time"
 
-	"git.curoverse.com/arvados.git/sdk/go/auth"
 	"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
+	"git.curoverse.com/arvados.git/sdk/go/auth"
 	"git.curoverse.com/arvados.git/sdk/go/httpserver"
 )
 
diff --git a/services/arv-git-httpd/server.go b/services/arv-git-httpd/server.go
index 9e80481..c3c36da 100644
--- a/services/arv-git-httpd/server.go
+++ b/services/arv-git-httpd/server.go
@@ -3,6 +3,7 @@ package main
 import (
 	"net/http"
 	"net/http/cgi"
+
 	"git.curoverse.com/arvados.git/sdk/go/httpserver"
 )
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list