Repository: vapor/vapor
File: Sources/Vapor/Engine/EngineClient.swift (Swift)

Code before:
    private func tlsRespond(to req: Request, redirecting: Int) throws -> Future<Response> {
        let tcpSocket = try TCPSocket(isNonBlocking: true)
        let tcpClient = try TCPClient(socket: tcpSocket)
        var settings = TLSClientSettings()
        let hostname = try req.http.uri.requireHostname()
        settings.peerDomainName = hostname
        #if os(macOS)
            let tlsClient = try AppleTLSClient(tcp: tcpClient, using: settings)
        #else
            let tlsClient = try OpenSSLClient(tcp: tcpClient, using: settings)
        #endif
        try tlsClient.connect(hostname: hostname, port: req.http.uri.port ?? 443)
        let client = HTTPClient(
            stream: tlsClient.socket.stream(on: self.container),
            on: self.container
        )
        req.http.headers[.host] = hostname
        return client.send(req.http).flatMap(to: Response.self) { httpRes in
            tlsClient.close()
            
            return try self.response(from: httpRes, for: req, redirecting: redirecting)
        }
    }

    /// Responds to a Request using TCP client.
    private func plaintextRespond(to req: Request, redirecting: Int) throws -> Future<Response> {
        let tcpSocket = try TCPSocket(isNonBlocking: true)
        let tcpClient = try TCPClient(socket: tcpSocket)
        let hostname = try req.http.uri.requireHostname()
        try tcpClient.connect(hostname: hostname, port: req.http.uri.port ?? 80)
        let stream = tcpSocket.stream(on: self.container) { _, error in
            print("[Client] \(error)")
        }
        let client = HTTPClient(
            stream: stream,
            on: self.container
        )
        req.http.headers[.host] = hostname
        return client.send(req.http).flatMap(to: Response.self) { httpRes in
            tcpClient.close()
            
            return try self.response(from: httpRes, for: req, redirecting: redirecting)
        }
    }
}

/// Configuration option's for the EngineClient.
public struct EngineClientConfig: Service {
    /// The maximum response size to allow for
    /// incoming HTTP responses.
    public let maxResponseSize: Int

Review comment (suggestion):
I know this is internal API, but I think it should be `maxRedirections:`

Code after:
        req.http.headers[.host] = hostname
        return client.send(req.http).flatMap(to: Response.self) { httpRes in
            tlsClient.close()
            
            return try self.response(from: httpRes, for: req, maxRedirects: redirects)
        }
    }

    /// Responds to a Request using TCP client.
    private func plaintextRespond(to req: Request, maxRedirects redirects: Int) throws -> Future<Response> {
        let tcpSocket = try TCPSocket(isNonBlocking: true)
        let tcpClient = try TCPClient(socket: tcpSocket)
        let hostname = try req.http.uri.requireHostname()
        try tcpClient.connect(hostname: hostname, port: req.http.uri.port ?? 80)
        let promise = Promise(Response.self)
        let stream = tcpSocket.stream(on: self.container) { _, error in
            promise.fail(error)
        }
        let client = HTTPClient(
            stream: stream,
            on: self.container
        )
        req.http.headers[.host] = hostname
        return client.send(req.http).flatMap(to: Response.self) { httpRes in
            tcpClient.close()
            
            return try self.response(from: httpRes, for: req, maxRedirects: redirects)
        }
    }
}

/// Configuration option's for the EngineClient.
public struct EngineClientConfig: Service {
    /// The maximum response size to allow for
    /// incoming HTTP responses.
    public var maxResponseHeaderSize: Int
    
    /// The maximum amount of 3xx redirect responses to follow
    ///
    /// Used to prevent infinite redirect loops
    public var maxRedirections: Int

    /// Create a new EngineClientConfig.
    public init() {
        self.maxResponseHeaderSize = 100_000
        self.maxRedirections = 8
    }
}

extension URI {
    /// Returns the URI hostname, throwing if none exists.