Esempio n. 1
0
func (ss *StoreService) get(req *msg.OcReq) (*msg.OcResp, error) {
	var containerID ContainerID
	var blobID BlobID
	if len(req.Args) == 1 {
		containerID = ocIDToContainerID(req.ID)
		blobID = BlobID(req.Args[0])
	} else if len(req.Args) == 2 {
		if req.Args[0] == "." {
			containerID = ocIDToContainerID(req.ID)
		} else {
			containerID = ContainerID(req.Args[0])
		}
		blobID = BlobID(req.Args[1])
	} else {
		return msg.NewRespError(msg.INVALID_ARGUMENTS), nil
	}

	fmt.Printf("get %v %v\n", containerID, blobID)

	if containerID != ocIDToContainerID(req.ID) {
		resp := msg.NewRespErrorWithBody(msg.INVALID_ARGUMENTS,
			[]byte("Cannot access that container"))
		return resp, nil
	}

	container := NewContainerFromDisk(req.ID)
	if !container.HasBlobID(blobID) {
		resp := msg.NewRespErrorWithBody(msg.INVALID_ARGUMENTS,
			[]byte("Cannot access that blob"))
		return resp, nil
	}

	blob, err := NewBlobFromDisk(blobID)
	if err != nil {
		return msg.NewRespError(msg.SERVER_ERROR), nil
	}
	var buf bytes.Buffer
	for _, block := range blob.Blocks {
		_, err := buf.Write(block.Data)
		if err != nil {
			return msg.NewRespError(msg.SERVER_ERROR), nil
		}
	}
	return msg.NewRespOk(buf.Bytes()), nil
}
Esempio n. 2
0
func (s *Server) checkBalance(p *peer.Peer) *msg.OcResp {
	balance, err := p.Balance(SERVER_PAYMENT_MIN_CONF, s.BtcConf)
	if err != nil {
		return msg.NewRespError(msg.SERVER_ERROR)
	}
	fmt.Printf("balance: %v\n", balance)
	if balance.Currency != msg.BTC {
		panic("TODO: support other currencies")
	}
	maxBalance, err := s.Conf.PolicyForCmd(conf.MAX_BALANCE)
	if err != nil {
		// TODO(ortutay): handle more configuration around max balance
		panic(err)
	}
	maxAllowed := maxBalance.Args[0].(*msg.PaymentValue).Amount
	fmt.Printf("max balance: %v\n", maxBalance.Args[0])
	if balance.Amount > maxAllowed {
		addr, err := p.PaymentAddr(-1, s.BtcConf)
		if err != nil {
			return msg.NewRespError(msg.SERVER_ERROR)
		}
		// TODO(ortutay): a clever client will notice that they can pay off just a
		// small amount to stay just at the edge of the max balance. they do not
		// much by doing this, and may waste money on miner fees, but nevertheless,
		// we could have some smarter handling for that situation.
		pr := msg.PaymentRequest{
			Amount:   balance.Amount,
			Currency: balance.Currency,
			Addr:     addr,
		}
		body, err := json.Marshal(&pr)
		if err != nil {
			return msg.NewRespError(msg.SERVER_ERROR)
		}
		return msg.NewRespErrorWithBody(msg.PLEASE_PAY, []byte(body))
	}
	return nil
}
Esempio n. 3
0
func (ss *StoreService) put(req *msg.OcReq) (*msg.OcResp, error) {
	var containerID ContainerID
	var blobID BlobID
	if len(req.Args) == 0 {
		containerID = ocIDToContainerID(req.ID)
		// blob will be read from request
	} else if len(req.Args) == 1 {
		if req.Args[0] == "." {
			containerID = ocIDToContainerID(req.ID)
		} else {
			containerID = ContainerID(req.Args[0])
		}
		// blob will be read from request
	} else if len(req.Args) == 2 {
		if req.Args[0] == "." {
			containerID = ocIDToContainerID(req.ID)
		} else {
			containerID = ContainerID(req.Args[0])
		}
		blobID = BlobID(req.Args[1])
	} else {
		return msg.NewRespError(msg.INVALID_ARGUMENTS), nil
	}

	if containerID != ocIDToContainerID(req.ID) {
		resp := msg.NewRespErrorWithBody(msg.INVALID_ARGUMENTS,
			[]byte("Cannot access that container"))
		return resp, nil
	}

	fmt.Printf("put request for: %v %v\n", containerID, blobID)

	// Store blob if it is new
	blob, err := NewBlobFromDisk(blobID)
	if blob == nil {
		if req.Body == nil || len(req.Body) == 0 {
			// TODO(ortutay): Neither "OK" nor "error" are appropriate status codes
			// in this case. It may be useful to have a third error class, but not
			// sure what to call it.
			return msg.NewRespOk([]byte("Please re-send with data.")), nil
		}
		if len(req.Body) > MAX_BLOB_BYTES {
			resp := msg.NewRespErrorWithBody(msg.CANNOT_COMPLETE_REQUEST,
				[]byte(fmt.Sprintf("Cannot store over %v",
					util.ByteSize(MAX_BLOB_BYTES).String())))
			return resp, nil
		}
		blob, err = NewBlobFromReader(bytes.NewReader(req.Body))
		if err != nil {
			return msg.NewRespError(msg.SERVER_ERROR), nil
		}
		err := storeBlob(blob)
		if err != nil {
			return msg.NewRespError(msg.SERVER_ERROR), nil
		}
	}

	// Append blob-id to container-id
	container := NewContainerFromDisk(req.ID)
	for _, id := range container.BlobIDs {
		if id == blob.ID {
			return msg.NewRespOk([]byte("")), nil
		}
	}
	container.WriteNewBlobID(blob.ID)

	return msg.NewRespOk([]byte(blob.ID.String())), nil
}