This is an automated email from the ASF dual-hosted git repository. dubeejw pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-client-go.git
The following commit(s) were added to refs/heads/master by this push: new 4a63a30 Added changes for classes and variables casing to be get exported and can be used in other places (#2675) (#38) 4a63a30 is described below commit 4a63a306d52f5dd54454e0ba38e0c7eb9cb2852b Author: Vincent <s...@us.ibm.com> AuthorDate: Mon Sep 25 14:12:46 2017 -0400 Added changes for classes and variables casing to be get exported and can be used in other places (#2675) (#38) * Updating classes and variables so that they are exported and usable by other modules * Updating missed debug statements to have case of client -> Client --- whisk/client.go | 161 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 55 deletions(-) diff --git a/whisk/client.go b/whisk/client.go index 3d6b655..aea23ec 100644 --- a/whisk/client.go +++ b/whisk/client.go @@ -32,6 +32,7 @@ import ( "github.com/apache/incubator-openwhisk-client-go/wski18n" "strings" "time" + "regexp" ) const ( @@ -80,6 +81,18 @@ type Config struct { UserAgent string } +type ObfuscateSet struct { + Regex string + Replacement string +} + +var DefaultObfuscateArr = []ObfuscateSet{ + { + Regex: "\"[Pp]assword\":\\s*\".*\"", + Replacement: `"password": "******"`, + }, +} + func NewClient(httpClient *http.Client, config_input *Config) (*Client, error) { var config *Config @@ -253,7 +266,7 @@ func (c *Client) addAuthHeader(req *http.Request, authRequired bool) error { // bodyTruncator limits the size of Req/Resp Body for --verbose ONLY. // It returns truncated Req/Resp Body, reloaded io.ReadCloser and any errors. -func bodyTruncator(body io.ReadCloser) (string, io.ReadCloser, error) { +func BodyTruncator(body io.ReadCloser) (string, io.ReadCloser, error) { limit := 1000 // 1000 byte limit, anything over is truncated data, err := ioutil.ReadAll(body) @@ -279,31 +292,15 @@ func bodyTruncator(body io.ReadCloser) (string, io.ReadCloser, error) { // error if an API error has occurred. If v implements the io.Writer // interface, the raw response body will be written to v, without attempting to // first decode it. -func (c *Client) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout bool) (*http.Response, error) { +func (c *Client) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout bool, secretToObfuscate ...ObfuscateSet) (*http.Response, error) { var err error - var truncatedBody string - - if IsVerbose() { - fmt.Println("REQUEST:") - fmt.Printf("[%s]\t%s\n", req.Method, req.URL) - - if len(req.Header) > 0 { - fmt.Println("Req Headers") - PrintJSON(req.Header) - } + var data []byte + secrets := append(DefaultObfuscateArr, secretToObfuscate...) - if req.Body != nil { - fmt.Println("Req Body") - if !IsDebug() { - if truncatedBody, req.Body, err = bodyTruncator(req.Body); err != nil { - return nil, err - } - fmt.Println(truncatedBody) - } else { - fmt.Println(req.Body) - } - Debug(DbgInfo, "Req Body (ASCII quoted string):\n%+q\n", req.Body) - } + req, err = PrintRequestInfo(req, secrets...) + //Putting this based on previous code + if err != nil { + return nil, err } // Issue the request to the Whisk server endpoint @@ -314,38 +311,9 @@ func (c *Client) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout boo return nil, werr } - // Don't "defer resp.Body.Close()" here because the body is reloaded to allow caller to - // do custom body parsing, such as handling per-route error responses. - Verbose("RESPONSE:") - Verbose("Got response with code %d\n", resp.StatusCode) - - if (IsVerbose() && len(resp.Header) > 0) { - fmt.Println("Resp Headers") - PrintJSON(resp.Header) - } - - // Read the response body - data, err := ioutil.ReadAll(resp.Body) + resp, data, err = PrintResponseInfo(resp, secrets...) if err != nil { - Debug(DbgError, "ioutil.ReadAll(resp.Body) error: %s\n", err) - werr := MakeWskError(err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE) - return resp, werr - } - - // Reload the response body to allow caller access to the body; otherwise, - // the caller will have any empty body to read - resp.Body = ioutil.NopCloser(bytes.NewBuffer(data)) - - Verbose("Response body size is %d bytes\n", len(data)) - - if !IsDebug() { - if truncatedBody, resp.Body, err = bodyTruncator(resp.Body); err != nil { - return nil, err - } - Verbose("Response body received:\n%s\n", truncatedBody) - } else { - Verbose("Response body received:\n%s\n", string(data)) - Debug(DbgInfo, "Response body received (ASCII quoted string):\n%+q\n", string(data)) + return resp, err } // With the HTTP response status code and the HTTP body contents, @@ -413,6 +381,89 @@ func (c *Client) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout boo return resp, werr } +func PrintRequestInfo(req *http.Request, secretToObfuscate ...ObfuscateSet) (*http.Request, error) { + var truncatedBody string + var err error + if IsVerbose() { + fmt.Println("REQUEST:") + fmt.Printf("[%s]\t%s\n", req.Method, req.URL) + + if len(req.Header) > 0 { + fmt.Println("Req Headers") + PrintJSON(req.Header) + } + + if req.Body != nil { + fmt.Println("Req Body") + // Since we're emptying out the reader, which is the req.Body, we have to reset it, + // but create some copies for our debug messages. + buffer, _ := ioutil.ReadAll(req.Body) + obfuscatedRequest := ObfuscateText(string(buffer), secretToObfuscate) + req.Body = ioutil.NopCloser(bytes.NewBuffer(buffer)) + + if !IsDebug() { + if truncatedBody, req.Body, err = BodyTruncator(ioutil.NopCloser(bytes.NewBuffer(buffer))); err != nil { + return nil, err + } + fmt.Println(ObfuscateText(truncatedBody, secretToObfuscate)) + } else { + fmt.Println(obfuscatedRequest) + } + Debug(DbgInfo, "Req Body (ASCII quoted string):\n%+q\n", obfuscatedRequest) + } + } + return req, nil +} + +func PrintResponseInfo(resp *http.Response, secretToObfuscate ...ObfuscateSet) (*http.Response, []byte, error) { + var truncatedBody string + // Don't "defer resp.Body.Close()" here because the body is reloaded to allow caller to + // do custom body parsing, such as handling per-route error responses. + Verbose("RESPONSE:") + Verbose("Got response with code %d\n", resp.StatusCode) + + if (IsVerbose() && len(resp.Header) > 0) { + fmt.Println("Resp Headers") + PrintJSON(resp.Header) + } + + // Read the response body + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + Debug(DbgError, "ioutil.ReadAll(resp.Body) error: %s\n", err) + werr := MakeWskError(err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE) + resp.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + return resp, data, werr + } + + // Reload the response body to allow caller access to the body; otherwise, + // the caller will have any empty body to read + resp.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + + Verbose("Response body size is %d bytes\n", len(data)) + + if !IsDebug() { + if truncatedBody, resp.Body, err = BodyTruncator(ioutil.NopCloser(bytes.NewBuffer(data))); err != nil { + return nil, data, err + } + Verbose("Response body received:\n%s\n", ObfuscateText(truncatedBody, secretToObfuscate)) + } else { + obfuscatedResponse := ObfuscateText(string(data), secretToObfuscate) + Verbose("Response body received:\n%s\n", obfuscatedResponse) + Debug(DbgInfo, "Response body received (ASCII quoted string):\n%+q\n", obfuscatedResponse) + } + return resp, data, err +} + +func ObfuscateText(text string, replacements []ObfuscateSet) string { + obfuscated := text + for _, oSet := range replacements { + r, _ := regexp.Compile(oSet.Regex) + obfuscated = r.ReplaceAllString(obfuscated, oSet.Replacement) + } + return obfuscated +} + func parseErrorResponse(resp *http.Response, data []byte, v interface{}) (*http.Response, error) { Debug(DbgInfo, "HTTP failure %d + body\n", resp.StatusCode) -- To stop receiving notification emails like this one, please contact ['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].