// 3 steps: Send UploadRequestMessage, Upload actual data, send transaction protected async Task <HeleusClientResponse> UploadDataAttachements(Attachements attachements, KeyStore clientAccount, Action <AttachementDataTransaction> setupCallback) { if (!await SetTargetChain(attachements.ChainId)) { return(new HeleusClientResponse(HeleusClientResultTypes.EndpointConnectionError)); } var uploadRequest = new ClientAttachementsRequestMessage(attachements, clientAccount.KeyIndex, clientAccount.DecryptedKey); Log.Trace($"UploadAttachements: Sending message {uploadRequest.MessageType}.", this); var sent = await SendMessage(attachements.AccountId, uploadRequest); if (!sent) { return(new HeleusClientResponse(HeleusClientResultTypes.ConnectionFailed)); } var uploadResponse = await WaitResponse(uploadRequest) as ClientAttachementsResponseMessage; if (uploadResponse == null || uploadResponse.ResultType != TransactionResultTypes.Ok) { if (uploadResponse == null) { return(new HeleusClientResponse(HeleusClientResultTypes.EndpointConnectionError)); } Log.Trace($"UploadAttachements: Upload failed {uploadResponse.ResultType}.", this); return(new HeleusClientResponse(HeleusClientResultTypes.Ok, uploadResponse.ResultType, uploadResponse.UserCode)); } try { using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromSeconds(120); using (var content = new MultipartFormDataContent()) { //var length = 0; foreach (var att in attachements.Items) { var data = att.GetData(); //length += data.Length; content.Add(new ByteArrayContent(data) { Headers = { ContentLength = data.Length } }, "files", att.Name); } //content.Headers.ContentLength = length; content.Headers.Add("X-Attachements", Convert.ToBase64String(attachements.ToByteArray())); var responseMessage = await client.PostAsync($"{ChainEndPoint.AbsoluteUri}dynamic/datachain/{attachements.ChainId}/{attachements.ChainIndex}/attachements/{uploadResponse.AttachementKey}/upload/", content); var responseText = await responseMessage.Content.ReadAsStringAsync(); if (responseMessage.StatusCode != System.Net.HttpStatusCode.OK) { try { var results = responseText.Split(','); var result = (TransactionResultTypes)(int.Parse(results[0])); var userCode = long.Parse(results[1]); Log.Trace($"UploadAttachements: Uploaded ({result}, UserCode: {userCode}).", this); return(new HeleusClientResponse(HeleusClientResultTypes.Ok, result, userCode)); } catch (Exception ex) { Log.HandleException(ex, this); return(new HeleusClientResponse(HeleusClientResultTypes.InternalError, 0)); } } } } } catch (Exception ex) { Log.IgnoreException(ex, this); return(new HeleusClientResponse(HeleusClientResultTypes.Timeout, 0)); } var transaction = new AttachementDataTransaction(attachements, uploadResponse.AttachementKey); setupCallback?.Invoke(transaction); return(await SendDataTransaction(transaction, true, clientAccount)); }
async Task OnAttachementsRequest(ClientAttachementsRequestMessage message, ClientConnection connection) { var result = TransactionResultTypes.Unknown; var userCode = 0L; var attachementKey = 0; var container = _chainManager.GetContainer(message.ChainId); var dataChain = container?.GetDataChain(message.ChainIndex); var serviceChain = container?.ServiceChain; var service = container?.Service; if (container == null || dataChain == null || serviceChain == null) { result = TransactionResultTypes.ChainNodeInvalid; goto end; } if (service == null) { result = TransactionResultTypes.ChainServiceUnavailable; goto end; } attachementKey = dataChain.AttachementKey; if (attachementKey < 0) { result = TransactionResultTypes.AttachementsNotAllowed; goto end; } Key key = null; if (message.KeyIndex == Protocol.CoreAccountSignKeyIndex) { var coreAccount = _chainManager.CoreChain.GetCoreAccount(message.AccountId); key = coreAccount?.AccountKey; } else { var chainAccount = serviceChain.GetValidServiceAccountKey(message.AccountId, message.KeyIndex, Time.Timestamp); key = chainAccount?.PublicKey; } if (key == null) { result = TransactionResultTypes.InvalidServiceAccountKey; goto end; } var attachements = message.Attachements.GetSignedItem(key); if (attachements == null) { result = TransactionResultTypes.InvalidSignature; goto end; } if (!attachements.CheckAttachements() || AttachementInfo.IsExpired(attachements)) { result = TransactionResultTypes.AttachementsInvalid; goto end; } var valid = await service.IsValidAttachementsRequest(attachements); userCode = valid.UserCode; if (!valid.IsOK) { result = TransactionResultTypes.ChainServiceErrorResponse; goto end; } if (!_attachementManager.AddAttachementsRequests(attachements)) { result = TransactionResultTypes.AttachementsInvalid; goto end; } // everything seems to be OK result = TransactionResultTypes.Ok; end: await connection.Send(new ClientAttachementsResponseMessage(message, result, userCode, attachementKey)); }