Skip to content

Commit

Permalink
Added APIGateway and S3Control Middleware (#261)
Browse files Browse the repository at this point in the history
- Added APIGatewayMiddleware: If an Accept header doesn't already exist adds one with value "application/json". This is required to get error codes back
- Added S3ControlMiddleware: Needed to do virtualAddressFixup
  • Loading branch information
adam-fowler authored Mar 24, 2020
1 parent 6059bfc commit 5ed9d17
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 10 deletions.
25 changes: 17 additions & 8 deletions CodeGenerator/Sources/CodeGenerator/CodeGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,21 @@ extension AWSService {
)
}

func getMiddleware() -> String? {
switch serviceName {
case "APIGateway":
return "APIGatewayMiddleware()"
case "Glacier":
return "GlacierRequestMiddleware(apiVersion: \"\(version)\")"
case "S3":
return "S3RequestMiddleware()"
case "S3Control":
return "S3ControlMiddleware()"
default:
return nil
}
}

/// Generate the context information for outputting the service api calls
func generateServiceContext() -> [String: Any] {
var context: [String: Any] = [:]
Expand All @@ -309,14 +324,8 @@ extension AWSService {
context["serviceEndpoints"] = endpoints
}
context["partitionEndpoint"] = partitionEndpoint
switch endpointPrefix {
case "s3":
context["middlewareClass"] = "S3RequestMiddleware()"
case "glacier":
context["middlewareClass"] = "GlacierRequestMiddleware(apiVersion: \"\(version)\")"
default:
break
}
context["middlewareClass"] = getMiddleware()

if !errors.isEmpty {
context["errorTypes"] = serviceErrorName
}
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ let package = Package(
targets: [
.target(name: "AWSACM", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/ACM"),
.target(name: "AWSACMPCA", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/ACMPCA"),
.target(name: "AWSAPIGateway", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/APIGateway"),
.target(name: "AWSAPIGateway", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/", sources: ["Services/APIGateway", "Extensions/APIGateway"]),
.target(name: "AWSAccessAnalyzer", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/AccessAnalyzer"),
.target(name: "AWSAlexaForBusiness", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/AlexaForBusiness"),
.target(name: "AWSAmplify", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/Amplify"),
Expand Down Expand Up @@ -410,7 +410,7 @@ let package = Package(
.target(name: "AWSRoute53Domains", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/Route53Domains"),
.target(name: "AWSRoute53Resolver", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/Route53Resolver"),
.target(name: "AWSS3", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/", sources: ["Services/S3", "Extensions/S3"]),
.target(name: "AWSS3Control", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/S3Control"),
.target(name: "AWSS3Control", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/", sources: ["Services/S3Control", "Extensions/S3Control"]),
.target(name: "AWSSES", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/SES"),
.target(name: "AWSSESV2", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/SESV2"),
.target(name: "AWSSFN", dependencies: ["AWSSDKSwiftCore"], path: "./Sources/AWSSDKSwift/Services/SFN"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import AWSSDKSwiftCore

public struct APIGatewayMiddleware: AWSServiceMiddleware {
public func chain(request: AWSRequest) throws -> AWSRequest {
var request = request
// have to set Accept header to application/json otherwise errors are not returned correctly
if request.httpHeaders["Accept"] == nil {
request.httpHeaders["Accept"] = "application/json"
}
return request
}
}
35 changes: 35 additions & 0 deletions Sources/AWSSDKSwift/Extensions/S3Control/S3ControlMiddleware.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import struct Foundation.CharacterSet
import struct Foundation.URL
import struct Foundation.URLComponents
import struct Foundation.URLQueryItem
import AWSSDKSwiftCore

public struct S3ControlMiddleware: AWSServiceMiddleware {

public init () {}

/// edit request before sending to S3
public func chain(request: AWSRequest) throws -> AWSRequest {
var request = request

virtualAddressFixup(request: &request)

return request
}

func virtualAddressFixup(request: inout AWSRequest) {
/// process URL into form ${account-id}.s3control.${region}.amazon.com
guard let accountId = request.httpHeaders["x-amz-account-id"] else { return }
guard let host = request.url.host else { return }
let urlHost = "\(accountId).\(host)"
var urlPath = "\(urlHost)\(request.url.path)"
// add percent encoding back into path as converting from URL to String has removed it
urlPath = urlPath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? urlPath
var urlString = "\(request.url.scheme ?? "https")://\(urlPath)"
if let query = request.url.query {
urlString += "?\(query)"
}
request.url = URL(string: urlString)!
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public struct APIGateway {
/// - middlewares: Array of middlewares to apply to requests and responses
/// - eventLoopGroupProvider: EventLoopGroup to use. Use `useAWSClientShared` if the client shall manage its own EventLoopGroup.
public init(accessKeyId: String? = nil, secretAccessKey: String? = nil, sessionToken: String? = nil, region: AWSSDKSwiftCore.Region? = nil, endpoint: String? = nil, middlewares: [AWSServiceMiddleware] = [], eventLoopGroupProvider: AWSClient.EventLoopGroupProvider = .useAWSClientShared) {
let middlewares = [APIGatewayMiddleware()] + middlewares
self.client = AWSClient(
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
Expand Down
1 change: 1 addition & 0 deletions Sources/AWSSDKSwift/Services/S3Control/S3Control_API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public struct S3Control {
/// - middlewares: Array of middlewares to apply to requests and responses
/// - eventLoopGroupProvider: EventLoopGroup to use. Use `useAWSClientShared` if the client shall manage its own EventLoopGroup.
public init(accessKeyId: String? = nil, secretAccessKey: String? = nil, sessionToken: String? = nil, region: AWSSDKSwiftCore.Region? = nil, endpoint: String? = nil, middlewares: [AWSServiceMiddleware] = [], eventLoopGroupProvider: AWSClient.EventLoopGroupProvider = .useAWSClientShared) {
let middlewares = [S3ControlMiddleware()] + middlewares
self.client = AWSClient(
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
Expand Down

0 comments on commit 5ed9d17

Please sign in to comment.