Example #1
0
func handleBatchRemove(req *http.Request, storage blobserver.Storage) (interface{}, error) {
	res := new(protocol.RemoveResponse)
	n := 0
	toRemove := make([]blob.Ref, 0)

	for {
		n++
		if n > maxRemovesPerRequest {
			return nil, newRateLimitError(maxRemovesPerRequest)
		}

		key := fmt.Sprintf("blob%v", n)
		value := req.FormValue(key)
		ref, ok := blob.Parse(value)

		if !ok {
			break
		}

		toRemove = append(toRemove, ref)
	}

	err := storage.RemoveBlobs(toRemove)

	if err != nil {
		log.Errorf("Server error during remove: %v", err)
		return nil, newHTTPError("Server error", http.StatusInternalServerError)
	}

	res.Removed = toRemove
	return res, nil
}
Example #2
0
func handleRemove(req *http.Request, storage blobserver.Storage) (interface{}, error) {
	res := new(protocol.RemoveResponse)
	vars := mux.Vars(req)
	ref, ok := blob.Parse(vars["blobRef"])
	if !ok {
		return nil, newHTTPError("Invalid blob ref", http.StatusBadRequest)
	}
	toRemove := []blob.Ref{ref}
	err := storage.RemoveBlobs(toRemove)

	if err != nil {
		log.Errorf("Server error during remove: %v", err)
		return nil, newHTTPError("Server error", http.StatusInternalServerError)
	}

	res.Removed = toRemove
	return res, nil
}
Example #3
0
func handleMultiPartUpload(req *http.Request, blobReceiver blobserver.Storage) (interface{}, error) {
	res := new(protocol.UploadResponse)
	receivedBlobs := make([]blob.SizedRef, 0, 4)
	multipart, err := req.MultipartReader()

	if err != nil {
		return nil, newHTTPError(fmt.Sprintf("Expected multipart/form-data POST request; %v", err), http.StatusBadRequest)
	}

	useFilename := false
	req.ParseForm()

	if req.FormValue("use-filename") != "" {
		useFilename = true
	}

	for {
		mimePart, err := multipart.NextPart()

		if err == io.EOF {
			break
		}

		if err != nil {
			return nil, newHTTPError(fmt.Sprintf("Error reading multipart section: %v", err), http.StatusBadRequest)
		}

		contentDisposition, _, err := mime.ParseMediaType(mimePart.Header.Get("Content-Disposition"))

		if err != nil {
			return nil, newHTTPError("Invalid Content-Disposition", http.StatusBadRequest)
		}

		if contentDisposition != "form-data" {
			return nil, newHTTPError(fmt.Sprintf("Expected Content-Disposition of \"form-data\"; got %q", contentDisposition), http.StatusBadRequest)
		}

		var ref blob.Ref
		var tooBig int64 = blobserver.MaxBlobSize + 1
		var readBytes int64

		filename := mimePart.FileName()
		log.Println("filename:", filename)

		if useFilename {
			log.Println("Use filename")
			ref = blob.NewRefFilename(filename)
		} else {
			ref = blob.NewRef(filename)
		}

		blobGot, err := blobReceiver.ReceiveBlob(ref, &readerutil.CountingReader{
			Reader: io.LimitReader(mimePart, tooBig),
			N:      &readBytes,
		})

		if readBytes == tooBig {
			err = fmt.Errorf("blob over the limit of %d bytes", blobserver.MaxBlobSize)
		}

		if err != nil {
			var errmsg string

			if log.Severity >= log.LevelInfo {
				errmsg = fmt.Sprintf("Error receiving blob (read bytes: %d) %v: %v\n", readBytes, ref, err)
			} else {
				errmsg = fmt.Sprintf("Error receiving blob: %v\n", err)
			}

			return nil, newHTTPError(errmsg, http.StatusInternalServerError)
		}

		log.Printf("Received blob %v\n", blobGot)
		receivedBlobs = append(receivedBlobs, blobGot)
	}

	for _, got := range receivedBlobs {
		rv := protocol.RefInfo{
			Ref:  got.Ref,
			Size: uint32(got.Size),
		}
		if h := got.Hash(); h != nil {
			rv.MD5 = hex.EncodeToString(h.Sum(nil))
		}
		res.Received = append(res.Received, rv)
	}
	return res, nil
}