From 295a7c38403d9591a5476bbeca98c5603c1c8692 Mon Sep 17 00:00:00 2001 From: "Stephen McQuay (smcquay)" Date: Fri, 3 Jun 2016 16:44:50 -0700 Subject: [PATCH] Only return the meta for requested package the go tool currenty has a pathology where it mistakingly claims it can't clone a repo because it checks prefix by bytes, not by splitting the path on slash. Once https://github.com/golang/go/issues/15947 comes out (go1.8) then go tools will be able to handle being provided with valid but overlapping packages. For now though we'll just return meta for the requested package. Change-Id: Ie5026e7d5c1377ff7d2c2140b21f9b745af69764 --- api_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ db.go | 7 +++++++ server.go | 18 ++++++++++++++---- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/api_test.go b/api_test.go index 31cf3e6..7f57892 100644 --- a/api_test.go +++ b/api_test.go @@ -508,3 +508,57 @@ func TestDelete(t *testing.T) { } } } + +func TestSingleGet(t *testing.T) { + db, done := testDB(t) + if db == nil { + t.Fatalf("could not create temp db") + } + defer done() + + sm := http.NewServeMux() + NewServer(sm, db, "", window) + ts := httptest.NewServer(sm) + + tok, err := db.addUser("sm@example.org") + if err != nil { + t.Fatalf("failure to add user: %v", err) + } + + ns := "foo" + + if err := db.NSForToken(ns, tok); err != nil { + t.Fatalf("could not initialize namespace %q for user %q: %v", ns, tok, err) + } + + p := Package{ + Vcs: "git", + Repo: "https://example.org/foo", + Path: fmt.Sprintf("%s/foo/bar", strings.TrimPrefix(ts.URL, "http://")), + Ns: ns, + } + if err := db.AddPackage(p); err != nil { + t.Fatalf("couldn't add package %v: %v", p, err) + } + + { + // expected failure + resp, err := http.Get(ts.URL + "/bleh/blah?go-get=1") + if err != nil { + t.Fatalf("problem getting route: %v", err) + } + if got, want := resp.StatusCode, http.StatusNotFound; got != want { + t.Fatalf("should have failed to GET unknown route; got %s, want %s", http.StatusText(got), http.StatusText(want)) + } + } + { + url := ts.URL + "/foo/bar?go-get=1" + resp, err := http.Get(url) + if err != nil { + t.Fatalf("problem getting route: %v", err) + } + if got, want := resp.StatusCode, http.StatusOK; got != want { + t.Fatalf("should have failed to GET unknown route; got %s, want %s", http.StatusText(got), http.StatusText(want)) + } + } +} diff --git a/db.go b/db.go index 197888b..3ed7384 100644 --- a/db.go +++ b/db.go @@ -1,6 +1,7 @@ package vain import ( + "database/sql" "fmt" "log" "net/http" @@ -100,6 +101,12 @@ func (db *DB) PackageExists(path string) bool { func (db *DB) Package(path string) (Package, error) { r := Package{} err := db.conn.Get(&r, "SELECT * FROM packages WHERE path = ?", path) + if err == sql.ErrNoRows { + return r, verrors.HTTP{ + Message: fmt.Sprintf("couldn't find package %q", path), + Code: http.StatusNotFound, + } + } return r, err } diff --git a/server.go b/server.go index 0b64ee6..94d2e73 100644 --- a/server.go +++ b/server.go @@ -54,11 +54,20 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { http.Redirect(w, req, prefix["static"], http.StatusTemporaryRedirect) return } - fmt.Fprintf(w, "\n\n") - for _, p := range s.db.Pkgs() { - fmt.Fprintf(w, "%s\n", p) + if req.URL.Path == "/" { + fmt.Fprintf(w, "\n\n") + for _, p := range s.db.Pkgs() { + fmt.Fprintf(w, "%s\n", p) + } + fmt.Fprintf(w, "\n

go tool metadata in head

\n\n") + } else { + p, err := s.db.Package(req.Host + req.URL.Path) + if err := verrors.ToHTTP(err); err != nil { + http.Error(w, err.Message, err.Code) + return + } + fmt.Fprintf(w, "\n\n%s\n\n

go tool metadata in head

\n\n", p) } - fmt.Fprintf(w, "\n

go tool metadata in head

\n\n") return } @@ -207,6 +216,7 @@ func (s *Server) forgot(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-type", "application/json") json.NewEncoder(w).Encode(resp) } + func (s *Server) pkgs(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-type", "application/json") json.NewEncoder(w).Encode(s.db.Pkgs())