nightcode/jmilter

Error while trying to use sample: AddHeaderMilterHandler

Closed this issue · 1 comments

Hi thanks for the lib, wanted to try the example code with postfix and got an error.

java main(): (kotlin) Java 17

// indicates what changes you intend to do with messages
        val milterActions: Actions = Actions.builder()
            .addHeader()
            .build()

        // indicates which steps you want to skip
        val milterProtocolSteps = ProtocolSteps.builder()
            .noHelo()
            .noData()
            .noBody()
            .build()
        // gateway address

        // gateway address

        val serverFactory = ServerFactory.tcpIpFactory(InetSocketAddress(7799))

        // a simple milter handler that only adds header "X-Received"
        val milterHandler: MilterHandler = AddHeaderMilterHandler(milterActions, milterProtocolSteps)

        val gatewayManager = MilterGatewayManager(serverFactory, milterHandler)

        gatewayManager.bind()

copied the from AddHeaderMilterHandler this repo


class AddHeaderMilterHandler internal constructor(milterActions: Actions?, milterProtocolSteps: ProtocolSteps?) :
    AbstractMilterHandler(milterActions, milterProtocolSteps) {
    @Throws(MilterException::class)
    override fun connect(context: MilterContext, hostname: String, family: Int, port: Int, address: SocketAddress?) {
        Log.debug().log(
            javaClass,
            String.format("<CONNECT> hostname: %s, family: %s, port: %s, address: %s", hostname, family, port, address)
        )
        super.connect(context, hostname, family, port, address)
    }

    @Throws(MilterException::class)
    override fun helo(context: MilterContext, helohost: String) {
        Log.debug().log(javaClass, "<HELO> helohost: $helohost")
        super.helo(context, helohost)
    }

    @Throws(MilterException::class)
    override fun envfrom(context: MilterContext, from: List<String>) {
        Log.debug().log(javaClass, "<ENVFROM> from: $from")
        super.envfrom(context, from)
    }

    @Throws(MilterException::class)
    override fun envrcpt(context: MilterContext, recipients: List<String>) {
        Log.debug().log(javaClass, "<ENVRCPT> recipients: $recipients")
        super.envrcpt(context, recipients)
    }

    @Throws(MilterException::class)
    override fun header(context: MilterContext, headerName: String, headerValue: String) {
        Log.debug().log(javaClass, String.format("<HEADER> headerName: %s, headerValue: %s", headerName, headerValue))
        super.header(context, headerName, headerValue)
    }

    @Throws(MilterException::class)
    override fun eoh(context: MilterContext) {
        Log.debug().log(javaClass, "<EOH>")
        super.eoh(context)
    }

    @Throws(MilterException::class)
    override fun body(context: MilterContext, bodyChunk: String) {
        Log.debug().log(javaClass, "<BODY> bodyChunk: $bodyChunk")
        super.body(context, bodyChunk)
    }

    @Throws(MilterException::class)
    override fun eob(context: MilterContext, bodyChunk: String?) {
        Log.debug().log(javaClass, "<EOB> bodyChunk: $bodyChunk")
        messageModificationService.addHeader(context, "X-Received", "Tue, 31 Oct 2018 17:56:00 -0700 (PDT)")
        super.eob(context, bodyChunk)
    }

    @Throws(MilterException::class)
    override fun abort(context: MilterContext, packet: MilterPacket?) {
        Log.debug().log(javaClass, "<ABORT> abort: $packet")
        super.abort(context, packet)
    }

    override fun quit(context: MilterContext) {
        Log.debug().log(javaClass, "<QUIT>")
    }

    override fun quitNc(context: MilterContext) {
        Log.debug().log(javaClass, "<QUIT_NC>")
    }

    @Throws(MilterException::class)
    override fun data(context: MilterContext, payload: ByteArray) {
        Log.debug().log(javaClass, "<DATA>")
        super.data(context, payload)
    }

    @Throws(MilterException::class)
    override fun optneg(
        context: MilterContext, mtaProtocolVersion: Int, mtaActions: Actions,
        mtaProtocolSteps: ProtocolSteps
    ) {
        Log.debug()
            .log(javaClass, String.format("<NEGOTIATE> %s, %s, %s", mtaProtocolVersion, mtaActions, mtaProtocolSteps))
        super.optneg(context, mtaProtocolVersion, mtaActions, mtaProtocolSteps)
    }

    @Throws(MilterException::class)
    override fun unknown(context: MilterContext, payload: ByteArray) {
        Log.debug().log(
            javaClass,
            String.format("<UNKNOWN> unknown: %s", if (payload.size > 0) HEX.fromByteArray(payload) else "NULL")
        )
        super.unknown(context, payload)
    }

    companion object {
        private val HEX = Hexs.hex()
    }
}

postfix/main.conf

milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:vs-smtp-milter-service-1:7799
non_smtpd_milters = inet:vs-smtp-milter-service-1:7799

// Error

2022-10-19T22:32:15.621438827 [Thread-1/TcpIpServerFactory]: unable to initialize netty EPOLL transport, switch to NIO: io.netty.channel.epoll.EpollEventLoopGroup
2022-10-19T22:32:26.796323676 [jmilter-0.0.0.0/0.0.0.0:7799-worker-nio-thread-1/AddHeaderMilterHandler]: <NEGOTIATE> 6, Actions: 000001FF, ProtocolSteps: 001FFFFF
2022-10-19T22:32:26.796599737 [jmilter-0.0.0.0/0.0.0.0:7799-worker-nio-thread-1/AddHeaderMilterHandler]: protocol negotiation
	MTA    { Version: 6 Actions: 000001FF ProtocolSteps: 001FFFFF}
	Milter { Version: 6 Actions: 00000001 ProtocolSteps: 00000212}
2022-10-19T22:32:26.800835170 [jmilter-0.0.0.0/0.0.0.0:7799-worker-nio-thread-1/AddHeaderMilterHandler]: <CONNECT> hostname: vs-smtp-submission-entrypoint-proxy-1.vn-mailsetup-1, family: 52, port: 54166, address: /172.25.1.144:54166
2022-10-19T22:32:26.802433546 [jmilter-0.0.0.0/0.0.0.0:7799-worker-nio-thread-1/AddHeaderMilterHandler]: <ABORT> abort: MilterPacket{command=0x41 'A', payload=EMPTY}
2022-10-19T22:32:26.802706812 [jmilter-0.0.0.0/0.0.0.0:7799-worker-nio-thread-1/AddHeaderMilterHandler]: <QUIT>
2022-10-19 22:32:26.819  WARN 1 --- [er-nio-thread-2] io.netty.channel.ChannelInitializer      : Failed to initialize a channel. Closing: [id: 0xdcf6c4d5, L:/172.25.1.161:7799 - R:/172.25.1.151:41872]
io.netty.channel.ChannelPipelineException: org.nightcode.milter.net.MilterChannelHandler is not a @Sharable handler, so can't be added or removed multiple times.
	at io.netty.channel.DefaultChannelPipeline.checkMultiplicity(DefaultChannelPipeline.java:600) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:202) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:195) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at org.nightcode.milter.net.SessionInitializer.initChannel(SessionInitializer.java:63) ~[jmilter-0.4.1.jar!/:na]
	at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:129) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:112) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:938) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:609) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline.access$100(DefaultChannelPipeline.java:46) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1463) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1115) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:650) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:514) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:429) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:486) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.82.Final.jar!/:4.1.82.Final]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.82.Final.jar!/:4.1.82.Final]
	at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]

Thanks for your bug report!