func convertError(err error) errors.ProxyError { switch e := err.(type) { case errors.ProxyError: return e case net.Error: if e.Timeout() { return errors.FromStatus(http.StatusRequestTimeout) } case *httputils.MaxSizeReachedError: return errors.FromStatus(http.StatusRequestEntityTooLarge) } return errors.FromStatus(http.StatusBadGateway) }
// Round trips the request to the selected proxy and writes back the response func (p *Handler) proxyRequest(w http.ResponseWriter, r *http.Request) error { // Lookup the Proxy registered for the given pair: method, path. proxy, params, _ := p.GetRouter().Lookup(r.Method, r.URL.Path) if len(params) > 0 { // fmt.Printf("params: %+v \n", params) r.URL.RawQuery = url.Values(params).Encode() + "&" + r.URL.RawQuery } if proxy == nil { p.logger.Warn("Handler failed to route: %s ", r.URL.Path) return errors.FromStatus(http.StatusBadGateway) } // Create a unique request with sequential ids that will be passed to all interfaces. fctx := context.NewFlowContext(r, w, atomic.AddInt64(&p.lastRequestId, 1), nil) // The roundtrip thru the whole pipeline of modules response, err := proxy.ProcessChain(fctx) // Preparing the response back to the client if applicable if response != nil { httputils.CopyHeaders(w.Header(), response.Header) w.WriteHeader(response.StatusCode) if response.Body == nil { logutils.FileLogger.Warn("Empty body contained on the response") } else { io.Copy(w, response.Body) defer response.Body.Close() } return nil } else { return err } }
func (a *Access) ProcessRequest(c ContextSpec) (*http.Response, error) { // Get the client IP address ip, _, _ := net.SplitHostPort(c.GetHttpRequest().RemoteAddr) fba := a.getFallbackAccess() if (fba == "ALLOW" && a.isExplicitlyDenied(ip)) || (fba == "DENY" && !a.isExplicitlyAllowed(ip)) { return nil, errors.FromStatus(http.StatusForbidden) } else { return nil, nil } }
func (uds *ModDocker) ProcessRequest(c ContextSpec) (*http.Response, error) { fmt.Println("[mod_docker] Request received") fmt.Printf("[mod_docker] Dialing socket: %s ...\n", uds.socket) config, _ := parseObjJSON(c.GetHttpRequest().Body) status, resp, err := uds.sockRequest(c.GetHttpRequest().Method, c.GetHttpRequest().URL.String(), config) if err != nil { return nil, errors.FromStatus(status) } fmt.Println("[mod_docker]", string(resp)) return &http.Response{ StatusCode: status, Body: ioutil.NopCloser(bytes.NewReader(resp))}, nil }
func (ba *BasicAuth) ProcessRequest(c context.ContextSpec) (*http.Response, error) { authHeaderValue := c.GetHttpRequest().Header.Get("Authorization") if authHeaderValue == "" { logutils.FileLogger.Error("Attempted access with malformed header, no auth header found. Path: %s, Origin: %s", c.GetHttpRequest().URL, c.GetHttpRequest().Referer()) return nil, errors.FromStatus(http.StatusUnauthorized) // 401 } // Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== parts := strings.Fields(authHeaderValue) if len(parts) != 2 { logutils.FileLogger.Error("Attempted access with malformed header, header not in basic auth format.") return nil, errors.FromStatus(http.StatusBadRequest) //400 } // Decode the username:password string authvaluesStr, err := base64.StdEncoding.DecodeString(parts[1]) if err != nil { logutils.FileLogger.Error("Base64 Decoding failed of basic auth data: %s", err) return nil, errors.FromStatus(http.StatusBadRequest) //400 } authValues := strings.Split(string(authvaluesStr), ":") if len(authValues) != 2 { // Header malformed logutils.FileLogger.Error("Attempted access with malformed header, values not in basic auth format.") return nil, errors.FromStatus(http.StatusBadRequest) //400 } // CHANGELOG.md - check session and identity for valid key // Ensure that username and password match up if ba.username != authValues[0] || ba.password != authValues[1] { logutils.FileLogger.Error("User not authorized") return nil, errors.FromStatus(http.StatusForbidden) //403 } return nil, nil // all good }
func upstreamFn(chain ChainSpec, ctx context.ContextSpec) handleStateFn { mods := chain.GetModules() for i, mod := range mods { resp, err := mod.ProcessRequest(ctx) chain.SetCursor(i) if resp != nil { //log.Printf("Module: %s writing response ...", mods[i].GetId()) ctx.SetHttpResponse(resp) return downstreamFn } if err != nil { //log.Printf("Module: %s found error ...", mods[i].GetId()) ctx.SetError(err) return errorFoundFn } } log.Printf("Error. At least one module must to respond") ctx.SetError(errors.FromStatus(http.StatusNoContent)) return errorFoundFn }