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 }
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 }
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 }