in openwhisk/forward_proxy.go [38:120]
func (ap *ActionProxy) ForwardRunRequest(w http.ResponseWriter, r *http.Request) {
if ap.clientProxyData == nil {
sendError(w, http.StatusInternalServerError, "Send init first")
return
}
var runRequest runRequest
err := json.NewDecoder(r.Body).Decode(&runRequest)
if err != nil {
sendError(w, http.StatusBadRequest, fmt.Sprintf("Error decoding run body while forwarding request: %v", err))
return
}
newBody := runRequest
newBody.ActionCodeHash = ap.clientProxyData.ActionCodeHash
var buf bytes.Buffer
err = json.NewEncoder(&buf).Encode(newBody)
if err != nil {
sendError(w, http.StatusBadRequest, fmt.Sprintf("Error encoding updated init body: %v", err))
return
}
bodyLen := buf.Len()
r.Body = io.NopCloser(bytes.NewBuffer(buf.Bytes()))
director := func(req *http.Request) {
req.Header = r.Header.Clone()
// Reset content length with the new body
req.Header.Set("Content-Length", strconv.Itoa(bodyLen))
req.ContentLength = int64(bodyLen)
req.URL.Scheme = ap.clientProxyData.ProxyURL.Scheme
req.URL.Host = ap.clientProxyData.ProxyURL.Host
req.Host = ap.clientProxyData.ProxyURL.Host
}
proxy := &httputil.ReverseProxy{Director: director}
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
Debug("Error forwarding run request: %v", err)
sendError(w, http.StatusBadGateway, "Error forwarding run request. Check logs for details.")
}
proxy.ModifyResponse = func(response *http.Response) error {
if response.StatusCode == http.StatusOK {
// Decode the response
var remoteReponse RemoteRunResponse
err := json.NewDecoder(response.Body).Decode(&remoteReponse)
if err != nil {
Debug("Error decoding remote response: %v", err)
return err
}
// Write the logs to the client logs.
if _, err := ap.outFile.WriteString(remoteReponse.Out); err != nil {
Debug("Error writing remote response out to client: %v", err)
}
// Avoid spamming just the output guard if there is no error string
if remoteReponse.Err != OutputGuard {
if _, err := ap.errFile.WriteString(remoteReponse.Err); err != nil {
Debug("Error writing remote response err to client: %v", err)
}
}
// Keep the response body only
response.Body = io.NopCloser(bytes.NewReader(remoteReponse.Response))
// recalculate the content length
response.ContentLength = int64(len(remoteReponse.Response))
response.Header.Set("Content-Length", strconv.Itoa(len(remoteReponse.Response)))
} else {
Debug("Remote response status code: %d", response.StatusCode)
}
return nil
}
Debug("Forwarding run request with to %s", ap.clientProxyData.ProxyURL.String())
proxy.ServeHTTP(w, r)
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
}