#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously static async Task <DeleteResult> ObjectDeleteMultiple(S3Context ctx, DeleteMultiple del) #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously { Console.WriteLine("ObjectDelete: " + ctx.Request.Bucket); Console.WriteLine(ctx.Request.DataAsString + Environment.NewLine); DeleteResult result = new DeleteResult( new List <Deleted>() { new Deleted("hello.txt", "1", false) }, null); return(result); }
static void Main(string[] args) { Console.WriteLine("Open RunExamples.cs. \nIn Main() method uncomment the example that you want to run."); Console.WriteLine("====================================================="); // Please uncomment the example you want to try out #region Quick Start QuickStart.SetLicenseFromFile.Run(); //QuickStart.SetLicenseFromStream.Run(); //QuickStart.SetMeteredLicense.Run(); QuickStart.HelloWorld.Run(); #endregion // Quick Start #region Basic Usage #region Common GetSupportedFileFormats.Run(); #endregion #region Document Preview GetDocumentInfo.Run(); GeneratePreview.Run(); GetDocumentProcessHistory.Run(); #endregion #region Sign document with different signature types //Sign document with text signature SignWithText.Run(); //Sign document with image signature SignWithImage.Run(); //Sign document with barcode signature SignWithBarcode.Run(); //Sign document with qr-code signature SignWithQRCode.Run(); //Sign document with digital signature SignWithDigital.Run(); //Sign document with Stamp signature SignWithStamp.Run(); //Sign image document with metadata signature SignImageWithMetadata.Run(); //Sign pdf document with metadata signature SignPdfWithMetadata.Run(); //Sign presentation document with metadata signature SignPresentationWithMetadata.Run(); //Sign spreadsheets document with metadata signature SignSpreadsheetWithMetadata.Run(); //Sign word-processing document with metadata signature SignWordProcessingWithMetadata.Run(); //Sign pdf document with form-field signature SignPdfWithFormField.Run(); // Sign document with multiple signature types SignWithMultipleOptions.Run(); #endregion // Sign document with different signature types #region Search signed documents for different signature types //Search document for Text signature SearchForText.Run(); //Search document for Image signature SearchForImage.Run(); //Search document for Barcode signature SearchForBarcode.Run(); //Search document for QR-Code signature SearchForQRCode.Run(); //Search document for digital signature SearchForDigital.Run(); //Search image document for metadata signatures SearchImageForMetadata.Run(); //Search PDF document for metadata signatures SearchPdfForMetadata.Run(); //Search Presentation document for metadata signatures SearchPresentationForMetadata.Run(); //Search Spreadsheet document for metadata signatures SearchSpreadsheetForMetadata.Run(); //Search WordProcessing document for metadata signatures SearchWordProcessingForMetadata.Run(); //Search document for form-field signature SearchForFormField.Run(); //Search document for multiple signature types SearchForMultiple.Run(); #endregion // Search signed documents for different signature types #region Verify documents signed with different signature types //Verify document with Text signature VerifyText.Run(); //Verify document with Barcode signature VerifyBarcode.Run(); //Verify document with QR-Code signature VerifyQRCode.Run(); //Verify document with digital signature VerifyDigital.Run(); //Verify document with multiple signatures VerifyWithMultipleOptions.Run(); #endregion // Verify documents signed with different signature types #region Update signatures in the document //Update Text signature in the document after Search method UpdateText.Run(); //Update Image signature in the document after Search method UpdateImage.Run(); //Update Barcode signature in the document after Search method UpdateBarcode.Run(); //Update QR-code signature in the document after Search method UpdateQRCode.Run(); #endregion #region Delete signatures from document //Delete found Text signature in the document after Search method DeleteText.Run(); //Delete found Image signature in the document after Search method DeleteImage.Run(); //Delete found Barcode signature in the document after Search method DeleteBarcode.Run(); //Delete found QR-code signature in the document after Search method DeleteQRCode.Run(); //Delete few found multiple signatures in the document after Search method DeleteMultiple.Run(); #endregion #endregion // Basic Usage #region Advanced Usage #region Loading LoadDocumentFromLocalDisk.Run(); LoadDocumentFromStream.Run(); LoadDocumentFromUrl.Run(); //LoadDocumentFromAmazonS3.Run(); //LoadDocumentFromAzureBlobStorage.Run(); //LoadDocumentFromFtp.Run(); LoadPasswordProtectedDocument.Run(); #endregion #region Saving SaveSignedPdfWithDifferentOutputFileType.Run(); SaveSignedSpreadsheetWithDifferentOutputFileType.Run(); SaveSignedWordProcessingWithDifferentOutputFileType.Run(); SaveSignedPresentationWithDifferentOutputFileType.Run(); SaveSignedImageWithDifferentOutputFileType.Run(); SaveSignedImageWithVariousOutputTypes.Run(); SaveDocumentWithPassword.Run(); SaveSignedDocumentsAsImages.Run(); #endregion #region Document Preview with hiding signatures GeneratePreviewAdvanced.Run(); GetDocumentInfoAdvanced.Run(); GetDocumentProcessHistoryAdvanced.Run(); #endregion #region Handling different special exceptions HandlingIncorrectPasswordException.Run(); HandlingPasswordRequiredException.Run(); #endregion #region Sign document with different signature types with additional options //Sign document with text signature applying specific options SignWithTextAdvanced.Run(); //Sign document with digital signature applying specific options SignWithDigitalAdvanced.Run(); //Sign Pdf document with digital time stamp SignWithDigitalAdvancedPdfTimestamp.Run(); //Sign Pdf document with digital certificate SignWithDigitalAdvancedPdfCertificate.Run(); //Sign Pdf document with digital certificate and custom appearance settings SignWithDigitalAdvancedPdfAppearance.Run(); //Sign document with image signature applying specific options SignWithImageAdvanced.Run(); //Sign document with Barcode signature applying specific options SignWithBarcodeAdvanced.Run(); //Sign document with QR-Code signature applying specific options SignWithQRCodeAdvanced.Run(); // Sign Pdf document with Form-fields SignPdfWithFormFieldAdvanced.Run(); SignPdfWithFormFieldAdvancedRadio.Run(); SignPdfWithFormFieldAdvancedCombobox.Run(); // Sign Pdf document with Stamp signature SignWithStampAdvanced.Run(); // Sign Spreadsheet document with XAdes signature SignWithXAdESTypes.Run(); #endregion #region Sign with further result analysis SignWithResultAnalysis.Run(); #endregion #region Sign with different signature implementation type SignWithTextStamp.Run(); SignWithTextAnnotation.Run(); SignWithTextImage.Run(); SignWithTextSticker.Run(); SignWithTextFormField.Run(); SignWithTextWatermark.Run(); SignWithTextWatermarkNative.Run(); #endregion #region Sign QR-Code Encryption, Custom encryption, custom serialization SignWithQRCodeEncryptedText.Run(); SignWithQRCodeEncryptedObject.Run(); SignWithQRCodeCustomEncryptionObject.Run(); SignWithQRCodeCustomSerializationObject.Run(); #endregion #region Sign QR-Code standard objects SignWithQRCodeAddressObject.Run(); SignWithQRCodeEmailObject.Run(); SignWithQRCodeVCardObject.Run(); SignWithQRCodeEPCObject.Run(); SignWithQRCodeEventObject.Run(); SignWithQRCodeMeCardObject.Run(); #endregion #region Sign Metadata advanced //Sign document with Metadata signature applying specific options SignPdfWithStandardMetadata.Run(); SignPdfWithCustomMetadata.Run(); SignImageWithCustomMetadata.Run(); SignWithMetadataEncryptedText.Run(); SignWithMetadataEncryptedObject.Run(); SignWithMetadataCustomEncryptionObject.Run(); SignWithMetadataCustomSerializationObject.Run(); #endregion #region Sign with different annotation SignWithPdfTextAnnotation.Run(); SignWithPdfTextSticker.Run(); SignWithImageAppearance.Run(); SignWithDigitalAppearance.Run(); #endregion #region Sign with different measure type SignWithMillimeters.Run(); SignWithPercents.Run(); SignWithAlignments.Run(); #endregion SignWithStretchMode.Run(); SignWithExceptionHandling.Run(); #region Signing with different brush styles SignWithSolidBrush.Run(); SignWithTextureBrush.Run(); SignWithLinearGradientBrush.Run(); SignWithRadialGradientBrush.Run(); #endregion #region Search signed documents for different signature types with additional options //Search document for Text signature with applying specific options SearchForTextAdvanced.Run(); //Search document for Image signature with applying specific options SearchForImageAdvanced.Run(); //Search document for Barcode signature with applying specific options SearchForBarcodeAdvanced.Run(); //Search document for encrypted QR-Code signature with applying specific options SearchForQRCodeAdvanced.Run(); //Search document for digital signature with applying specific options SearchForDigitalAdvanced.Run(); //Search document for form-field signature with applying specific options SearchForFormFieldAdvanced.Run(); //Advanced search image document for metadata signatures SearchImageForMetadataAdvanced.Run(); //Advanced search PDF document for metadata signatures SearchPdfForMetadataAdvanced.Run(); //Advanced search Presentation document for metadata signatures SearchPresentationForMetadataAdvanced.Run(); //Advanced search Spreadsheet document for metadata signatures SearchSpreadsheetForMetadataAdvanced.Run(); //Advanced search WordProcessing document for metadata signatures SearchWordProcessingForMetadataAdvanced.Run(); #region Search for QR-Code Encryption, Custom encryption, custom serialization SearchForMetadataEncryptedText.Run(); SearchForMetadataEncryptedObject.Run(); SearchForMetadataCustomEncryptionObject.Run(); SearchForMetadataCustomSerializationObject.Run(); #endregion #region Search for QR-Code standard objects SearchForQRCodeAddressObject.Run(); SearchForQRCodeEmailObject.Run(); SearchForQRCodeVCardObject.Run(); SearchForQRCodeEPCObject.Run(); SearchForQRCodeEventObject.Run(); SearchForQRCodeMeCardObject.Run(); #endregion SearchWithExceptionHandling.Run(); #endregion // Search signed documents for different signature types with additional options #region Search for QR-Code Encryption, custom encryption, custom serialization SearchForQRCodeEncryptedText.Run(); SearchForQRCodeEncryptedObject.Run(); SearchForQRCodeCustomEncryptionObject.Run(); SearchForQRCodeCustomSerializationObject.Run(); #endregion SearchAndSkipExternalSignatures.Run(); #region Verify signed documents with additional options //Verify document with Text signature with applying specific options VerifyTextAdvanced.Run(); //Verify document with Barcode signature with applying specific options VerifyBarcodeAdvanced.Run(); //Verify document with QR-Code signature with applying specific options VerifyQRCodeAdvanced.Run(); //Verify document with digital signature with applying specific options VerifyDigitalAdvanced.Run(); #endregion // Verify signed documents with additional options #region Subscribing for signing, verification, searching events SubscribeSignEvents.Run(); SubscribeVerifyEvents.Run(); SubscribeSearchEvents.Run(); #endregion #region Cancellation of signing, verification, searching process CancellationSignProcess.Run(); CancellationVerifyProcess.Run(); CancellationSearchProcess.Run(); #endregion VerifyWithExceptionHandling.Run(); #region Updating document signatures UpdateTextAfterSearch.Run(); UpdateTextById.Run(); UpdateImageAfterSearch.Run(); UpdateImageById.Run(); UpdateBarcodeAfterSearch.Run(); UpdateBarcodeById.Run(); UpdateQRCodeAfterSearch.Run(); UpdateQRCodeById.Run(); UpdateMultipleAdvanced.Run(); #endregion #region Delete signatures from the document DeleteTextAfterSearch.Run(); DeleteTextById.Run(); DeleteImageAfterSearch.Run(); DeleteImageById.Run(); DeleteBarcodeAfterSearch.Run(); DeleteBarcodeById.Run(); DeleteQRCodeAfterSearch.Run(); DeleteQRCodeById.Run(); DeleteDigitalAfterSearch.Run(); DeleteDigitalById.Run(); DeleteMultipleAdvanced.Run(); #endregion #region Processing signatures over all CRUD operation to show full signature process life-cycle ProcessingTextSignatureOverCRUD.Run(); ProcessingImageSignatureOverCRUD.Run(); ProcessingBarcodeSignatureOverCRUD.Run(); ProcessingQrCodeSignatureOverCRUD.Run(); #endregion OptionsSerialization.Run(); #endregion // Advanced Usage Console.WriteLine(); Console.WriteLine("All done."); Console.ReadKey(); }
private async Task RequestHandler(HttpContext ctx) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } DateTime startTime = DateTime.Now; S3Context s3ctx = null; try { s3ctx = new S3Context(ctx, _BaseDomains, null, (Logging.S3Requests ? Logger : null)); s3ctx.Response.Headers.Add("x-amz-request-id", s3ctx.Request.RequestId); s3ctx.Response.Headers.Add("x-amz-id-2", s3ctx.Request.RequestId); } catch (Exception e) { if (Logging.Exceptions) { Logger?.Invoke(_Header + "Exception:" + Environment.NewLine + Common.SerializeJson(e, true)); } return; } bool success = false; bool exists = false; S3Object s3obj = null; ObjectMetadata md = null; AccessControlPolicy acp = null; LegalHold legalHold = null; Retention retention = null; Tagging tagging = null; ListAllMyBucketsResult buckets = null; ListBucketResult listBucketResult = null; ListVersionsResult listVersionResult = null; LocationConstraint location = null; BucketLoggingStatus bucketLogging = null; VersioningConfiguration versionConfig = null; WebsiteConfiguration wc = null; DeleteMultiple delMultiple = null; DeleteResult delResult = null; try { if (Logging.HttpRequests) { Logger?.Invoke(_Header + "HTTP request: " + Environment.NewLine + s3ctx.Http.ToJson(true)); } if (Logging.S3Requests) { Logger?.Invoke(_Header + "S3 request: " + Environment.NewLine + s3ctx.Request.ToJson(true)); } if (PreRequestHandler != null) { success = await PreRequestHandler(s3ctx).ConfigureAwait(false); if (success) { await s3ctx.Response.Send().ConfigureAwait(false); return; } } switch (s3ctx.Request.RequestType) { #region Service case S3RequestType.ListBuckets: if (Service.ListBuckets != null) { buckets = await Service.ListBuckets(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(buckets)).ConfigureAwait(false); return; } break; #endregion #region Bucket case S3RequestType.BucketDelete: if (Bucket.Delete != null) { await Bucket.Delete(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 204; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketDeleteTags: if (Bucket.DeleteTagging != null) { await Bucket.DeleteTagging(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 204; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketDeleteWebsite: if (Bucket.DeleteWebsite != null) { await Bucket.DeleteWebsite(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 204; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketExists: if (Bucket.Exists != null) { exists = await Bucket.Exists(s3ctx).ConfigureAwait(false); if (exists) { ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); } else { ctx.Response.StatusCode = 404; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); } return; } break; case S3RequestType.BucketRead: if (Bucket.Read != null) { listBucketResult = await Bucket.Read(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(listBucketResult)).ConfigureAwait(false); return; } break; case S3RequestType.BucketReadAcl: if (Bucket.ReadAcl != null) { acp = await Bucket.ReadAcl(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(acp)).ConfigureAwait(false); return; } break; case S3RequestType.BucketReadLocation: if (Bucket.ReadLocation != null) { location = await Bucket.ReadLocation(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(location)).ConfigureAwait(false); return; } break; case S3RequestType.BucketReadLogging: if (Bucket.ReadLogging != null) { bucketLogging = await Bucket.ReadLogging(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(bucketLogging)).ConfigureAwait(false); return; } break; case S3RequestType.BucketReadTags: if (Bucket.ReadTagging != null) { tagging = await Bucket.ReadTagging(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(tagging)).ConfigureAwait(false); return; } break; case S3RequestType.BucketReadVersioning: if (Bucket.ReadVersioning != null) { versionConfig = await Bucket.ReadVersioning(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(versionConfig)).ConfigureAwait(false); return; } break; case S3RequestType.BucketReadVersions: if (Bucket.ReadVersions != null) { listVersionResult = await Bucket.ReadVersions(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(listVersionResult)).ConfigureAwait(false); return; } break; case S3RequestType.BucketReadWebsite: if (Bucket.ReadWebsite != null) { wc = await Bucket.ReadWebsite(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(wc)).ConfigureAwait(false); return; } break; case S3RequestType.BucketWrite: if (Bucket.Write != null) { await Bucket.Write(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketWriteAcl: if (Bucket.WriteAcl != null) { try { acp = Common.DeserializeXml <AccessControlPolicy>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Bucket.WriteAcl(s3ctx, acp).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketWriteLogging: if (Bucket.WriteLogging != null) { try { bucketLogging = Common.DeserializeXml <BucketLoggingStatus>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Bucket.WriteLogging(s3ctx, bucketLogging).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketWriteTags: if (Bucket.WriteTagging != null) { try { tagging = Common.DeserializeXml <Tagging>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Bucket.WriteTagging(s3ctx, tagging).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketWriteVersioning: if (Bucket.WriteVersioning != null) { try { versionConfig = Common.DeserializeXml <VersioningConfiguration>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Bucket.WriteVersioning(s3ctx, versionConfig).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.BucketWriteWebsite: if (Bucket.WriteWebsite != null) { try { wc = Common.DeserializeXml <WebsiteConfiguration>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Bucket.WriteWebsite(s3ctx, wc).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; #endregion #region Object case S3RequestType.ObjectDelete: if (Object.Delete != null) { await Object.Delete(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 204; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.ObjectDeleteMultiple: if (Object.DeleteMultiple != null) { try { delMultiple = Common.DeserializeXml <DeleteMultiple>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } delResult = await Object.DeleteMultiple(s3ctx, delMultiple).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(delResult)).ConfigureAwait(false); return; } break; case S3RequestType.ObjectDeleteTags: if (Object.DeleteTagging != null) { await Object.DeleteTagging(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 204; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.ObjectExists: if (Object.Exists != null) { md = await Object.Exists(s3ctx).ConfigureAwait(false); if (md != null) { if (!String.IsNullOrEmpty(md.ETag)) { ctx.Response.Headers.Add("ETag", md.ETag); } ctx.Response.Headers.Add("Last-Modified", md.LastModified.ToString()); ctx.Response.Headers.Add("x-amz-storage-class", md.StorageClass); ctx.Response.StatusCode = 200; ctx.Response.ContentLength = md.Size; ctx.Response.ContentType = md.ContentType; await ctx.Response.Send(md.Size).ConfigureAwait(false); } else { ctx.Response.StatusCode = 404; await ctx.Response.Send().ConfigureAwait(false); } return; } break; case S3RequestType.ObjectRead: if (Object.Read != null) { s3obj = await Object.Read(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = s3obj.ContentType; ctx.Response.ContentLength = s3obj.Size; await ctx.Response.Send(s3obj.Size, s3obj.Data).ConfigureAwait(false); return; } break; case S3RequestType.ObjectReadAcl: if (Object.ReadAcl != null) { acp = await Object.ReadAcl(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(acp)).ConfigureAwait(false); return; } break; case S3RequestType.ObjectReadLegalHold: if (Object.ReadLegalHold != null) { legalHold = await Object.ReadLegalHold(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(legalHold)).ConfigureAwait(false); return; } break; case S3RequestType.ObjectReadRange: if (Object.ReadRange != null) { s3obj = await Object.ReadRange(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = s3obj.ContentType; ctx.Response.ContentLength = s3obj.Size; await ctx.Response.Send(s3obj.Size, s3obj.Data).ConfigureAwait(false); return; } break; case S3RequestType.ObjectReadRetention: if (Object.ReadRetention != null) { retention = await Object.ReadRetention(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(retention)).ConfigureAwait(false); return; } break; case S3RequestType.ObjectReadTags: if (Object.ReadTagging != null) { tagging = await Object.ReadTagging(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/xml"; await ctx.Response.Send(Common.SerializeXml(tagging)).ConfigureAwait(false); return; } break; case S3RequestType.ObjectWrite: if (Object.Write != null) { await Object.Write(s3ctx).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.ObjectWriteAcl: if (Object.WriteAcl != null) { try { acp = Common.DeserializeXml <AccessControlPolicy>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Object.WriteAcl(s3ctx, acp).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.ObjectWriteLegalHold: if (Object.WriteLegalHold != null) { try { legalHold = Common.DeserializeXml <LegalHold>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Object.WriteLegalHold(s3ctx, legalHold).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.ObjectWriteRetention: if (Object.WriteRetention != null) { try { retention = Common.DeserializeXml <Retention>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Object.WriteRetention(s3ctx, retention).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; case S3RequestType.ObjectWriteTags: if (Object.WriteTagging != null) { try { tagging = Common.DeserializeXml <Tagging>(s3ctx.Request.DataAsString); } catch (InvalidOperationException ioe) { ioe.Data.Add("Context", s3ctx); ioe.Data.Add("RequestBody", s3ctx.Request.DataAsString); Logger?.Invoke(_Header + "XML exception: " + Environment.NewLine + Common.SerializeJson(ioe, true)); await s3ctx.Response.Send(S3Objects.ErrorCode.MalformedXML).ConfigureAwait(false); return; } await Object.WriteTagging(s3ctx, tagging).ConfigureAwait(false); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/plain"; await ctx.Response.Send().ConfigureAwait(false); return; } break; #endregion } if (DefaultRequestHandler != null) { await DefaultRequestHandler(s3ctx).ConfigureAwait(false); return; } await s3ctx.Response.Send(S3Objects.ErrorCode.InvalidRequest).ConfigureAwait(false); return; } catch (S3Exception s3e) { if (Logging.Exceptions) { Logger?.Invoke(_Header + "S3 exception:" + Environment.NewLine + Common.SerializeJson(s3e, true)); } await s3ctx.Response.Send(s3e.Error).ConfigureAwait(false); return; } catch (Exception e) { if (Logging.Exceptions) { Logger?.Invoke(_Header + "exception:" + Environment.NewLine + Common.SerializeJson(e, true)); } await s3ctx.Response.Send(S3Objects.ErrorCode.InternalError).ConfigureAwait(false); return; } finally { if (Logging.HttpRequests) { Logger?.Invoke( _Header + "[" + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + "] " + ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery + " " + s3ctx.Response.StatusCode + " [" + Common.TotalMsFrom(startTime) + "ms]"); } if (PostRequestHandler != null) { await PostRequestHandler(s3ctx).ConfigureAwait(false); } } }