Skip to content

Commit

Permalink
Undo whitespace changes
Browse files Browse the repository at this point in the history
  • Loading branch information
pbthif committed Aug 26, 2021
1 parent 578f642 commit da243c5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 49 deletions.
30 changes: 15 additions & 15 deletions Sources/S3Client/String+asS3ObjectIdentifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public struct S3ObjectIdentifer: Equatable {
internal static let httpsPrefix = "https://"
internal static let httpPrefix = "http://"
internal static let s3EndpointRegex = #"^https?:\/\/(.+\.)?s3[.-][a-z0-9-]+\."#

public let bucketName: String
public let keyPath: String

public init(bucketName: String,
keyPath: String) {
self.bucketName = bucketName
Expand All @@ -29,38 +29,38 @@ public extension String {
/**
If possible creates an S3ObjectIdentifer instance from this string,
seperating the bucket name and key path.

Will return nil if this string is not of the form-
s3://bucketName/the/key/path

This would return S3ObjectIdentifer(bucketName: "bucketName",
keyPath: "/the/key/path")
*/
func asS3ObjectIdentifier() -> S3ObjectIdentifer? {
if self.starts(with: S3ObjectIdentifer.s3Prefix) {
// get the url without the scheme - of the form {bucket}/{key+}
let nonPrefixedUrl = self.dropFirst(S3ObjectIdentifer.s3Prefix.count)

return asS3ObjectIdentifierFromNonPrefixedUrl(nonPrefixedUrl: nonPrefixedUrl)
} else if self.starts(with: S3ObjectIdentifer.httpsPrefix) || self.starts(with: S3ObjectIdentifer.httpPrefix) {
return asS3ObjectIdentifierFromHttpOrHttps()
}

return nil
}

/// Tries to parse the bucket and key names from an HTTP or HTTPS URL.
private func asS3ObjectIdentifierFromHttpOrHttps() -> S3ObjectIdentifer? {
guard let url = URL(string: self) else {
return nil
}

let urlPath = url.path.dropFirst()

guard let regex = try? NSRegularExpression(pattern: S3ObjectIdentifer.s3EndpointRegex, options: []) else {
return nil
}

let searchRange = NSRange(self.startIndex..<self.endIndex, in: self)
let match = regex.firstMatch(in: self, options: [], range: searchRange)
if let match = match,
Expand All @@ -75,32 +75,32 @@ public extension String {
let keyName = String(urlPath)
return S3ObjectIdentifer(bucketName: bucketName, keyPath: keyName)
}

// If the regex capture group is empty, the URL is in the path style, for example:
// https://s3.amazonaws.com/bucket/key
// Both the bucket and key names are in the URL path
return asS3ObjectIdentifierFromNonPrefixedUrl(nonPrefixedUrl: Substring(urlPath))
}

private func getIndexOfNextUrlSeparator(url: Substring) -> String.Index? {
#if swift(>=4.2)
return url.firstIndex(of: "/")
#else
return url.index(of: "/")
#endif
}

/// Spilts a url of the form {bucket}/{key+} into a S3ObjectIdentifer if possible
private func asS3ObjectIdentifierFromNonPrefixedUrl(nonPrefixedUrl: Substring) -> S3ObjectIdentifer? {
guard let nextUrlSeparator = getIndexOfNextUrlSeparator(url: nonPrefixedUrl) else {
return nil
}

let bucketKeySeperatorIndex = nonPrefixedUrl.index(nextUrlSeparator,
offsetBy: 1)
let bucketName = String(nonPrefixedUrl[..<nextUrlSeparator])
let keyPath = String(nonPrefixedUrl[bucketKeySeperatorIndex...])

return S3ObjectIdentifer(bucketName: bucketName, keyPath: keyPath)
}
}
68 changes: 34 additions & 34 deletions Tests/S3ClientTests/S3ClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ import AsyncHTTPClient
import Logging

class S3ClientTests: XCTestCase {

func testValidS3Uri() throws {
let s3Uri = "s3://bucketName/the/key/path"

let identifier = s3Uri.asS3ObjectIdentifier()

let expected = S3ObjectIdentifer(bucketName: "bucketName",
keyPath: "the/key/path")

XCTAssertEqual(expected, identifier)
}

func testValidHttpsUri() throws {
let s3Uris = [
"https://s3.amazonaws.com/bucketName/the/key/path",
Expand All @@ -36,16 +36,16 @@ class S3ClientTests: XCTestCase {
"https://bucketName.s3.us-east-1.amazonaws.com/the/key/path",
"https://bucketName.s3-abc.us-east-1.amazonaws.com/the/key/path",
]

let expected = S3ObjectIdentifer(bucketName: "bucketName",
keyPath: "the/key/path")

for s3Uri in s3Uris {
let identifier = s3Uri.asS3ObjectIdentifier()
XCTAssertEqual(expected, identifier)
}
}

func testValidHttpUri() throws {
let s3Uris = [
"http://s3.amazonaws.com/bucketName/the/key/path",
Expand All @@ -57,48 +57,48 @@ class S3ClientTests: XCTestCase {
"http://bucketName.s3.us-east-1.amazonaws.com/the/key/path",
"http://bucketName.s3-abc.us-east-1.amazonaws.com/the/key/path",
]

let expected = S3ObjectIdentifer(bucketName: "bucketName",
keyPath: "the/key/path")

for s3Uri in s3Uris {
for s3Uri in s3Uris {
let identifier = s3Uri.asS3ObjectIdentifier()
XCTAssertEqual(expected, identifier)
}
}

func testInvalidS3UriPrefix() throws {
let s3Uri = "ssh://bucketName/the/key/path"

let identifier = s3Uri.asS3ObjectIdentifier()

XCTAssertNil(identifier)
}

func testS3UriNoSeparator() throws {
let s3Uri = "s3://bucketName"

let identifier = s3Uri.asS3ObjectIdentifier()

XCTAssertNil(identifier)
}

func testHttpsUriNoSeparatorForBucket() throws {
let s3Uri = "https://bucketName"

let identifier = s3Uri.asS3ObjectIdentifier()

XCTAssertNil(identifier)
}

func testHttpsUriNoSeparatorForKey() throws {
let s3Uri = "https://host/bucketName"

let identifier = s3Uri.asS3ObjectIdentifier()

XCTAssertNil(identifier)
}

func testAccessDeniedErrorDecode() throws {
let message = "Access Denied"
let errorResponse = """
Expand All @@ -108,7 +108,7 @@ class S3ClientTests: XCTestCase {
<Message>\(message)</Message>
</Error>
"""

let response = HTTPClient.Response(host: "s3.us-west-2.amazonaws.com", status: .badRequest,
version: HTTPVersion(major: 1, minor: 1),
headers: HTTPHeaders(), body: nil)
Expand All @@ -120,16 +120,16 @@ class S3ClientTests: XCTestCase {
let error = try clientDelegate.getResponseError(response: response,
responseComponents: components,
invocationReporting: invocationReporting)

guard case let S3Error.accessDenied(returnedMessage) = error.cause else {
return XCTFail()
}

guard message == returnedMessage else {
return XCTFail()
}
}

func testAccessDeniedErrorDataAPIsDecode() throws {
let message = "Access Denied"
let errorResponse = """
Expand All @@ -139,7 +139,7 @@ class S3ClientTests: XCTestCase {
<Message>\(message)</Message>
</Error>
"""

let response = HTTPClient.Response(host: "s3.us-west-2.amazonaws.com", status: .badRequest,
version: HTTPVersion(major: 1, minor: 1),
headers: HTTPHeaders(), body: nil)
Expand All @@ -151,16 +151,16 @@ class S3ClientTests: XCTestCase {
let error = try clientDelegate.getResponseError(response: response,
responseComponents: components,
invocationReporting: invocationReporting)

guard case let S3Error.accessDenied(returnedMessage) = error.cause else {
return XCTFail()
}

guard message == returnedMessage else {
return XCTFail()
}
}

func testKnownErrorDecode() throws {
let message = "The specified key does not exist."
let errorResponse = """
Expand All @@ -171,7 +171,7 @@ class S3ClientTests: XCTestCase {
<Key>myKey</Key>
</Error>
"""

let response = HTTPClient.Response(host: "s3.us-west-2.amazonaws.com", status: .badRequest,
version: HTTPVersion(major: 1, minor: 1),
headers: HTTPHeaders(), body: nil)
Expand All @@ -183,7 +183,7 @@ class S3ClientTests: XCTestCase {
let error = try clientDelegate.getResponseError(response: response,
responseComponents: components,
invocationReporting: invocationReporting)

guard case S3Error.noSuchKey = error.cause else {
return XCTFail()
}
Expand Down

0 comments on commit da243c5

Please sign in to comment.