Skip to content

Instantly share code, notes, and snippets.

@agaoglu
Created October 13, 2014 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agaoglu/e353d6d597af353c916d to your computer and use it in GitHub Desktop.
Save agaoglu/e353d6d597af353c916d to your computer and use it in GitHub Desktop.
import akka.actor.{Actor, ActorRef}
import akka.io.IO
import spray.can.Http
import spray.can.client.ClientConnectionSettings
import spray.http.Uri
import spray.http.HttpHeaders
import spray.http.HttpRequest
import spray.http.HttpResponse
class Proxy(
address: String,
port: Int,
connectTimeout: String,
requestTimeout: String) extends Actor {
val settings = ClientConnectionSettings(s"""
spray.can.client.connecting-timeout = ${connectTimeout}
spray.can.client.request-timeout = ${requestTimeout}""") // Override others if necessary
def receive = {
case httpRequest: HttpRequest =>
import context.system
IO(Http) ! Http.Connect(
host = address,
port = port,
settings = Some(settings))
context.become(connecting(sender, httpRequest))
}
def connecting(client: ActorRef, httpRequest: HttpRequest): Receive = {
case _: Http.Connect => // Connection successful, now dispatch request
val req = HttpRequest(
httpRequest.method,
httpRequest.uri.withAuthority(address, port),
httpRequest.headers.filterNot(_.is("host")),
httpRequest.entity,
httpRequest.protocol)
sender ! req
context.become(replying(sender, client))
case _: Http.CommandFailed => // Connection failed. Timedout, not-resolved, not-reachable etc.
client ! HttpResponse(503)
context.stop(self)
}
def replying(connection: ActorRef, client: ActorRef): Receive = {
case HttpResponse(status, entity, headers, scheme) => // Server responded
// Clean some headers or spray-can will complain
val nheaders = headers.filter{
case _: HttpHeaders.Server => false
case _: HttpHeaders.Date => false
case _: HttpHeaders.`Content-Type` => false
case _: HttpHeaders.`Content-Length` => false
case _ => true
}
client ! HttpResponse(status, entity, nheaders, scheme)
connection ! Http.Close // Close connection regardless of the response
context.stop(self)
case Http.Aborted => // Request timed-out
client ! HttpResponse(504)
connection ! Http.Close
context.stop(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment