fc/http_handler_response.go (85 lines of code) (raw):

// Copyright 2021 Alibaba Group Holding Limited. All Rights Reserved. package fc import ( "bytes" "encoding/base64" "encoding/json" "net/http" "strings" "time" ) // fcResponse implements http.ResponseWriter. // // The response body not support stream write. type fcResponse struct { req *http.Request status int wroteHeader bool header http.Header body bytes.Buffer contentLength int64 // explicitly-declared Content-Length; or -1 } func newFcResponse(req *http.Request) *fcResponse { return &fcResponse{ req: req, contentLength: -1, header: http.Header{}, body: bytes.Buffer{}, } } func (r *fcResponse) Header() http.Header { return r.header } func (r *fcResponse) Write(p []byte) (n int, err error) { if !r.wroteHeader { r.WriteHeader(http.StatusOK) } return r.body.Write(p) } func (r *fcResponse) WriteHeader(statusCode int) { if r.wroteHeader { return } r.wroteHeader = true r.status = statusCode if r.header.Get("Date") == "" { r.header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) } } func (r *fcResponse) responseParams() (string, error) { respParams := map[string]interface{}{ "status": r.status, "headersMap": r.header, } respParamsStr, err := json.Marshal(respParams) if err != nil { return "", err } encoded := base64.StdEncoding.EncodeToString(respParamsStr) return encoded, nil } // Deprecated: Use Body and HttpParam instead func (r *fcResponse) Payload() ([]byte, error) { respHeaders := map[string]string{} for key, values := range r.header { respHeaders[key] = strings.Join(values, ", ") } encodedHttpParams, err := r.responseParams() if err != nil { return []byte{}, err } respHeaders[headerHttpParams] = encodedHttpParams // json.Marshal encoded []byte as a base64-encoded string // so `base64.StdEncoding.EncodeToString(r.body.Bytes())` is not necessary // see https://pkg.go.dev/encoding/json#Marshal resp := map[string]interface{}{ "headers": respHeaders, "body": r.body.Bytes(), "isBase64Encoded": true, } return json.Marshal(resp) } func (r *fcResponse) Body() []byte { body := r.body.Bytes() r.body.Reset() return body } func (r *fcResponse) HttpParam() (string, error) { encodedHttpParams, err := r.responseParams() if err != nil { return "", err } return encodedHttpParams, nil }