in plugins/listeners/httplistener/httplistener.go [96:219]
func (h *apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
verb := strings.TrimLeft(r.URL.Path, "/")
var (
httpStatus = http.StatusOK
resp api.Response
errMsg string
err error
)
// This is only used by status, stop, and reply. Ignored for other
// methods. If not set by the client, this is an empty string.
if r.Method != "POST" {
h.reply(w, http.StatusBadRequest, "Only POST requests are supported")
return
}
jobIDStr := r.PostFormValue("jobID")
jobDesc := r.PostFormValue("jobDesc")
requestor := api.EventRequestor(r.PostFormValue("requestor"))
ctx := h.ctx.WithTags(xcontext.Fields{
"http_verb": verb,
"http_requestor": requestor,
}).WithField("http_job_id", jobIDStr)
switch verb {
case "start":
if jobDesc == "" {
httpStatus = http.StatusBadRequest
errMsg = "Missing job description"
break
}
if resp, err = h.api.Start(ctx, requestor, jobDesc); err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Start failed: %v", err)
}
case "status":
jobID, err := strToJobID(jobIDStr)
if err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Status failed: %v", err)
break
}
if resp, err = h.api.Status(ctx, requestor, jobID); err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Status failed: %v", err)
}
case "stop":
jobID, err := strToJobID(jobIDStr)
if err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Stop failed: %v", err)
break
}
if resp, err = h.api.Stop(ctx, requestor, jobID); err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Stop failed: %v", err)
}
case "retry":
jobID, err := strToJobID(jobIDStr)
if err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Retry failed: %v", err)
break
}
if resp, err = h.api.Retry(ctx, requestor, jobID); err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Retry failed: %v", err)
}
case "list":
var fields []storage.JobQueryField
if statesStr := r.PostFormValue("states"); len(statesStr) > 0 {
var states []job.State
for _, sts := range strings.Split(statesStr, ",") {
st, err := job.EventNameToJobState(event.Name(sts))
if err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("List failed: %v", err)
break
}
states = append(states, st)
}
fields = append(fields, storage.QueryJobStates(states...))
}
if tagsStr := r.PostFormValue("tags"); len(tagsStr) > 0 {
fields = append(fields, storage.QueryJobTags(strings.Split(tagsStr, ",")...))
}
jobQuery, err := storage.BuildJobQuery(fields...)
if err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("Invalid query: %v", err)
break
}
if resp, err = h.api.List(ctx, requestor, jobQuery); err != nil {
httpStatus = http.StatusBadRequest
errMsg = fmt.Sprintf("List failed: %v", err)
}
case "version":
resp = h.api.Version()
default:
errMsg = fmt.Sprintf("unknown verb: %s", verb)
httpStatus = http.StatusBadRequest
}
if httpStatus != http.StatusOK {
errResp := HTTPAPIError{
Msg: errMsg,
}
msg, err := json.Marshal(errResp)
if err != nil {
panic(fmt.Sprintf("cannot marshal HTTPAPIError: %v", err))
}
h.reply(w, httpStatus, string(msg))
return
}
apiResp := NewHTTPAPIResponse(&resp)
buffer := &bytes.Buffer{}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
err = encoder.Encode(apiResp)
if err != nil {
panic(fmt.Sprintf("cannot marshal HTTPAPIResponse: %v", err))
}
msg := buffer.Bytes()
h.reply(w, httpStatus, string(msg))
}