org.graylog2.inputs.transports.netty.LenientLineBasedFrameDecoder Maven / Gradle / Ivy
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* .
*/
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.graylog2.inputs.transports.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.TooLongFrameException;
import io.netty.util.ByteProcessor;
import java.util.List;
/**
* A decoder that splits the received {@link ByteBuf}s on line endings.
*
* Both {@code "\n"} and {@code "\r\n"} are handled.
* For a more general delimiter-based decoder, see {@link DelimiterBasedFrameDecoder}.
*/
public class LenientLineBasedFrameDecoder extends ByteToMessageDecoder {
/**
* Maximum length of a frame we're willing to decode.
*/
private final int maxLength;
/**
* Whether or not to throw an exception as soon as we exceed maxLength.
*/
private final boolean failFast;
private final boolean stripDelimiter;
private final boolean emitLastLineWithoutDelimiter;
/**
* True if we're discarding input because we're already over maxLength.
*/
private boolean discarding;
private int discardedBytes;
/**
* Last scan position.
*/
private int offset;
/**
* Creates a new decoder.
*
* @param maxLength the maximum length of the decoded frame.
* A {@link TooLongFrameException} is thrown if
* the length of the frame exceeds this value.
*/
public LenientLineBasedFrameDecoder(final int maxLength) {
this(maxLength, true, false, true);
}
/**
* Creates a new decoder.
*
* @param maxLength the maximum length of the decoded frame.
* A {@link TooLongFrameException} is thrown if
* the length of the frame exceeds this value.
* @param stripDelimiter whether the decoded frame should strip out the
* delimiter or not
* @param failFast If true, a {@link TooLongFrameException} is
* thrown as soon as the decoder notices the length of the
* frame will exceed maxFrameLength regardless of
* whether the entire frame has been read.
* If false, a {@link TooLongFrameException} is
* thrown after the entire frame that exceeds
* maxFrameLength has been read.
* @param emitLastLineWithoutDelimiter emit the last line even if it doesn't
* end with the delimiter
*/
public LenientLineBasedFrameDecoder(final int maxLength, final boolean stripDelimiter, final boolean failFast,
final boolean emitLastLineWithoutDelimiter) {
this.maxLength = maxLength;
this.failFast = failFast;
this.stripDelimiter = stripDelimiter;
this.emitLastLineWithoutDelimiter = emitLastLineWithoutDelimiter;
}
@Override
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List