-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for non-json reponse result to http.send builtin. #1264
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,8 @@ import ( | |
"crypto/tls" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"strconv" | ||
|
||
"net/http" | ||
|
@@ -27,6 +29,7 @@ var allowedKeyNames = [...]string{ | |
"url", | ||
"body", | ||
"enable_redirect", | ||
"force_json_decode", | ||
"headers", | ||
"tls_use_system_certs", | ||
"tls_ca_cert_file", | ||
|
@@ -127,6 +130,7 @@ func executeHTTPRequest(bctx BuiltinContext, obj ast.Object) (ast.Value, error) | |
var tlsClientKeyFile string | ||
var body *bytes.Buffer | ||
var enableRedirect bool | ||
var forceJSONDecode bool | ||
var tlsUseSystemCerts bool | ||
var tlsConfig tls.Config | ||
var clientCerts []tls.Certificate | ||
|
@@ -150,6 +154,11 @@ func executeHTTPRequest(bctx BuiltinContext, obj ast.Object) (ast.Value, error) | |
if err != nil { | ||
return nil, err | ||
} | ||
case "force_json_decode": | ||
forceJSONDecode, err = strconv.ParseBool(obj.Get(val).String()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
case "body": | ||
bodyVal := obj.Get(val).Value | ||
bodyValInterface, err := ast.JSON(bodyVal) | ||
|
@@ -272,12 +281,27 @@ func executeHTTPRequest(bctx BuiltinContext, obj ast.Object) (ast.Value, error) | |
|
||
// format the http result | ||
var resultBody interface{} | ||
json.NewDecoder(resp.Body).Decode(&resultBody) | ||
var resultRawBody []byte | ||
|
||
var buf bytes.Buffer | ||
tee := io.TeeReader(resp.Body, &buf) | ||
resultRawBody, err = ioutil.ReadAll(tee) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// If the response body cannot be JSON decoded, | ||
// an error will not be returned. Instead the "body" field | ||
// in the result will be null. | ||
if isContentTypeJSON(resp.Header) || forceJSONDecode { | ||
json.NewDecoder(&buf).Decode(&resultBody) | ||
} | ||
|
||
result := make(map[string]interface{}) | ||
result["status"] = resp.Status | ||
result["status_code"] = resp.StatusCode | ||
result["body"] = resultBody | ||
result["raw_body"] = string(resultRawBody) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, what happens if the raw body contains binary characters? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the response body contains binary characters, the raw body will have them too. |
||
|
||
resultObj, err := ast.InterfaceToValue(result) | ||
if err != nil { | ||
|
@@ -291,6 +315,10 @@ func executeHTTPRequest(bctx BuiltinContext, obj ast.Object) (ast.Value, error) | |
return resultObj, nil | ||
} | ||
|
||
func isContentTypeJSON(header http.Header) bool { | ||
return strings.Contains(header.Get("Content-Type"), "application/json") | ||
} | ||
|
||
// getCtxKey returns the cache key. | ||
// Key format: <METHOD>_<url> | ||
func getCtxKey(method string, url string) string { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a note.