in openwhisk/runHandler.go [68:149]
func (ap *ActionProxy) runHandler(w http.ResponseWriter, r *http.Request) {
if ap.proxyMode == ProxyModeNone {
ap.doRun(w, r)
return
}
if ap.proxyMode == ProxyModeClient {
ap.ForwardRunRequest(w, r)
return
}
if ap.proxyMode == ProxyModeServer {
// parse the request
body, err := io.ReadAll(r.Body)
defer r.Body.Close()
if err != nil {
sendError(w, http.StatusBadRequest, fmt.Sprintf("Error reading request body: %v", err))
return
}
var runRequest runRequest
err = json.NewDecoder(bytes.NewReader(body)).Decode(&runRequest)
if err != nil {
sendError(w, http.StatusBadRequest, fmt.Sprintf("Error decoding run body: %v", err))
return
}
if runRequest.ActionCodeHash == "" {
sendError(w, http.StatusBadRequest, "Action code hash not provided from client")
return
}
innerActionProxy, ok := ap.serverProxyData.actions[runRequest.ActionCodeHash]
if !ok {
Debug("Action hash %s not found in server proxy data", runRequest.ActionCodeHash)
sendError(w, http.StatusNotFound, "Action not found in remote runtime. Check logs for details.")
return
}
// Enqueue the request to be processed by the inner proxy one at a time
responseChan := make(chan *ServerRunResponseChanPayload)
innerActionProxy.runRequestQueue <- &remoteRunChanPayload{runRequest: &runRequest, respChan: responseChan}
res := <-responseChan
if res.err != nil {
sendError(w, res.status, res.err.Error())
return
}
// write response
// turn response struct into json
responsePayload, err := json.Marshal(res.runResp)
if err != nil {
sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error marshalling response: %v", err))
return
}
// write response
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(responsePayload)))
numBytesWritten, err := w.Write(responsePayload)
// handle writing errors
if err != nil {
Debug("(remote) Error writing response: %v", err)
sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error writing response: %v", err))
return
}
if numBytesWritten < len(responsePayload) {
Debug("(remote) Only wrote %d of %d bytes to response", numBytesWritten, len(responsePayload))
sendError(w, http.StatusInternalServerError, fmt.Sprintf("Only wrote %d of %d bytes to response", numBytesWritten, len(responsePayload)))
return
}
// flush output if possible
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
close(responseChan)
}
}