Source

miuler-mocksmtp / src / main / scala / com / miuler / mocksmtp / core / MockSMTP.scala

package com.miuler.mocksmtp.core

import io.netty.bootstrap.ServerBootstrap
import org.slf4j.LoggerFactory
import io.netty.channel.socket.nio.{NioServerSocketChannel, NioEventLoopGroup}
import io.netty.channel._
import io.netty.channel.socket.SocketChannel
import io.netty.handler.codec.string.{StringEncoder, StringDecoder}
import io.netty.handler.codec.{DelimiterBasedFrameDecoder, Delimiters}
import java.net.InetAddress
import com.miuler.mocksmtp.gui.QConnectionThreadNetty


class MockSMTP (connectionTheadNetty: QConnectionThreadNetty) {

  private val log = LoggerFactory.getLogger(classOf[MockSMTP])

  var server: ServerBootstrap = _

  def start = {
    log.debug("start server")

    server = new ServerBootstrap()
      .group(new NioEventLoopGroup())
      .channel(classOf[NioServerSocketChannel])
      .localAddress(8080)
      .childHandler(
        new ChannelInitializer[SocketChannel]() {
          def initChannel(ch: SocketChannel) {
            ch.pipeline()
              .addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()(0)))
              .addLast("decoder", new StringDecoder)
              .addLast("encoder", new StringEncoder)
              .addLast("handlerIn", new ChannelInboundHandlerBasic(connectionTheadNetty))
          }
        })
    server.bind().sync()
  }

  def stop = server.shutdown()

}

object LoadingData extends Enumeration {
  val INACTIVE, LOADING, FINALIZED = Value
}

import LoadingData._

class ChannelInboundHandlerBasic(connectionTheadNetty: QConnectionThreadNetty) extends ChannelInboundMessageHandlerAdapter[String] {

  private val log = LoggerFactory.getLogger(classOf[MockSMTP])
  private var loadingData = INACTIVE
  private var email:String = _

  override def channelActive(ctx: ChannelHandlerContext) {
    log.debug("channelActive")
    ctx.write("220 ***************************************\n")
    //ctx.fireChannelActive(); //TODO: I do not know if this is necessary
  }

  override def messageReceived(ctx: ChannelHandlerContext, msg: String) {
    log.debug("mensage: {}", msg)
    log.debug("loadingData: {}", loadingData)

    var outmsg = ""

    msg.toUpperCase match {
      case _msg:String if _msg.trim matches "HELO|EHLO" => outmsg = "501 Syntax: " + _msg + " hostname\n"
      case _msg:String if _msg matches "(HELO|EHLO) .+" => outmsg = "250 " + InetAddress.getLocalHost.getHostName  + "\n"
      case _msg:String if _msg matches "MAIL FROM:.+" => outmsg = "250 Ok\n"
      case _msg:String if _msg matches "RCPT TO:.+" => outmsg = "250 Ok\n"
      case _msg:String if _msg matches "DATA.*" => {
        outmsg = "354 End data with <CR><LF>.<CR><LF>\n"
        loadingData = LOADING
      }
      case _msg:String if _msg == "." => {
        outmsg = "250 Ok\n"
        log.debug("Enviando el correo al GUI")
        connectionTheadNetty.msg = email
        connectionTheadNetty.mutex.unlock
        loadingData = INACTIVE
        email = ""
      }
      case _msg:String if _msg == "QUIT" => {outmsg = "221 Bye\n"
        log.debug("respuesta: {}", outmsg)
        ctx.write(outmsg).addListener(ChannelFutureListener.CLOSE)
        return
      }
      case _ => {
        log.debug("No es un comando")
        if (loadingData==LOADING) email += msg + "\n"
      }
    }

    ctx.write(outmsg)
    log.debug("respuesta: {}", outmsg)
  }

  override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
    log.error("error", cause)
    ctx.close()
  }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.