public INode CommitUpload(string Name, INode parent, MegaAesCtrStreamCrypter encryptedStream, string completionHandle) { byte[] cryptedAttributes = Crypto.EncryptAttributes(new Attributes(Name), encryptedStream.FileKey); byte[] fileKey = new byte[32]; for (int i = 0; i < 8; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.Iv[i]); fileKey[i + 16] = encryptedStream.Iv[i]; } for (int i = 8; i < 16; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.MetaMac[i - 8]); fileKey[i + 16] = encryptedStream.MetaMac[i - 8]; } byte[] encryptedKey = Crypto.EncryptKey(fileKey, this.masterKey); CreateNodeRequest createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); GetNodesResponse createNodeResponse = this.Request <GetNodesResponse>(createNodeRequest, this.masterKey); return(createNodeResponse.Nodes[0]); }
/// <summary> /// Upload a stream on Mega.co.nz and attach created node to selected parent /// </summary> /// <param name="stream">Data to upload</param> /// <param name="name">Created node name</param> /// <param name="parent">Node to attach the uploaded file (all types except <see cref="NodeType.File" /> are supported)</param> /// <returns>Created node</returns> /// <exception cref="NotSupportedException">Not logged in</exception> /// <exception cref="ApiException">Mega.co.nz service reports an error</exception> /// <exception cref="ArgumentNullException">stream or name or parent is null</exception> /// <exception cref="ArgumentException">parent is not valid (all types except <see cref="NodeType.File" /> are supported)</exception> public INode Upload(Stream stream, string name, INode parent) { if (stream == null) { throw new ArgumentNullException("stream"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (parent == null) { throw new ArgumentNullException("parent"); } if (parent.Type == NodeType.File) { throw new ArgumentException("Invalid parent node"); } this.EnsureLoggedIn();//check are login string completionHandle = "-"; int remainingRetry = ApiRequestAttempts; while (remainingRetry-- > 0) { UploadUrlRequest uploadRequest = new UploadUrlRequest(stream.Length); UploadUrlResponse uploadResponse = this.Request <UploadUrlResponse>(uploadRequest);//Retrieve upload URL using (MegaAesCtrStreamCrypter encryptedStream = new MegaAesCtrStreamCrypter(stream)) { var chunkStartPosition = 0; var chunksSizesToUpload = this.ComputeChunksSizesToUpload(encryptedStream.ChunksPositions, encryptedStream.Length).ToArray(); for (int i = 0; i < chunksSizesToUpload.Length; i++) { int chunkSize = chunksSizesToUpload[i]; byte[] chunkBuffer = new byte[chunkSize]; encryptedStream.Read(chunkBuffer, 0, chunkSize); using (MemoryStream chunkStream = new MemoryStream(chunkBuffer)) { Uri uri = new Uri(uploadResponse.Url + "/" + chunkStartPosition); chunkStartPosition += chunkSize; try { completionHandle = this.webClient.PostRequestRaw(uri, chunkStream); if (completionHandle.StartsWith("-")) { break; } } catch (Exception ex) { Console.WriteLine(ex); break; } } } if (completionHandle.StartsWith("-")) { Thread.Sleep(ApiRequestDelay); // Restart upload from the beginning stream.Position = 0; // Reset steam position continue; } byte[] cryptedAttributes = Crypto.EncryptAttributes(new Attributes(name), encryptedStream.FileKey);// Encrypt attributes #region Compute the file key byte[] fileKey = new byte[32]; for (int i = 0; i < 8; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.Iv[i]); fileKey[i + 16] = encryptedStream.Iv[i]; } for (int i = 8; i < 16; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.MetaMac[i - 8]); fileKey[i + 16] = encryptedStream.MetaMac[i - 8]; } byte[] encryptedKey = Crypto.EncryptKey(fileKey, this.masterKey); #endregion CreateNodeRequest createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); GetNodesResponse createNodeResponse = this.Request <GetNodesResponse>(createNodeRequest, this.masterKey); return(createNodeResponse.Nodes[0]); } } throw new UploadException(completionHandle); }