@@ -15,44 +15,51 @@ public extension S3 {
1515
1616 // MARK: Buckets
1717
18- // /// Get bucket location
19- // public func location(bucket: String, on container: Container) throws -> Future<Bucket.Location> {
20- // let region = region ?? signer.config.region
21- // guard let url = URL(string: "https://\(bucket).s3.amazonaws.com/?location"), let host = url.host else {
22- // throw Error.invalidUrl
23- // }
24- //
25- // let headers = [
26- // "host": host
27- // ]
28- // let awsHeaders = try signer.headers(for: .GET, urlString: url.absoluteString, region: region, headers: headers, payload: .none)
29- // return try make(request: url, method: .GET, headers: awsHeaders, data: "".convertToData(), on: container).map(to: Bucket.Location.self) { response in
30- // if response.http.status == .notFound {
31- // throw Error.notFound
32- // }
33- // guard response.http.status == .ok || response.http.status == .noContent else {
34- // if let error = try? response.decode(to: ErrorMessage.self) {
35- // throw Error.errorResponse(response.http.status, error)
36- // } else {
37- // throw Error.badResponse(response)
38- // }
39- // }
40- // return try response.decode(to: Bucket.Location.self)
41- // }
42- // }
18+ /// Get bucket location
19+ public func location( bucket: String , on container: Container ) throws -> Future < Region > {
20+ let builder = urlBuilder ( for: container)
21+ let region = Region . euWest2
22+ let url = try builder. url ( region: region, bucket: bucket)
23+
24+ let awsHeaders = try signer. headers ( for: . GET, urlString: url. absoluteString, region: region, payload: . none)
25+ return try make ( request: url, method: . GET, headers: awsHeaders, data: emptyData ( ) , on: container) . map ( to: Region . self) { response in
26+ if response. http. status == . notFound {
27+ throw Error . notFound
28+ }
29+ if response. http. status == . ok {
30+ return region
31+ } else {
32+ if let error = try ? response. decode ( to: ErrorMessage . self) , error. code == " PermanentRedirect " , let endpoint = error. endpoint {
33+ if endpoint == " s3.amazonaws.com " {
34+ return Region . usEast1
35+ } else {
36+ // Split bucket.s3.region.amazonaws.com into parts
37+ var parts = endpoint. split ( separator: " . " )
38+ // Remove .com
39+ parts. removeLast ( )
40+ // Remove .amazonaws
41+ parts. removeLast ( )
42+ // Get region (lat part)
43+ let regionString = String ( parts. removeLast ( ) ) . lowercased ( )
44+ guard let region = Region ( rawValue: regionString) else {
45+ throw Error . badResponse ( response)
46+ }
47+ return region
48+ }
49+ } else {
50+ throw Error . badResponse ( response)
51+ }
52+ }
53+ }
54+ }
4355
4456 /// Delete bucket
4557 public func delete( bucket: String , region: Region ? = nil , on container: Container ) throws -> Future < Void > {
46- let region = region ?? signer. config. region
47- guard let url = URL ( string: " https:// \( bucket) .s3. \( region. rawValue) .amazonaws.com/ " ) , let host = url. host else {
48- throw Error . invalidUrl
49- }
58+ let builder = urlBuilder ( for: container)
59+ let url = try builder. url ( region: region, bucket: bucket)
5060
51- let headers = [
52- " host " : host
53- ]
54- let awsHeaders = try signer. headers ( for: . DELETE, urlString: url. absoluteString, region: region, headers: headers, payload: . none)
55- return try make ( request: url, method: . DELETE, headers: awsHeaders, data: " " . convertToData ( ) , on: container) . map ( to: Void . self) { response in
61+ let awsHeaders = try signer. headers ( for: . DELETE, urlString: url. absoluteString, region: region, payload: . none)
62+ return try make ( request: url, method: . DELETE, headers: awsHeaders, data: emptyData ( ) , on: container) . map ( to: Void . self) { response in
5663 try self . check ( response)
5764 return Void ( )
5865 }
@@ -61,9 +68,9 @@ public extension S3 {
6168 /// Create a bucket
6269 public func create( bucket: String , region: Region ? = nil , on container: Container ) throws -> Future < Void > {
6370 let region = region ?? signer. config. region
64- guard let url = URL ( string : " https:// \( bucket ) .s3. \( region . rawValue ) .amazonaws.com/ " ) , let host = url . host else {
65- throw Error . invalidUrl
66- }
71+
72+ let builder = urlBuilder ( for : container )
73+ let url = try builder . url ( region : region , bucket : bucket )
6774
6875 let content = """
6976 <CreateBucketConfiguration xmlns= " http://s3.amazonaws.com/doc/2006-03-01/ " >
@@ -72,11 +79,7 @@ public extension S3 {
7279 """
7380
7481 let data = content. convertToData ( )
75-
76- let headers = [
77- " host " : host
78- ]
79- let awsHeaders = try signer. headers ( for: . PUT, urlString: url. absoluteString, region: region, headers: headers, payload: . bytes( data) )
82+ let awsHeaders = try signer. headers ( for: . PUT, urlString: url. absoluteString, region: region, payload: . bytes( data) )
8083 return try make ( request: url, method: . PUT, headers: awsHeaders, data: data, on: container) . map ( to: Void . self) { response in
8184 try self . check ( response)
8285 return Void ( )
0 commit comments