Commit 72f847b9 authored by Quentin Smith's avatar Quentin Smith

storage: report a view URL in /upload responses if configured

Change-Id: I5e10082adc66e51898a71e1a67da7833f287af9d
Reviewed-on: https://go-review.googlesource.com/35067Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 3c74c699
......@@ -25,6 +25,11 @@ type App struct {
// 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.
......
......@@ -11,6 +11,7 @@ import (
"io"
"mime/multipart"
"net/http"
"net/url"
"sort"
"golang.org/x/net/context"
......@@ -71,6 +72,8 @@ type uploadStatus struct {
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 @@ func (a *App) processUpload(ctx context.Context, user string, mr *multipart.Read
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) {
......
......@@ -12,6 +12,7 @@ import (
"mime/multipart"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"golang.org/x/perf/storage/db"
......@@ -44,9 +45,10 @@ func createTestApp(t *testing.T) *testApp {
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 @@ func TestUpload(t *testing.T) {
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 @@ func TestUpload(t *testing.T) {
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()))
}
......
......@@ -65,7 +65,8 @@ func auth(w http.ResponseWriter, r *http.Request) (string, error) {
// 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 @@ func appHandler(w http.ResponseWriter, r *http.Request) {
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)
}
......
......@@ -21,3 +21,4 @@ env_variables:
CLOUDSQL_PASSWORD: ''
CLOUDSQL_DATABASE: perfdata
GCS_BUCKET: golang-perfdata
PERFDATA_VIEW_URL_BASE: https://perf.golang.org/search?q=uploadid:
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment