예제 #1
0
        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]);
        }
예제 #2
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);
        }