X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/2697f35c5356e4aa6c0ca9c59068980c0ef25d61..c9c0706ab97753cc8517096b66057d418908cd35:/lib/controller/router/response.go diff --git a/lib/controller/router/response.go b/lib/controller/router/response.go index 3eba611450..543e25d0ce 100644 --- a/lib/controller/router/response.go +++ b/lib/controller/router/response.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "git.curoverse.com/arvados.git/sdk/go/arvados" - "git.curoverse.com/arvados.git/sdk/go/httpserver" + "git.arvados.org/arvados.git/sdk/go/arvados" + "git.arvados.org/arvados.git/sdk/go/httpserver" ) const rfc3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" @@ -45,16 +45,25 @@ func applySelectParam(selectParam []string, orig map[string]interface{}) map[str selected[attr] = v } } - // Preserve "kind" even if not requested - if v, ok := orig["kind"]; ok { - selected["kind"] = v + // Some keys are always preserved, even if not requested + for _, k := range []string{"etag", "kind", "writable_by"} { + if v, ok := orig[k]; ok { + selected[k] = v + } } return selected } -func (rtr *router) sendResponse(w http.ResponseWriter, resp interface{}, opts responseOptions) { +func (rtr *router) sendResponse(w http.ResponseWriter, req *http.Request, resp interface{}, opts responseOptions) { var tmp map[string]interface{} + if resp, ok := resp.(http.Handler); ok { + // resp knows how to write its own http response + // header and body. + resp.ServeHTTP(w, req) + return + } + err := rtr.transcode(resp, &tmp) if err != nil { rtr.sendError(w, err) @@ -65,18 +74,28 @@ func (rtr *router) sendResponse(w http.ResponseWriter, resp interface{}, opts re if respKind != "" { tmp["kind"] = respKind } + defaultItemKind := "" + if strings.HasSuffix(respKind, "List") { + defaultItemKind = strings.TrimSuffix(respKind, "List") + } if items, ok := tmp["items"].([]interface{}); ok { for i, item := range items { - // Fill in "kind" by inspecting UUID + // Fill in "kind" by inspecting UUID/PDH if + // possible; fall back on assuming each + // Items[] entry in an "arvados#fooList" + // response should have kind="arvados#foo". item, _ := item.(map[string]interface{}) - uuid, _ := item["uuid"].(string) - if len(uuid) != 27 { - // unsure whether this happens - } else if t, ok := infixMap[uuid[6:11]]; !ok { - // infix not listed in infixMap - } else if k := kind(t); k != "" { + infix := "" + if uuid, _ := item["uuid"].(string); len(uuid) == 27 { + infix = uuid[6:11] + } + if k := kind(infixMap[infix]); k != "" { item["kind"] = k + } else if pdh, _ := item["portable_data_hash"].(string); pdh != "" { + item["kind"] = "arvados#collection" + } else if defaultItemKind != "" { + item["kind"] = defaultItemKind } items[i] = applySelectParam(opts.Select, item) } @@ -110,7 +129,10 @@ func (rtr *router) sendResponse(w http.ResponseWriter, resp interface{}, opts re tmp[k] = t.Format(rfc3339NanoFixed) } } - json.NewEncoder(w).Encode(tmp) + w.Header().Set("Content-Type", "application/json") + enc := json.NewEncoder(w) + enc.SetEscapeHTML(false) + enc.Encode(tmp) } func (rtr *router) sendError(w http.ResponseWriter, err error) {