internal GetObjectsListResponse(HttpStatusCode statusCode, string responseContent) : base(statusCode, responseContent) { if (string.IsNullOrEmpty(responseContent) || !HttpStatusCode.OK.Equals(statusCode)) { return; } using (var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseContent))) { this.BucketResult = (ListBucketResult) new XmlSerializer(typeof(ListBucketResult)).Deserialize(stream); } XDocument root = XDocument.Parse(responseContent); var items = from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}Contents") select new Item { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Key").Value, LastModified = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}LastModified").Value, ETag = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}ETag").Value, Size = ulong.Parse(c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Size").Value, CultureInfo.CurrentCulture), IsDir = false }; var prefixes = from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}CommonPrefixes") select new Item { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Prefix").Value, IsDir = true }; items = items.Concat(prefixes); this.ObjectsTuple = Tuple.Create(this.BucketResult, items.ToList()); }
public void Test() { string xml = @"<ListBucketResult xmlns=""http://s3.amazonaws.com/doc/2006-03-01/""> <Name>cmcdn</Name> <Prefix>1</Prefix> <Marker></Marker> <MaxKeys>100</MaxKeys> <IsTruncated>true</IsTruncated> <Contents> <Key>100000/800x600.jpeg</Key> <LastModified>2009-06-20T09:54:05.000Z</LastModified> <ETag>"c55fad5b272947050bed993ec22c6d0d"</ETag> <Size>116879</Size> <Owner> <ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID> <DisplayName>jason17095</DisplayName> </Owner> <StorageClass>STANDARD</StorageClass> </Contents> <Contents><Key>100001/800x600.jpeg</Key><LastModified>2009-06-20T09:54:01.000Z</LastModified><ETag>"4ef58e19a01ea04d4f9da27c6f6638d7"</ETag><Size>116882</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100002/800x600.jpeg</Key><LastModified>2009-06-20T09:54:03.000Z</LastModified><ETag>"684a80aa91730cb5405f7e80ce5964c4"</ETag><Size>135978</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100003/800x600.jpeg</Key><LastModified>2009-06-20T09:54:03.000Z</LastModified><ETag>"02e0d9459b336939d502dfc48735ec27"</ETag><Size>118443</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100004/800x600.jpeg</Key><LastModified>2009-06-20T09:54:05.000Z</LastModified><ETag>"1a770a89862a9c562e0d50cfaabeb3cf"</ETag><Size>78121</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100005/751x454.jpeg</Key><LastModified>2009-01-31T01:56:16.000Z</LastModified><ETag>"2de8dd5eb865d07f0290661c0810fef8"</ETag><Size>66425</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100005/76x45.jpeg</Key><LastModified>2009-01-31T01:56:15.000Z</LastModified><ETag>"b332051971d6d0c886cc82386201acc8"</ETag><Size>2767</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100005/85x66-c.jpeg</Key><LastModified>2009-02-06T19:22:13.000Z</LastModified><ETag>"aca7d00231df12c237e167e757030420"</ETag><Size>3827</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>10001/240x140-c.jpeg</Key><LastModified>2009-06-07T21:12:43.000Z</LastModified><ETag>"95971a91f300c7dfcfc2aa10eea6e0fb"</ETag><Size>15264</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>10001/800x500.jpeg</Key><LastModified>2010-01-06T07:06:36.000Z</LastModified><ETag>"705bf0b85d18f5103aef04d38c55aec4"</ETag><Size>127995</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100010/240x140-c.jpeg</Key><LastModified>2009-01-27T10:05:46.000Z</LastModified><ETag>"24cfccef22ba3f522d80da0e5ff316c7"</ETag><Size>9223</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100010/76x50.jpeg</Key><LastModified>2009-02-28T00:54:22.000Z</LastModified><ETag>"dde230c9a84cc675daf8f7ffd7c275b6"</ETag><Size>2276</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100010/800x533.jpeg</Key><LastModified>2009-02-28T00:54:21.000Z</LastModified><ETag>"328cba3f2b86aba12a9bc82c373f77f5"</ETag><Size>87509</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100011/76x50.jpeg</Key><LastModified>2009-02-28T00:54:22.000Z</LastModified><ETag>"eaeb79622b7e119d9e68c8d625b13039"</ETag><Size>2510</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100011/800x533.jpeg</Key><LastModified>2009-02-28T00:54:25.000Z</LastModified><ETag>"f0916e5b73842b971858ac9caae99e13"</ETag><Size>95977</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100012/76x50.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"a4e3b4e047ffcc7620ef0c42ab8653b8"</ETag><Size>2553</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100012/800x533.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"1e1bc2f521703d77c755b1243edc6b34"</ETag><Size>91198</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100013/76x50.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"2f8e25a2d84c53bcbaae41e3a7dfb5f9"</ETag><Size>2492</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100013/800x533.jpeg</Key><LastModified>2009-02-28T00:54:25.000Z</LastModified><ETag>"051c429013472a26e2fd53d4652e4729"</ETag><Size>83263</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100014/76x50.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"d28169de8e5ab2fee04953441237082c"</ETag><Size>2461</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100014/800x533.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"dc50d4962026a406df27f00b5a2380ac"</ETag><Size>75645</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100015/76x50.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"3b1d83db75f9a9e922d46238889e689f"</ETag><Size>2427</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100015/800x533.jpeg</Key><LastModified>2009-02-28T00:54:24.000Z</LastModified><ETag>"673395aa2384ab6aaf73c06640cb529d"</ETag><Size>74532</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100017/76x50.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"e1712adc4d2c65be6630a4469929c186"</ETag><Size>2490</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100017/800x533.jpeg</Key><LastModified>2009-02-28T00:54:24.000Z</LastModified><ETag>"16ea459e7ec536df7a8d9f99f97807f1"</ETag><Size>85499</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100018/76x50.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"7d07a81ad9f228c529936f37c4a5516e"</ETag><Size>2459</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100018/800x533.jpeg</Key><LastModified>2009-02-28T00:54:25.000Z</LastModified><ETag>"a6736b9c704c969849317b5017a58f26"</ETag><Size>80252</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100019/76x50.jpeg</Key><LastModified>2009-02-28T00:54:23.000Z</LastModified><ETag>"ac878f96e63148727205f380eeafa295"</ETag><Size>2561</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100019/800x533.jpeg</Key><LastModified>2009-02-28T00:54:27.000Z</LastModified><ETag>"b827d4034ad09e7a7937777e375fb623"</ETag><Size>76946</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100020/76x50.jpeg</Key><LastModified>2009-02-28T00:54:39.000Z</LastModified><ETag>"a79bff93ce728f3b69dd688641a2c146"</ETag><Size>2353</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100020/800x533.jpeg</Key><LastModified>2009-02-28T00:54:27.000Z</LastModified><ETag>"a99b3c3677de66374f5ced105b302785"</ETag><Size>73828</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100021/76x50.jpeg</Key><LastModified>2009-02-28T00:54:40.000Z</LastModified><ETag>"343e1f3754bc843eda87994fabc7dcda"</ETag><Size>2498</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100021/800x533.jpeg</Key><LastModified>2009-02-28T00:54:28.000Z</LastModified><ETag>"e7880067cf3dcc866e89290d438d0a36"</ETag><Size>73382</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100022/76x50.jpeg</Key><LastModified>2009-02-28T00:54:40.000Z</LastModified><ETag>"de99cc0099552e733beb5b52bc57fb45"</ETag><Size>2238</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100022/800x533.jpeg</Key><LastModified>2009-02-28T00:54:29.000Z</LastModified><ETag>"445e02490c560a46ce5f6b5302597027"</ETag><Size>63673</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100023/76x50.jpeg</Key><LastModified>2009-02-28T00:54:40.000Z</LastModified><ETag>"56bcfb29ef325109e2307e0ab2680dba"</ETag><Size>3035</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100023/800x533.jpeg</Key><LastModified>2009-02-28T00:54:29.000Z</LastModified><ETag>"f1a566c9279edda735ddf348ba7eefed"</ETag><Size>98221</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100024/76x50.jpeg</Key><LastModified>2009-02-28T00:54:41.000Z</LastModified><ETag>"91065780c3427da413691d0ef824f282"</ETag><Size>2644</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100024/800x533.jpeg</Key><LastModified>2009-02-28T00:54:30.000Z</LastModified><ETag>"625ddecda88a8d58106e855e95a8b8ed"</ETag><Size>93177</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100025/76x50.jpeg</Key><LastModified>2009-02-28T00:54:41.000Z</LastModified><ETag>"6706a4632023afffe54d38e5166de7d5"</ETag><Size>2259</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100025/800x533.jpeg</Key><LastModified>2009-02-28T00:54:31.000Z</LastModified><ETag>"72b366054ccaf53951667002054ec3e3"</ETag><Size>72609</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100026/76x50.jpeg</Key><LastModified>2009-02-28T00:54:41.000Z</LastModified><ETag>"d8357e4a81050e9df810ca88fc6c552f"</ETag><Size>2334</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100026/800x533.jpeg</Key><LastModified>2009-02-28T00:54:31.000Z</LastModified><ETag>"1abc6d54a4b6aa50eb593678d055acf8"</ETag><Size>79443</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100027/76x50.jpeg</Key><LastModified>2009-02-28T00:54:41.000Z</LastModified><ETag>"06aa89fdf4862f3185b1ad9586e19c1b"</ETag><Size>2312</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100027/800x533.jpeg</Key><LastModified>2009-02-28T00:54:31.000Z</LastModified><ETag>"f31e927a00e45239e9dc2dfe4ddd5041"</ETag><Size>78452</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100028/76x50.jpeg</Key><LastModified>2009-02-28T00:54:41.000Z</LastModified><ETag>"f606cc5da137f0f7bd07d9c64e75daba"</ETag><Size>2309</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100028/800x533.jpeg</Key><LastModified>2009-02-28T00:54:32.000Z</LastModified><ETag>"f4eac353a67c82dd63a5f0a011e3357d"</ETag><Size>85090</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100029/76x50.jpeg</Key><LastModified>2009-02-28T00:56:03.000Z</LastModified><ETag>"35b8b239daf9f23647d5b92dd8df308a"</ETag><Size>2412</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100029/800x533.jpeg</Key><LastModified>2009-02-28T00:54:34.000Z</LastModified><ETag>"cc7e61fe17aca5e4dd3ba50328561e1c"</ETag><Size>82376</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100030/76x50.jpeg</Key><LastModified>2009-02-28T00:56:03.000Z</LastModified><ETag>"4e209441b31e574f843a5ed33bfc38f7"</ETag><Size>2578</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100030/800x533.jpeg</Key><LastModified>2009-02-28T00:54:34.000Z</LastModified><ETag>"5b8248bb4e384ba4bee327c5b123c3fc"</ETag><Size>85491</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100031/76x50.jpeg</Key><LastModified>2009-02-28T00:56:03.000Z</LastModified><ETag>"dc394bed0ccfe643d68c5b3f978a8f67"</ETag><Size>2480</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100031/800x533.jpeg</Key><LastModified>2009-02-28T00:54:34.000Z</LastModified><ETag>"ad37a9d4aeb36191a2ef6bb5e2094819"</ETag><Size>77359</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100032/76x50.jpeg</Key><LastModified>2009-02-28T00:56:03.000Z</LastModified><ETag>"a7a182a0c7f03c0cd13cf6231e8a856d"</ETag><Size>2289</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100032/800x533.jpeg</Key><LastModified>2009-02-28T00:54:35.000Z</LastModified><ETag>"0bf6957496054cc3fb6cf61bc2cfaef3"</ETag><Size>89525</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100033/76x50.jpeg</Key><LastModified>2009-02-28T00:56:03.000Z</LastModified><ETag>"a1fa1002203c41605b7c5eff2f6eacd0"</ETag><Size>2449</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100033/800x533.jpeg</Key><LastModified>2009-02-28T00:54:35.000Z</LastModified><ETag>"49991bf643254bda6ab226c863135917"</ETag><Size>91792</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100034/76x50.jpeg</Key><LastModified>2009-02-28T00:56:03.000Z</LastModified><ETag>"0985c6ce1916fc01c62c7e9921ed63f7"</ETag><Size>1956</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100034/800x533.jpeg</Key><LastModified>2009-02-28T00:54:36.000Z</LastModified><ETag>"3680993ea2873f698d83c3bbb390e536"</ETag><Size>70690</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100035/76x50.jpeg</Key><LastModified>2009-02-28T00:56:04.000Z</LastModified><ETag>"80d4326b5d6bfd356f5c413f54ad00f2"</ETag><Size>1808</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100035/800x533.jpeg</Key><LastModified>2009-02-28T00:54:37.000Z</LastModified><ETag>"9afc1f01f77010426e71c194b1db43a9"</ETag><Size>68424</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100036/76x50.jpeg</Key><LastModified>2009-02-28T00:56:04.000Z</LastModified><ETag>"d3d82e531099eba9e925953a60d1db6c"</ETag><Size>1859</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100036/800x533.jpeg</Key><LastModified>2009-02-28T00:54:37.000Z</LastModified><ETag>"a6d49d5ed78bcc08809cc30d018fc02a"</ETag><Size>73678</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100037/76x50.jpeg</Key><LastModified>2009-02-28T00:56:04.000Z</LastModified><ETag>"0bf20e267d951bad2033f3aaa2819ac8"</ETag><Size>2002</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100037/800x533.jpeg</Key><LastModified>2009-02-28T00:54:39.000Z</LastModified><ETag>"46d9be8508d5cc20c03dfefd6ded2e3f"</ETag><Size>78422</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100038/76x48.jpeg</Key><LastModified>2009-02-03T04:01:24.000Z</LastModified><ETag>"360258290abeb6f428107c03f3d7b4a9"</ETag><Size>2160</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100038/800x506.jpeg</Key><LastModified>2009-02-03T04:01:25.000Z</LastModified><ETag>"216a8cecf70c313fb163f4a1a93687db"</ETag><Size>131847</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100039/700x522.jpeg</Key><LastModified>2009-02-03T04:01:25.000Z</LastModified><ETag>"f1aca43d86d82b9c32ffaf92af5352e8"</ETag><Size>128155</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100039/76x56.jpeg</Key><LastModified>2009-02-03T04:01:25.000Z</LastModified><ETag>"b7d1b23ff29629accf8e564bf992f8d5"</ETag><Size>2608</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>10004/800x600.jpeg</Key><LastModified>2010-03-27T02:55:25.000Z</LastModified><ETag>"c427c400e9b3d8a4c011fd14578dde77"</ETag><Size>218644</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100041/240x140-c.jpeg</Key><LastModified>2009-05-12T19:59:34.000Z</LastModified><ETag>"4d092726dbfd38666bb6c6567348a121"</ETag><Size>13763</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100047/375x140-c.jpeg</Key><LastModified>2009-04-08T19:12:13.000Z</LastModified><ETag>"d860a6fa0369a8dad5cc063a360c2e93"</ETag><Size>19824</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100053/375x140-c.jpeg</Key><LastModified>2009-04-08T19:12:13.000Z</LastModified><ETag>"724164795e7ea772610e1b419e2dcb25"</ETag><Size>19328</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100063/440x660.jpeg</Key><LastModified>2009-02-13T01:05:54.000Z</LastModified><ETag>"be25d1f5bc9b810c168db633ce1cb975"</ETag><Size>63712</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100064/515x660.jpeg</Key><LastModified>2009-02-13T01:05:56.000Z</LastModified><ETag>"e49e6f07ea1ad3e50eb4544b6ec84d4c"</ETag><Size>87658</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100065/523x660.jpeg</Key><LastModified>2009-02-13T01:05:56.000Z</LastModified><ETag>"44dda2676acd554840c4ed41ed904d7e"</ETag><Size>68546</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100066/800x576.jpeg</Key><LastModified>2009-02-13T01:05:56.000Z</LastModified><ETag>"ec7643230b8d23b8a855673b2c3a9bec"</ETag><Size>131592</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100067/515x660.jpeg</Key><LastModified>2009-02-13T01:05:56.000Z</LastModified><ETag>"c608a2c0accdeb252d81c0a797a262dd"</ETag><Size>97100</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100068/510x660.jpeg</Key><LastModified>2009-02-15T05:21:45.000Z</LastModified><ETag>"4dd606f970296b293e72127fd0b6cf07"</ETag><Size>85451</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100070/240x140-c.jpeg</Key><LastModified>2009-02-13T01:05:31.000Z</LastModified><ETag>"a2cb5cdd46669c1d65642a26135237b1"</ETag><Size>16039</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100070/720x466.jpeg</Key><LastModified>2009-02-13T01:05:54.000Z</LastModified><ETag>"bf64556c652e7f1c8995872b8f8335fa"</ETag><Size>104092</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100071/510x660.jpeg</Key><LastModified>2009-02-13T01:05:57.000Z</LastModified><ETag>"71de6e4d96878cac54f49b17fb14a25e"</ETag><Size>54454</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100072/192x100-c.jpeg</Key><LastModified>2010-04-01T14:06:41.000Z</LastModified><ETag>"a0a8f22520697d9457b9ba6c2c4cb70c"</ETag><Size>2956</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100072/240x140-c.jpeg</Key><LastModified>2010-04-01T14:06:14.000Z</LastModified><ETag>"f490b9f88fb7161275dca323b6573c17"</ETag><Size>4524</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100072/315x420.jpeg</Key><LastModified>2010-04-01T14:06:42.000Z</LastModified><ETag>"48c4ba4cd0ce6e624b5a2259b88ce9b7"</ETag><Size>15878</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100072/495x660.jpeg</Key><LastModified>2010-04-01T14:07:06.000Z</LastModified><ETag>"12708e9813a7e3839ab95ee1ada8fcd2"</ETag><Size>41436</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100072/85x66-c.jpeg</Key><LastModified>2010-04-01T14:06:41.000Z</LastModified><ETag>"2cd741115a349d673844a79ac27253c2"</ETag><Size>1674</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100074/800x600.jpeg</Key><LastModified>2010-04-01T14:07:05.000Z</LastModified><ETag>"a5e8989d45cbaab0f2b67f8a5a8265f4"</ETag><Size>78982</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100074/85x66-c.jpeg</Key><LastModified>2010-04-01T14:06:41.000Z</LastModified><ETag>"16f7985e4474260a853036e802b35889"</ETag><Size>3190</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100075/800x600.jpeg</Key><LastModified>2010-04-01T14:07:05.000Z</LastModified><ETag>"d0d61505b21e990d18e7d5ca4072139b"</ETag><Size>75121</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100075/85x66-c.jpeg</Key><LastModified>2010-04-01T14:06:41.000Z</LastModified><ETag>"4b6f66f6454af74921c318450a602358"</ETag><Size>3239</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100076/800x600.jpeg</Key><LastModified>2010-04-01T14:07:05.000Z</LastModified><ETag>"eff3fbc8ec1e1813e8d19a9c921335a2"</ETag><Size>67024</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100076/85x66-c.jpeg</Key><LastModified>2010-04-01T14:06:42.000Z</LastModified><ETag>"a4e4a80cdf71f166606332f9b29de343"</ETag><Size>3000</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100077/240x140-c.jpeg</Key><LastModified>2009-06-12T19:03:33.000Z</LastModified><ETag>"376c3f87fef7f2f208629f42abc841de"</ETag><Size>11721</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100080/240x140-c.jpeg</Key><LastModified>2009-06-12T19:03:33.000Z</LastModified><ETag>"a4601bbf4e0ba471db75b6daffd7ed81"</ETag><Size>15132</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100093/240x140-c.jpeg</Key><LastModified>2009-06-12T20:56:33.000Z</LastModified><ETag>"76b4fd520855e9290401b191f0de3889"</ETag><Size>16637</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100094/260x37.jpeg</Key><LastModified>2009-02-08T01:10:51.000Z</LastModified><ETag>"56fc637744037fd48e2858a932d5fea7"</ETag><Size>5406</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100094/760x110-c.jpeg</Key><LastModified>2009-01-26T10:48:37.000Z</LastModified><ETag>"695432ff1b5e525587e401bd63ce015a"</ETag><Size>22911</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100110/97x102.jpeg</Key><LastModified>2010-03-17T14:09:27.000Z</LastModified><ETag>"27d3ea0bc36ac0d2f8592490c6214902"</ETag><Size>4452</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>100111/97x102.jpeg</Key><LastModified>2009-12-21T05:52:18.000Z</LastModified><ETag>"9cdae36adc5ef808dc68f4e9df4a47bc"</ETag><Size>4167</Size><Owner><ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID><DisplayName>jason17095</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>"; var result = ListBucketResult.ParseXml(xml); Assert.Equal("cmcdn", result.Name); Assert.Equal("1", result.Prefix); Assert.Equal("", result.Marker); Assert.Equal(100, result.MaxKeys); Assert.Equal(100, result.Items.Length); Assert.Equal("100000/800x600.jpeg", result.Items[0].Key); // Assert.Equal("STANDARD", result.Items[0].StorageClass); Assert.Equal(DateTime.Parse("2009-06-20T09:54:05.000Z", null, DateTimeStyles.AdjustToUniversal), result.Items[0].LastModified); }
private Tuple <ListBucketResult, List <Item> > GetObjectList(string bucket, string prefix, bool recursive, string marker) { var queries = new List <string>(); if (!recursive) { queries.Add("delimiter=%2F"); } if (prefix != null) { queries.Add("prefix=" + Uri.EscapeDataString(prefix)); } if (marker != null) { queries.Add("marker=" + Uri.EscapeDataString(marker)); } queries.Add("max-keys=1000"); string query = string.Join("&", queries); string path = bucket; if (query.Length > 0) { path += "?" + query; } var request = new RestRequest(path, Method.GET); var response = client.Execute(request); if (response.StatusCode == HttpStatusCode.OK) { var contentBytes = System.Text.Encoding.UTF8.GetBytes(response.Content); var stream = new MemoryStream(contentBytes); ListBucketResult listBucketResult = (ListBucketResult)(new XmlSerializer(typeof(ListBucketResult)).Deserialize(stream)); XDocument root = XDocument.Parse(response.Content); var items = (from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}Contents") select new Item() { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Key").Value, LastModified = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}LastModified").Value, ETag = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}ETag").Value, Size = UInt64.Parse(c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Size").Value), IsDir = false }); var prefixes = (from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}CommonPrefixes") select new Item() { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Prefix").Value, IsDir = true }); items = items.Concat(prefixes); return(new Tuple <ListBucketResult, List <Item> >(listBucketResult, items.ToList())); } throw ParseError(response); }
/// <summary> /// Gets the list of objects in the bucket filtered by prefix /// </summary> /// <param name="bucketName">Bucket to list objects from</param> /// <param name="prefix">Filters all objects not beginning with a given prefix</param> /// <param name="recursive">Set to false to emulate a directory</param> /// <param name="marker">marks location in the iterator sequence</param> /// <returns>Task with a tuple populated with objects</returns> /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param> private async Task <Tuple <ListBucketResult, List <Item> > > GetObjectListAsync(string bucketName, string prefix, bool recursive, string marker, CancellationToken cancellationToken = default(CancellationToken)) { var queries = new List <string>(); if (!recursive) { queries.Add("delimiter=%2F"); } if (prefix != null) { queries.Add("prefix=" + Uri.EscapeDataString(prefix)); } if (marker != null) { queries.Add("marker=" + Uri.EscapeDataString(marker)); } queries.Add("max-keys=1000"); string query = string.Join("&", queries); var request = await this.CreateRequest(Method.GET, bucketName, resourcePath : "?" + query) .ConfigureAwait(false); var response = await this.ExecuteTaskAsync(this.NoErrorHandlers, request, cancellationToken).ConfigureAwait(false); var contentBytes = System.Text.Encoding.UTF8.GetBytes(response.Content); ListBucketResult listBucketResult = null; using (var stream = new MemoryStream(contentBytes)) { listBucketResult = (ListBucketResult)(new XmlSerializer(typeof(ListBucketResult)).Deserialize(stream)); } XDocument root = XDocument.Parse(response.Content); var items = (from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}Contents") select new Item() { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Key").Value, LastModified = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}LastModified").Value, ETag = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}ETag").Value, Size = UInt64.Parse(c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Size").Value, CultureInfo.CurrentCulture), IsDir = false }); var prefixes = (from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}CommonPrefixes") select new Item() { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Prefix").Value, IsDir = true }); items = items.Concat(prefixes); return(new Tuple <ListBucketResult, List <Item> >(listBucketResult, items.ToList())); }
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously static async Task <ListBucketResult> BucketRead(S3Context ctx) #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously { Console.WriteLine("BucketRead: " + ctx.Request.Bucket); List <ObjectMetadata> contents = new List <ObjectMetadata>() { _ObjectMetadata }; ListBucketResult result = new ListBucketResult("default", contents, 1, 1); return(result); }
public void Test2() { var text = @"<?xml version=""1.0"" encoding=""UTF-8""?> <ListBucketResult xmlns=""http://s3.amazonaws.com/doc/2006-03-01/""> <Name>cmcdn</Name> <Prefix>1</Prefix> <Marker></Marker> <MaxKeys>100</MaxKeys> <IsTruncated>true</IsTruncated> <NextContinuationToken>1ueGcxLPRx1Tr/XYExHnhbYLgveDs2J/wm36Hy4vbOwM=</NextContinuationToken> <Contents> <Key>100000/800x600.jpeg</Key> <LastModified>2009-06-20T09:54:05.000Z</LastModified> <ETag>"c55fad5b272947050bed993ec22c6d0d"</ETag> <Size>116879</Size> <Owner> <ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID> <DisplayName>jason17095</DisplayName> </Owner> <StorageClass>STANDARD</StorageClass> </Contents> <Contents> <Key>100001/800x600.jpeg</Key> <LastModified>2009-06-20T09:54:01.000Z</LastModified> <ETag>"4ef58e19a01ea04d4f9da27c6f6638d7"</ETag> <Size>116882</Size> <Owner> <ID>9c18bda0312b59b259789b4acf29a06efdb6193a4ef51fcafa739f5cda4f3bf0</ID> <DisplayName>jason17095</DisplayName> </Owner> <StorageClass>STANDARD</StorageClass> </Contents> </ListBucketResult>"; var result = ListBucketResult.ParseXml(text); Assert.Equal("cmcdn", result.Name); Assert.Equal("1", result.Prefix); Assert.Equal(116879, result.Items[0].Size); Assert.Equal(116882, result.Items[1].Size); Assert.Equal(true, result.IsTruncated); Assert.Equal("STANDARD", result.Items[1].StorageClass); Assert.Equal("100000/800x600.jpeg", result.Items[0].Key); Assert.Equal("100001/800x600.jpeg", result.Items[1].Key); }
/// <summary> /// Gets the list of objects in the bucket filtered by prefix /// </summary> /// <param name="bucketName">Bucket to list objects from</param> /// <param name="prefix">Filters all objects starting with a given prefix</param> /// <param name="delimiter">Delimit the output upto this character</param> /// <param name="marker">marks location in the iterator sequence</param> /// <returns>Task with a tuple populated with objects</returns> /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param> private async Task <Tuple <ListBucketResult, List <Item> > > GetObjectListAsync(string bucketName, string prefix, string delimiter, string marker, CancellationToken cancellationToken = default(CancellationToken)) { var queryMap = new Dictionary <string, string>(); // null values are treated as empty strings. if (delimiter == null) { delimiter = string.Empty; } if (prefix == null) { prefix = string.Empty; } if (marker == null) { marker = string.Empty; } var request = await this.CreateRequest(Method.GET, bucketName) .ConfigureAwait(false); request.AddQueryParameter("delimiter", Uri.EscapeDataString(delimiter)); request.AddQueryParameter("prefix", Uri.EscapeDataString(prefix)); request.AddQueryParameter("max-keys", "1000"); request.AddQueryParameter("marker", Uri.EscapeDataString(marker)); request.AddQueryParameter("encoding-type", "url"); var response = await this.ExecuteTaskAsync(this.NoErrorHandlers, request, cancellationToken).ConfigureAwait(false); var contentBytes = System.Text.Encoding.UTF8.GetBytes(response.Content); ListBucketResult listBucketResult = null; using (var stream = new MemoryStream(contentBytes)) { listBucketResult = (ListBucketResult) new XmlSerializer(typeof(ListBucketResult)).Deserialize(stream); } XDocument root = XDocument.Parse(response.Content); var items = from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}Contents") select new Item { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Key").Value, LastModified = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}LastModified").Value, ETag = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}ETag").Value, Size = ulong.Parse(c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Size").Value, CultureInfo.CurrentCulture), IsDir = false }; var prefixes = from c in root.Root.Descendants("{http://s3.amazonaws.com/doc/2006-03-01/}CommonPrefixes") select new Item { Key = c.Element("{http://s3.amazonaws.com/doc/2006-03-01/}Prefix").Value, IsDir = true }; items = items.Concat(prefixes); return(Tuple.Create(listBucketResult, items.ToList())); }
public void MarshalResponse(IConfig config, ListObjectsResponse response, IDictionary <string, string> headers, Stream responseStream) { XmlSerializer s = new XmlSerializer(typeof(ListBucketResult)); using (XmlTextReader r = new XmlTextReader(responseStream)) { r.Namespaces = false; ListBucketResult bucketResult = (ListBucketResult)s.Deserialize(r); if (bucketResult.EncodingType != null) { response.EncodingType = ValueHelper.ParseEnum <EncodingType>(bucketResult.EncodingType); } response.Delimiter = config.AutoUrlDecodeResponses && response.EncodingType == EncodingType.Url ? WebUtility.UrlDecode(bucketResult.Delimiter) : bucketResult.Delimiter; response.Prefix = config.AutoUrlDecodeResponses && response.EncodingType == EncodingType.Url ? WebUtility.UrlDecode(bucketResult.Prefix) : bucketResult.Prefix; response.StartAfter = config.AutoUrlDecodeResponses && response.EncodingType == EncodingType.Url ? WebUtility.UrlDecode(bucketResult.StartAfter) : bucketResult.StartAfter; response.NextContinuationToken = bucketResult.NextContinuationToken; response.MaxKeys = bucketResult.MaxKeys; response.IsTruncated = bucketResult.IsTruncated; response.KeyCount = bucketResult.KeyCount; response.BucketName = bucketResult.Name; response.ContinuationToken = bucketResult.ContinuationToken; response.RequestCharged = headers.ContainsKey(AmzHeaders.XAmzRequestCharged); if (bucketResult.CommonPrefixes != null) { response.CommonPrefixes = new List <string>(bucketResult.CommonPrefixes.Count); foreach (CommonPrefix prefix in bucketResult.CommonPrefixes) { response.CommonPrefixes.Add(prefix.Prefix); } } else { response.CommonPrefixes = Array.Empty <string>(); } if (bucketResult.Contents != null) { response.Objects = new List <S3Object>(bucketResult.KeyCount); foreach (Content content in bucketResult.Contents) { S3Object obj = new S3Object(); obj.ObjectKey = config.AutoUrlDecodeResponses && response.EncodingType == EncodingType.Url ? WebUtility.UrlDecode(content.Key) : content.Key; obj.ETag = content.ETag; if (content.StorageClass != null) { obj.StorageClass = ValueHelper.ParseEnum <StorageClass>(content.StorageClass); } obj.LastModifiedOn = content.LastModified; obj.Size = content.Size; if (content.Owner != null) { obj.Owner = new S3Identity { Name = content.Owner.DisplayName, Id = content.Owner.Id } } ; response.Objects.Add(obj); } } else { response.Objects = Array.Empty <S3Object>(); } } }
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); } } }
public void MarshalResponse(GetBucketRequest request, GetBucketResponse response, IDictionary <string, string> headers, Stream responseStream) { XmlSerializer s = new XmlSerializer(typeof(ListBucketResult)); using (XmlTextReader r = new XmlTextReader(responseStream)) { r.Namespaces = false; ListBucketResult bucketResult = (ListBucketResult)s.Deserialize(r); response.MaxKeys = bucketResult.MaxKeys; response.IsTruncated = bucketResult.IsTruncated; response.KeyCount = bucketResult.KeyCount; response.Name = bucketResult.Name; response.Prefix = bucketResult.Prefix; response.ContinuationToken = bucketResult.ContinuationToken; if (bucketResult.CommonPrefixes != null) { response.CommonPrefixes = new List <string>(bucketResult.CommonPrefixes.Count); foreach (CommonPrefix prefix in bucketResult.CommonPrefixes) { response.CommonPrefixes.Add(prefix.Prefix); } } else { response.CommonPrefixes = Array.Empty <string>(); } if (bucketResult.EncodingType != null) { response.EncodingType = ValueHelper.ParseEnum <EncodingType>(bucketResult.EncodingType); } response.NextContinuationToken = bucketResult.NextContinuationToken; response.StartAfter = bucketResult.StartAfter; if (bucketResult.Contents != null) { response.Objects = new List <S3Object>(bucketResult.KeyCount); foreach (Content content in bucketResult.Contents) { S3Object obj = new S3Object(); obj.Name = content.Key; obj.ETag = content.ETag; if (content.StorageClass != null) { obj.StorageClass = ValueHelper.ParseEnum <StorageClass>(content.StorageClass); } obj.LastModified = content.LastModified; obj.Size = content.Size; if (content.Owner != null) { obj.Owner = new S3ObjectIdentity { Name = content.Owner.DisplayName, Id = content.Owner.Id } } ; response.Objects.Add(obj); } } else { response.Objects = Array.Empty <S3Object>(); } } }