Description
Hello,
I need a proxy server endpoint for my Vapor project. The goal is to get the endpoint, which will take a URL as a parameter, get the page of that URL, modify it, and return it to the user. I've searched for an example here and over the internet but had no luck. Can I get the fully working thing I am trying to do with async-http-client? I need to proxy a page with JS, Google authorization, so I need to forward cookies etc.
The only useful thing I have found was the implementation of the proxy for the different Swift serverside framework - Hummingbird. It also uses async-http-client and the author says, that the implementation in Vapor will look similar.
Well, I am not a pro but here is what I have at the moment:
Proxy Middleware:
func respond(to request: Vapor.Request, chainingTo next: Vapor.AsyncResponder) async throws -> Vapor.Response {
// Convert to HTTPClient.Request
let ahcRequest = try await request.ahcRequest(host: target)
// Execute the request using httpClient
let clientResponse = httpClient.execute(request: ahcRequest)
// Convert HTTPClient.Response to Vapor.Response
var vaporResponse = try await clientResponse.get().vaporResponse
return vaporResponse
}
HTTP.Response -> Vapor.Response:
extension HTTPClient.Response {
var vaporResponse: Response {
var headers = HTTPHeaders()
self.headers.forEach { headers.add(name: $0.name, value: $0.value) }
let body: Response.Body
if let buffer = self.body {
body = .init(buffer: buffer)
} else {
body = .empty
}
return Response(
status: .init(statusCode: Int(self.status.code)),
headers: headers,
body: body
)
}
}
Vapor.Request -> async-http-client.Request:
extension Request {
func ahcRequest(host: String) async throws -> HTTPClient.Request {
let collectedBuffer = try await self.body.collect(max: 1024 * 1024).get()
return try HTTPClient.Request(
url: host,
method: self.method,
headers: self.headers,
body: collectedBuffer.map { HTTPClient.Body.byteBuffer($0) }
)
}
}
When I try to proxy the simple webpage with only HTML written - it works. But something more complicated fails.
If you have an example of how I can implement a working proxy for the modern websites, please share it with me.
Thanks.