// tasksearch searches the task list. The search criteria is specified by a query parameter // of the form text={text} where {text} is matched against the task's value string. func tasksearch(ctx context.Context, w http.ResponseWriter, req *http.Request) { tasks := ctx.Value("tasks").(*list.List) qt := req.URL.Query().Get("text") if len(qt) <= 0 { w.WriteHeader(http.StatusBadRequest) w.Write(mkError("ClientError", "reason", "Missing text parameter")) return } resp := mkEmptylist() if resp == nil { panic("can't generate base UBER document") } for t, i := tasks.Front(), 0; t != nil; t = t.Next() { if qt == t.Value.(string) { resp.appendItem(fmt.Sprintf("task%d", i+1), t.Value.(string)) i++ } } bs, err := json.Marshal(resp) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(mkError("ServerError", "reason", "Cannot read HTTP request body")) } w.WriteHeader(http.StatusOK) w.Write(bs) }
// Do sends an HTTP request with the provided http.Client and returns an HTTP response. // If the client is nil, http.DefaultClient is used. // If the context is canceled or times out, ctx.Err() will be returned. func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { if client == nil { client = http.DefaultClient } // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. cancel := canceler(client, req) type responseAndError struct { resp *http.Response err error } result := make(chan responseAndError, 1) go func() { resp, err := client.Do(req) result <- responseAndError{resp, err} }() select { case <-ctx.Done(): cancel() return nil, ctx.Err() case r := <-result: return r.resp, r.err } }
// taskcomplete removes a task from the list. It expects a body containing id={task} where // {task} is the id of the task to be removed. func taskcomplete(ctx context.Context, w http.ResponseWriter, req *http.Request) { body, err := ioutil.ReadAll(req.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(mkError("ServerError", "reason", "Cannot read HTTP request body")) return } re := regexp.MustCompile("id=[[:alpha:]]+([[:digit:]]+)") sm := re.FindStringSubmatch(string(body)) if sm == nil { w.WriteHeader(http.StatusBadRequest) w.Write(mkError("ClientError", "reason", "Unrecognized complete text body")) return } completed := false taskid, err := strconv.Atoi(sm[1]) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(mkError("ServerError", "reason", "Cannot read HTTP request body")) return } tasks := ctx.Value("tasks").(*list.List) if tasks.Len() < taskid { w.WriteHeader(http.StatusNotFound) w.Write(mkError("ClientError", "reason", "No such task")) return } for t, i := tasks.Front(), 1; t != nil; t = t.Next() { if i == taskid { completed = true tasks.Remove(t) } i++ } if !completed { w.WriteHeader(http.StatusNotFound) w.Write(mkError("ClientError", "reason", "No such task")) return } w.WriteHeader(http.StatusNoContent) }
// taskadd adds a task to the list. func taskadd(ctx context.Context, w http.ResponseWriter, req *http.Request) { body, err := ioutil.ReadAll(req.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(mkError("ServerError", "reason", "Cannot read HTTP request body")) return } re := regexp.MustCompile("text=(([[:word:]]|[[:space:]])*)") sm := re.FindStringSubmatch(string(body)) if sm == nil { w.WriteHeader(http.StatusBadRequest) w.Write(mkError("ClientError", "reason", "Unrecognized add task body")) return } tasks := ctx.Value("tasks").(*list.List) tasks.PushBack(sm[1]) w.WriteHeader(http.StatusNoContent) }
// tasklist responds with the list of tasks. func tasklist(ctx context.Context, w http.ResponseWriter, req *http.Request) { tasks := ctx.Value("tasks").(*list.List) resp := mkEmptylist() if resp == nil { panic("can't generate base UBER document") } for t, i := tasks.Front(), 0; t != nil; t = t.Next() { resp.appendItem(fmt.Sprintf("task%d", i+1), t.Value.(string)) i++ } bs, err := json.Marshal(resp) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(mkError("ServerError", "reason", "Cannot read HTTP request body")) return } w.WriteHeader(http.StatusOK) w.Write(bs) }