@Test public void testDecodingFileWithBufferedSessionData() throws Exception { final ReadableByteChannel channel = new ReadableByteChannelMock( new String[] {"stuff; ", "more stuff; ", "a lot more stuff!"}, Consts.ASCII); final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII); final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl(); final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics); final int i = inbuf.fill(channel); Assert.assertEquals(7, i); createTempFile(); final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw"); try { final FileChannel fchannel = testfile.getChannel(); long pos = 0; while (!decoder.isCompleted()) { final long bytesRead = decoder.transfer(fchannel, pos, 10); if (bytesRead > 0) { pos += bytesRead; } } // count everything except the initial 7 bytes that went to the session buffer Assert.assertEquals(testfile.length() - 7, metrics.getBytesTransferred()); } finally { testfile.close(); } Assert.assertEquals( "stuff; more stuff; a lot more stuff!", CodecTestUtils.readFromFile(this.tmpfile)); }
@Test public void testDecodingFromSessionBuffer() throws Exception { final ReadableByteChannel channel = new ReadableByteChannelMock(new String[] {"stuff;", "more stuff"}, Consts.ASCII); final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, Consts.ASCII); final HttpTransportMetricsImpl metrics = new HttpTransportMetricsImpl(); inbuf.fill(channel); Assert.assertEquals(6, inbuf.length()); final IdentityDecoder decoder = new IdentityDecoder(channel, inbuf, metrics); final ByteBuffer dst = ByteBuffer.allocate(1024); int bytesRead = decoder.read(dst); Assert.assertEquals(6, bytesRead); Assert.assertEquals("stuff;", CodecTestUtils.convert(dst)); Assert.assertFalse(decoder.isCompleted()); Assert.assertEquals(0, metrics.getBytesTransferred()); // doesn't count if from session buffer dst.clear(); bytesRead = decoder.read(dst); Assert.assertEquals(10, bytesRead); Assert.assertEquals("more stuff", CodecTestUtils.convert(dst)); Assert.assertFalse(decoder.isCompleted()); Assert.assertEquals(10, metrics.getBytesTransferred()); dst.clear(); bytesRead = decoder.read(dst); Assert.assertEquals(-1, bytesRead); Assert.assertTrue(decoder.isCompleted()); Assert.assertEquals(10, metrics.getBytesTransferred()); dst.clear(); bytesRead = decoder.read(dst); Assert.assertEquals(-1, bytesRead); Assert.assertTrue(decoder.isCompleted()); Assert.assertEquals(10, metrics.getBytesTransferred()); }
@Override public void consumeData(final IOSession iosession, final ServerState sessionState) throws IOException, SMTPProtocolException { Args.notNull(iosession, "IO session"); Args.notNull(sessionState, "Session state"); SessionInputBuffer buf = this.iobuffers.getInbuf(); synchronized (sessionState) { for (; ; ) { int bytesRead = buf.fill(iosession.channel()); try { SMTPCommand command = this.parser.parse(buf, bytesRead == -1); if (command == null) { if (bytesRead == -1 && !sessionState.isTerminated() && this.pendingActions.isEmpty()) { throw new UnexpectedEndOfStreamException(); } else { break; } } Action<ServerState> action = this.commandHandler.handle(command); this.pendingActions.add(action); } catch (SMTPErrorException ex) { SMTPReply reply = new SMTPReply(ex.getCode(), ex.getEnhancedCode(), ex.getMessage()); this.pendingActions.add(new SimpleAction(reply)); } catch (SMTPProtocolException ex) { SMTPReply reply = new SMTPReply( SMTPCodes.ERR_PERM_SYNTAX_ERR_COMMAND, new SMTPCode(5, 3, 0), ex.getMessage()); this.pendingActions.add(new SimpleAction(reply)); } } if (!this.pendingActions.isEmpty()) { iosession.setEvent(SelectionKey.OP_WRITE); } } }
@Override public void consumeData(final IOSession iosession, final ClientState sessionState) throws IOException, SMTPProtocolException { Args.notNull(iosession, "IO session"); Args.notNull(sessionState, "Session state"); SessionInputBuffer buf = this.iobuffers.getInbuf(); int bytesRead = buf.fill(iosession.channel()); SMTPReply reply = this.parser.parse(buf, bytesRead == -1); if (reply != null) { switch (this.codecState) { case SERVICE_READY_EXPECTED: if (reply.getCode() == SMTPCodes.SERVICE_READY) { this.codecState = CodecState.EHLO_READY; iosession.setEvent(SelectionKey.OP_WRITE); } else { this.codecState = CodecState.COMPLETED; sessionState.setReply(reply); } break; case EHLO_RESPONSE_EXPECTED: if (reply.getCode() == SMTPCodes.OK) { Set<String> extensions = sessionState.getExtensions(); List<String> lines = reply.getLines(); if (lines.size() > 1) { for (int i = 1; i < lines.size(); i++) { String line = lines.get(i); extensions.add(line.toUpperCase(Locale.US)); } } this.codecState = CodecState.COMPLETED; sessionState.setReply(reply); } else if (reply.getCode() == SMTPCodes.ERR_PERM_SYNTAX_ERR_COMMAND) { this.codecState = CodecState.HELO_READY; iosession.setEvent(SelectionKey.OP_WRITE); } else { this.codecState = CodecState.COMPLETED; sessionState.setReply(reply); } break; case HELO_RESPONSE_EXPECTED: this.codecState = CodecState.COMPLETED; sessionState.setReply(reply); break; default: if (reply.getCode() == SMTPCodes.ERR_TRANS_SERVICE_NOT_AVAILABLE) { sessionState.setReply(reply); this.codecState = CodecState.COMPLETED; } else { throw new SMTPProtocolException("Unexpected reply: " + reply); } } } else { if (bytesRead == -1 && !sessionState.isTerminated()) { throw new UnexpectedEndOfStreamException(); } } }