storage: report a view URL in /upload responses if configured
Change-Id: I5e10082adc66e51898a71e1a67da7833f287af9d
Reviewed-on: https://go-review.googlesource.com/35067
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/storage/app/app.go b/storage/app/app.go
index fea66b0..3db5b7f 100644
--- a/storage/app/app.go
+++ b/storage/app/app.go
@@ -25,6 +25,11 @@
// If necessary, it can write its own response (e.g. a
// redirect) and return ErrResponseWritten.
Auth func(http.ResponseWriter, *http.Request) (string, error)
+
+ // ViewURLBase will be used to construct a URL to return as
+ // "viewurl" in the response from /upload. If it is non-empty,
+ // the upload ID will be appended to ViewURLBase.
+ ViewURLBase string
}
// ErrResponseWritten can be returned by App.Auth to abort the normal /upload handling.
diff --git a/storage/app/upload.go b/storage/app/upload.go
index 60467df..68a378f 100644
--- a/storage/app/upload.go
+++ b/storage/app/upload.go
@@ -11,6 +11,7 @@
"io"
"mime/multipart"
"net/http"
+ "net/url"
"sort"
"golang.org/x/net/context"
@@ -71,6 +72,8 @@
UploadID string `json:"uploadid"`
// FileIDs is the list of file IDs assigned to the files in the upload.
FileIDs []string `json:"fileids"`
+ // ViewURL is a URL that can be used to interactively view the upload.
+ ViewURL string `json:"viewurl,omitempty"`
}
// processUpload takes one or more files from a multipart.Reader,
@@ -118,7 +121,12 @@
fileids = append(fileids, meta["fileid"])
}
- return &uploadStatus{upload.ID, fileids}, nil
+ status := &uploadStatus{UploadID: upload.ID, FileIDs: fileids}
+ if a.ViewURLBase != "" {
+ status.ViewURL = a.ViewURLBase + url.QueryEscape(upload.ID)
+ }
+
+ return status, nil
}
func (a *App) indexFile(ctx context.Context, upload *db.Upload, p io.Reader, meta map[string]string) (err error) {
diff --git a/storage/app/upload_test.go b/storage/app/upload_test.go
index 7f976e0..5560c0e 100644
--- a/storage/app/upload_test.go
+++ b/storage/app/upload_test.go
@@ -12,6 +12,7 @@
"mime/multipart"
"net/http"
"net/http/httptest"
+ "reflect"
"testing"
"golang.org/x/perf/storage/db"
@@ -44,9 +45,10 @@
fs := fs.NewMemFS()
app := &App{
- DB: db,
- FS: fs,
- Auth: func(http.ResponseWriter, *http.Request) (string, error) { return "user", nil },
+ DB: db,
+ FS: fs,
+ Auth: func(http.ResponseWriter, *http.Request) (string, error) { return "user", nil },
+ ViewURLBase: "view:",
}
mux := http.NewServeMux()
@@ -94,7 +96,7 @@
app := createTestApp(t)
defer app.Close()
- app.uploadFiles(t, func(mpw *multipart.Writer) {
+ status := app.uploadFiles(t, func(mpw *multipart.Writer) {
w, err := mpw.CreateFormFile("file", "1.txt")
if err != nil {
t.Errorf("CreateFormFile: %v", err)
@@ -102,6 +104,16 @@
fmt.Fprintf(w, "key: value\nBenchmarkOne 5 ns/op\nkey:value2\nBenchmarkTwo 10 ns/op\n")
})
+ if status.UploadID != "1" {
+ t.Errorf("uploadid = %q, want %q", status.UploadID, "1")
+ }
+ if have, want := status.FileIDs, []string{"1/0"}; !reflect.DeepEqual(have, want) {
+ t.Errorf("fileids = %v, want %v", have, want)
+ }
+ if status.ViewURL != "view:1" {
+ t.Errorf("viewurl = %q, want %q", status.ViewURL, "view:1")
+ }
+
if len(app.fs.Files()) != 1 {
t.Errorf("/upload wrote %d files, want 1", len(app.fs.Files()))
}
diff --git a/storage/appengine/app.go b/storage/appengine/app.go
index 498e812..d948f81 100644
--- a/storage/appengine/app.go
+++ b/storage/appengine/app.go
@@ -65,7 +65,8 @@
// It creates a new App instance using the appengine Context and then
// dispatches the request to the App. The environment variable
// GCS_BUCKET must be set in app.yaml with the name of the bucket to
-// write to.
+// write to. PERFDATA_VIEW_URL_BASE may be set to the URL that should
+// be supplied in /upload responses.
func appHandler(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
// GCS clients need to be constructed with an AppEngine
@@ -88,7 +89,7 @@
return
}
mux := http.NewServeMux()
- app := &app.App{DB: db, FS: fs, Auth: auth}
+ app := &app.App{DB: db, FS: fs, Auth: auth, ViewURLBase: os.Getenv("PERFDATA_VIEW_URL_BASE")}
app.RegisterOnMux(mux)
mux.ServeHTTP(w, r)
}
diff --git a/storage/appengine/app.yaml b/storage/appengine/app.yaml
index 757ceb8..05e4621 100644
--- a/storage/appengine/app.yaml
+++ b/storage/appengine/app.yaml
@@ -21,3 +21,4 @@
CLOUDSQL_PASSWORD: ''
CLOUDSQL_DATABASE: perfdata
GCS_BUCKET: golang-perfdata
+ PERFDATA_VIEW_URL_BASE: https://perf.golang.org/search?q=uploadid: