Ejemplo n.º 1
0
        public static async Task UploadAttachment(this Vault vault, PasswordRecord record, IAttachmentUploadTask uploadTask)
        {
            var fileStream = uploadTask.Stream;

            if (fileStream == null)
            {
                throw new KeeperInvalidParameter("Vault::UploadAttachment", "uploadTask", "GetStream()", "null");
            }
            var thumbStream = uploadTask.Thumbnail?.Stream;
            var command     = new RequestUploadCommand();

            command.fileCount      = 1;
            command.thumbnailCount = thumbStream != null ? 1 : 0;

            var rs = await vault.Auth.ExecuteAuthCommand <RequestUploadCommand, RequestUpoadResponse>(command);

            if (rs.fileUploads == null || rs.fileUploads.Length < 1)
            {
                throw new KeeperInvalidParameter("Vault::UploadAttachment", "request_upload", "file_uploads", "empty");
            }

            UploadParameters fileUpload  = rs.fileUploads[0];
            UploadParameters thumbUpload = null;

            if (rs.thumbnailUploads != null && rs.thumbnailUploads.Length > 0)
            {
                thumbUpload = rs.thumbnailUploads[0];
            }

            var key  = CryptoUtils.GenerateEncryptionKey();
            var atta = new AttachmentFile {
                Id           = fileUpload.fileID,
                Name         = uploadTask.Name,
                Title        = uploadTask.Title,
                Key          = key.Base64UrlEncode(),
                Type         = uploadTask.MimeType,
                LastModified = DateTimeOffset.Now,
            };
            var transform = new EncryptAesV1Transform(key);

            using (var cryptoStream = new CryptoStream(fileStream, transform, CryptoStreamMode.Read)) {
                await UploadSingleFile(fileUpload, cryptoStream);

                atta.Size = transform.EncryptedBytes;
            }
            if (thumbUpload != null)
            {
                try {
                    transform = new EncryptAesV1Transform(key);
                    using (var cryptoStream = new CryptoStream(thumbStream, transform, CryptoStreamMode.Read))
                    {
                        await UploadSingleFile(thumbUpload, cryptoStream);
                    }
                    var thumbnail = new AttachmentFileThumb
                    {
                        Id   = thumbUpload.fileID,
                        Type = uploadTask.Thumbnail.MimeType,
                        Size = uploadTask.Thumbnail.Size
                    };
                    var ts = new AttachmentFileThumb[] { thumbnail };
                    if (atta.Thumbnails == null)
                    {
                        atta.Thumbnails = ts;
                    }
                    else
                    {
                        atta.Thumbnails = atta.Thumbnails.Concat(ts).ToArray();
                    }
                }
                catch (Exception e) {
                    Trace.TraceError("Upload Thumbname: {0}: \"{1}\"", e.GetType().Name, e.Message);
                }
            }

            record.Attachments.Add(atta);
        }
Ejemplo n.º 2
0
        internal static async Task UploadSingleFile(UploadParameters upload, Stream source)
        {
            string boundary = "----------" + DateTime.Now.Ticks.ToString("x");

            byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary);

            var request = (HttpWebRequest)WebRequest.Create(new Uri(upload.url));

            request.Method      = "POST";
            request.ContentType = "multipart/form-data; boundary=" + boundary;

            using (var requestStream = await Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null))
            {
                string parameterTemplate = "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                if (upload.parameters != null)
                {
                    foreach (var pair in upload.parameters)
                    {
                        await requestStream.WriteAsync(boundaryBytes, 0, boundaryBytes.Length);

                        string formitem      = string.Format(parameterTemplate, pair.Key, pair.Value);
                        byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                        requestStream.Write(formitembytes, 0, formitembytes.Length);
                    }
                }
                await requestStream.WriteAsync(boundaryBytes, 0, boundaryBytes.Length);

                string fileTemplate = "\r\nContent-Disposition: form-data; name=\"{0}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
                var    fileItem     = string.Format(fileTemplate, upload.fileParameter);
                var    fileBytes    = Encoding.UTF8.GetBytes(fileItem);
                await requestStream.WriteAsync(fileBytes, 0, fileBytes.Length);

                await source.CopyToAsync(requestStream);

                await requestStream.WriteAsync(boundaryBytes, 0, boundaryBytes.Length);

                var trailer = Encoding.ASCII.GetBytes("--\r\n");
                await requestStream.WriteAsync(trailer, 0, trailer.Length);
            }
            HttpWebResponse response;

            try {
                response = (HttpWebResponse)await Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null);

                if ((int)response.StatusCode != upload.successStatusCode)
                {
                    throw new KeeperInvalidParameter("Vault::UploadSingleFile", "StatusCode", response.StatusCode.ToString(), "not success");
                }
            }
            catch (WebException e) {
                response = (HttpWebResponse)e.Response;
                if (response.ContentType == "application/xml")
                {
                    using (var stream = new MemoryStream()) {
                        await response.GetResponseStream().CopyToAsync(stream);

                        string responseText = Encoding.UTF8.GetString(stream.ToArray());
                        Trace.TraceError(responseText);
                    }
                }
                throw e;
            }
        }