func (conf *HttpConfiguration) handleWithMethod(method JobHandler) func(*rest.ResponseWriter, *rest.Request) { return func(w *rest.ResponseWriter, r *rest.Request) { match := r.Header.Get("If-Match") segments := strings.Split(match, ",") for i := range segments { if strings.HasPrefix(segments[i], "api=") { if segments[i][4:] != ApiVersion() { http.Error(w, fmt.Sprintf("Current API version %s does not match requested %s", ApiVersion(), segments[i][4:]), http.StatusPreconditionFailed) return } } } context := &jobs.JobContext{} requestId := r.Header.Get("X-Request-Id") if requestId == "" { context.Id = jobs.NewRequestIdentifier() } else { id, err := jobs.NewRequestIdentifierFromString(requestId) if err != nil { http.Error(w, "X-Request-Id must be a 32 character hexadecimal string", http.StatusBadRequest) return } context.Id = id } // parse the incoming request into an object jobRequest, errh := method(context, r) if errh != nil { serveRequestError(w, apiRequestError{errh, errh.Error(), http.StatusBadRequest}) return } // find the job implementation for that request job, errj := jobs.JobFor(jobRequest) if errj != nil { serveRequestError(w, apiRequestError{errj, errj.Error(), http.StatusBadRequest}) return } // determine the type of the request acceptHeader := r.Header.Get("Accept") overrideAcceptHeader := r.Header.Get("X-Accept") if overrideAcceptHeader != "" { acceptHeader = overrideAcceptHeader } // setup the appropriate mode mode := ResponseJson if acceptHeader == "text/plain" { mode = ResponseTable } canStream := didClientRequestStreamableResponse(acceptHeader) response := NewHttpJobResponse(w.ResponseWriter, !canStream, mode) // queue / handle the request wait, errd := conf.Dispatcher.Dispatch(context.Id, job, response) if errd == jobs.ErrRanToCompletion { http.Error(w, errd.Error(), http.StatusNoContent) return } else if errd != nil { serveRequestError(w, apiRequestError{errd, errd.Error(), http.StatusServiceUnavailable}) return } <-wait } }
func (conf *HttpConfiguration) handleWithMethod(method JobHandler) func(*rest.ResponseWriter, *rest.Request) { return func(w *rest.ResponseWriter, r *rest.Request) { match := r.Header.Get("If-Match") segments := strings.Split(match, ",") for i := range segments { if strings.HasPrefix(segments[i], "api=") { if segments[i][4:] != ApiVersion() { http.Error(w, fmt.Sprintf("Current API version %s does not match requested %s", ApiVersion(), segments[i][4:]), http.StatusPreconditionFailed) return } } } context := &jobs.JobContext{} requestId := r.Header.Get("X-Request-Id") if requestId == "" { context.Id = jobs.NewRequestIdentifier() } else { id, err := jobs.NewRequestIdentifierFromString(requestId) if err != nil { http.Error(w, "X-Request-Id must be a 32 character hexadecimal string", http.StatusBadRequest) return } context.Id = id } /*token, id, errt := extractToken(r.PathParam("token"), r.Request) if errt != nil { log.Println(errt) http.Error(w, "Token is required - pass /token/<token>/<path>", http.StatusForbidden) return } if token.D == 0 { log.Println("http: Recommend passing 'd' as an argument for the current date") } if token.U == "" { log.Println("http: Recommend passing 'u' as an argument for the associated user") }*/ job, errh := method(context, r) if errh != nil { if errh != ErrHandledResponse { http.Error(w, "Invalid request: "+errh.Error()+"\n", http.StatusBadRequest) } return } mode := ResponseJson if r.Header.Get("Accept") == "text/plain" { mode = ResponseTable } acceptHeader := r.Header.Get("Accept") overrideAcceptHeader := r.Header.Get("X-Accept") if overrideAcceptHeader != "" { acceptHeader = overrideAcceptHeader } canStream := didClientRequestStreamableResponse(acceptHeader) if streaming, ok := job.(HttpStreamable); ok { canStream = streaming.Streamable() } response := NewHttpJobResponse(w.ResponseWriter, !canStream, mode) wait, errd := conf.Dispatcher.Dispatch(context.Id, job, response) if errd == jobs.ErrRanToCompletion { http.Error(w, errd.Error(), http.StatusNoContent) return } else if errd != nil { serveRequestError(w, apiRequestError{errd, errd.Error(), http.StatusServiceUnavailable}) return } <-wait } }
func (conf *HttpConfiguration) handleWithMethod(method JobHandler) func(*rest.ResponseWriter, *rest.Request) { return func(w *rest.ResponseWriter, r *rest.Request) { context := &HttpContext{} context.ApiVersion = r.Header.Get("X-Api-Version") requestId := r.Header.Get("X-Request-Id") if requestId == "" { context.Id = jobs.NewRequestIdentifier() } else { id, err := jobs.NewRequestIdentifierFromString(requestId) if err != nil { http.Error(w, "X-Request-Id must be a 32 character hexadecimal string", http.StatusBadRequest) return } context.Id = id } // parse the incoming request into an object jobRequest, errh := method(conf, context, r) if errh != nil { serveRequestError(w, apiRequestError{errh, errh.Error(), http.StatusBadRequest}) return } // find the job implementation for that request job, errj := jobs.JobFor(jobRequest) if errj != nil { if errj == jobs.ErrNoJobForRequest { serveRequestError(w, apiRequestError{errj, fmt.Sprintf("The requested job %s has no registered implementation", reflect.TypeOf(jobRequest)), http.StatusBadRequest}) } serveRequestError(w, apiRequestError{errj, errj.Error(), http.StatusBadRequest}) return } // determine the type of the request acceptHeader := r.Header.Get("Accept") overrideAcceptHeader := r.Header.Get("X-Accept") if overrideAcceptHeader != "" { acceptHeader = overrideAcceptHeader } // setup the appropriate mode mode := client.ResponseJson if acceptHeader == "text/plain" { mode = client.ResponseTable } canStream := didClientRequestStreamableResponse(acceptHeader) response := NewHttpJobResponse(w.ResponseWriter, !canStream, mode) // queue / handle the request wait, errd := conf.Dispatcher.Dispatch(context.Id, job, response) if errd == jobs.ErrRanToCompletion { http.Error(w, errd.Error(), http.StatusNoContent) return } else if errd != nil { serveRequestError(w, apiRequestError{errd, errd.Error(), http.StatusServiceUnavailable}) return } <-wait } }