Created
December 18, 2012 14:05
-
-
Save anonymous/4328254 to your computer and use it in GitHub Desktop.
A simple echoing client with ssl written on top of spray-io
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package spray.examples | |
import scala.concurrent.duration.Duration | |
import scala.concurrent.duration._ | |
import akka.actor._ | |
import akka.pattern.ask | |
import spray.util._ | |
import spray.io._ | |
import akka.event.LoggingAdapter | |
import akka.util.Timeout | |
import java.nio.ByteBuffer | |
import javax.net.ssl.{X509TrustManager, SSLContext} | |
import java.security.cert.X509Certificate | |
object Main extends App { | |
val myCtx = SSLContext.getInstance("TLS") | |
// a trust manager which trusts everyone without checking | |
object MyTrust extends X509TrustManager { | |
def checkClientTrusted(p1: Array[X509Certificate], p2: String) { | |
println("checkClientTrusted") | |
} | |
def checkServerTrusted(p1: Array[X509Certificate], p2: String) { | |
println("checkClientTrusted") | |
} | |
def getAcceptedIssuers: Array[X509Certificate] = { | |
println("getAcceptedIssuers") | |
Array.empty | |
} | |
} | |
myCtx.init(null, Array(MyTrust), null) | |
implicit val engineProvider = | |
SSLContextProvider.forContext(myCtx) | |
// we need an ActorSystem to host our application in | |
implicit val system = ActorSystem() | |
// create and start an IOBridge | |
val ioBridge = IOExtension(system).ioBridge() | |
// and our actual server "service" actor | |
val client = system.actorOf( | |
Props(new SimpleSSLClient(ioBridge)), | |
name = "simple-ssl-client" | |
) | |
val testActor = system.actorOf(Props(new TestActor(client))) | |
} | |
class TestActor(client: ActorRef) extends Actor with ActorLogging { | |
override def preStart() { | |
client ! IOClient.Connect("localhost", 8888) | |
// shutdown after 10 seconds | |
context.system.scheduler.scheduleOnce(10.seconds) { | |
context.system.shutdown() | |
} | |
} | |
def receive = { | |
case IOClient.Connected(connection) => | |
log.info("Got connected to "+connection) | |
sender ! IOClient.Send(ByteBuffer.wrap("Hello world!".getBytes("ASCII"))) | |
case IOClient.Received(handle, buffer) => | |
val str = new String(buffer.array()) | |
log.info("Got "+str) | |
// return the same buffer | |
sender ! IOClient.Send(buffer) | |
} | |
} | |
class SimpleSSLClient(ioBridge: ActorRef)(implicit sslEngineProvider: ClientSSLEngineProvider) extends IOClient(ioBridge) with ConnectionActors { | |
protected val pipeline: PipelineStage = SimpleSSLClient.pipeline(log) | |
} | |
object SimpleSSLClient { | |
def pipeline(log: LoggingAdapter)(implicit sslEngineProvider: ClientSSLEngineProvider): PipelineStage = | |
FrontendStage() >> | |
SslTlsSupport(sslEngineProvider, log, _ => true /* enable ssl by default */) | |
/** Simple frontend which just captures the sender of the last command and | |
* forwards every event it gets from downstream | |
*/ | |
def FrontendStage(): PipelineStage = | |
new PipelineStage { | |
def build(context: PipelineContext, commandPL: CPL, eventPL: EPL): Pipelines = | |
new Pipelines { | |
var lastSender: ActorRef = _ | |
def commandPipeline: (Command) => Unit = { | |
case x => | |
lastSender = context.sender | |
commandPL(x) | |
} | |
def eventPipeline: (Event) => Unit = { | |
case e => | |
commandPL(IOPeer.Tell(lastSender, e, context.self)) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment