func serverHasBlob(bs blobserver.BlobStatter, br *blobref.BlobRef) (have bool, err os.Error) { ch := make(chan blobref.SizedBlobRef, 1) go func() { err = bs.StatBlobs(ch, []*blobref.BlobRef{br}, 0) close(ch) }() for _ = range ch { have = true } return }
func handleStat(conn http.ResponseWriter, req *http.Request, storage blobserver.BlobStatter) { if w, ok := storage.(blobserver.ContextWrapper); ok { storage = w.WrapContext(req) } toStat := make([]*blobref.BlobRef, 0) switch req.Method { case "POST": fallthrough case "GET": camliVersion := req.FormValue("camliversion") if camliVersion == "" { httputil.BadRequestError(conn, "No camliversion") return } n := 0 for { n++ key := fmt.Sprintf("blob%v", n) value := req.FormValue(key) if value == "" { n-- break } if n > maxStatBlobs { httputil.BadRequestError(conn, "Too many stat blob checks") return } ref := blobref.Parse(value) if ref == nil { httputil.BadRequestError(conn, "Bogus blobref for key "+key) return } toStat = append(toStat, ref) } default: httputil.BadRequestError(conn, "Invalid method.") return } waitSeconds := 0 if waitStr := req.FormValue("maxwaitsec"); waitStr != "" { waitSeconds, _ = strconv.Atoi(waitStr) switch { case waitSeconds < 0: waitSeconds = 0 case waitSeconds > 30: // TODO: don't hard-code 30. push this up into a blobserver interface // for getting the configuration of the server (ultimately a flag in // in the binary) waitSeconds = 30 } } statRes := make([]map[string]interface{}, 0) if len(toStat) > 0 { blobch := make(chan blobref.SizedBlobRef) resultch := make(chan os.Error, 1) go func() { err := storage.StatBlobs(blobch, toStat, waitSeconds) close(blobch) resultch <- err }() for sb := range blobch { ah := make(map[string]interface{}) ah["blobRef"] = sb.BlobRef.String() ah["size"] = sb.Size statRes = append(statRes, ah) } err := <-resultch if err != nil { log.Printf("Stat error: %v", err) conn.WriteHeader(http.StatusInternalServerError) return } } configer, _ := storage.(blobserver.Configer) ret := commonUploadResponse(configer, req) ret["stat"] = statRes ret["canLongPoll"] = true httputil.ReturnJson(conn, ret) }