cmd/coordinator: allow CORS requests to /try.json
Allow any origin to make cross-origin requests to get builder
statuses.
Also fixes a bug with an ineffectual Header().Set(...) call since
WriteHeader was called before it.
Change-Id: Ic2867624a286dad7268ddb94c3bb5afb52bf84ac
Reviewed-on: https://go-review.googlesource.com/98995
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/cmd/coordinator/coordinator.go b/cmd/coordinator/coordinator.go
index cdd147a..a2e48e6 100644
--- a/cmd/coordinator/coordinator.go
+++ b/cmd/coordinator/coordinator.go
@@ -553,7 +553,7 @@
ts.mu.Unlock()
}
if json {
- serveTryStatusJSON(w, ts, tss)
+ serveTryStatusJSON(w, r, ts, tss)
return
}
serveTryStatusHTML(w, ts, tss)
@@ -561,7 +561,12 @@
}
// tss is a clone that does not require ts' lock.
-func serveTryStatusJSON(w http.ResponseWriter, ts *trySet, tss trySetState) {
+func serveTryStatusJSON(w http.ResponseWriter, r *http.Request, ts *trySet, tss trySetState) {
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ if r.Method == "OPTIONS" {
+ // This is likely a pre-flight CORS request.
+ return
+ }
var resp struct {
Success bool `json:"success"`
Error string `json:"error,omitempty"`
@@ -574,9 +579,9 @@
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- w.WriteHeader(http.StatusNotFound)
w.Header().Set("Content-Type", "application/json")
- io.Copy(w, &buf)
+ w.WriteHeader(http.StatusNotFound)
+ w.Write(buf.Bytes())
return
}
type litebuild struct {
diff --git a/cmd/coordinator/coordinator_test.go b/cmd/coordinator/coordinator_test.go
index 5033ad9..d920ad4 100644
--- a/cmd/coordinator/coordinator_test.go
+++ b/cmd/coordinator/coordinator_test.go
@@ -29,19 +29,30 @@
func TestTryStatusJSON(t *testing.T) {
testCases := []struct {
desc string
+ method string
ts *trySet
tss trySetState
status int
body string
}{
{
+ "pre-flight CORS header",
+ "OPTIONS",
+ nil,
+ trySetState{},
+ http.StatusOK,
+ ``,
+ },
+ {
"nil trySet",
+ "GET",
nil,
trySetState{},
http.StatusNotFound,
`{"success":false,"error":"TryBot result not found (already done, invalid, or not yet discovered from Gerrit). Check Gerrit for results."}` + "\n",
},
{"non-nil trySet",
+ "GET",
&trySet{
tryKey: tryKey{
Commit: "deadbeef",
@@ -69,8 +80,16 @@
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
w := httptest.NewRecorder()
- serveTryStatusJSON(w, tc.ts, tc.tss)
+ r, err := http.NewRequest(tc.method, "", nil)
+ if err != nil {
+ t.Fatalf("could not create http.Request: %v", err)
+ }
+ serveTryStatusJSON(w, r, tc.ts, tc.tss)
resp := w.Result()
+ hdr := "Access-Control-Allow-Origin"
+ if got, want := resp.Header.Get(hdr), "*"; got != want {
+ t.Errorf("unexpected %q header: got %q; want %q", hdr, got, want)
+ }
if got, want := resp.StatusCode, tc.status; got != want {
t.Errorf("response status code: got %d; want %d", got, want)
}