Пример #1
0
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
	}
}
Пример #2
0
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
	}
}
Пример #3
0
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
	}
}