Source

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

Full commit
Hector Miuler Ma… f8f9ed6 


Hector Miuler Ma… 3b747d5 
Hector Miuler Ma… 01dcce9 
Hector Miuler Ma… f659358 
Hector Miuler Ma… 01dcce9 
Hector Miuler Ma… dad6c46 

Hector Miuler Ma… 2bf3561 
Hector Miuler Ma… cca6cd9 
Hector Miuler Ma… f8f9ed6 
Hector Miuler Ma… 2bf3561 
Hector Miuler Ma… cca6cd9 
Hector Miuler Ma… f8f9ed6 
Hector Miuler Ma… 3b747d5 
Hector Miuler Ma… f8f9ed6 
Hector Miuler Ma… 01dcce9 
Hector Miuler Ma… f8f9ed6 
Hector Miuler Ma… 01dcce9 
Hector Miuler Ma… 2bf3561 
Hector Miuler Ma… dad6c46 
Hector Miuler Ma… 01dcce9 






Hector Miuler Ma… f659358 
Hector Miuler Ma… dad6c46 
Hector Miuler Ma… cca6cd9 


Hector Miuler Ma… 01dcce9 

Hector Miuler Ma… 0de00ed 
Hector Miuler Ma… 01dcce9 
Hector Miuler Ma… 3b747d5 

Hector Miuler Ma… f8f9ed6 

Hector Miuler Ma… 2bf3561 
Hector Miuler Ma… 5607bf5 




Hector Miuler Ma… 2bf3561 
Hector Miuler Ma… cca6cd9 
Hector Miuler Ma… 2bf3561 

Hector Miuler Ma… 5607bf5 

Hector Miuler Ma… 2bf3561 


Hector Miuler Ma… dad6c46 
Hector Miuler Ma… 2bf3561 


Hector Miuler Ma… dad6c46 
Hector Miuler Ma… 5607bf5 


Hector Miuler Ma… f16cdbd 
Hector Miuler Ma… dad6c46 
Hector Miuler Ma… f16cdbd 




Hector Miuler Ma… 5607bf5 











Hector Miuler Ma… f16cdbd 


Hector Miuler Ma… 5607bf5 



Hector Miuler Ma… 27ad751 
Hector Miuler Ma… 5607bf5 
Hector Miuler Ma… dad6c46 
Hector Miuler Ma… f16cdbd 


Hector Miuler Ma… dad6c46 




Hector Miuler Ma… 2bf3561 


Hector Miuler Ma… cca6cd9 



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()
  }
}