Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2014 Netflix, Inc.
*
* Licensed 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 io.reactivex.netty.protocol.http.sse;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.ByteProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.util.List;
/**
* A decoder to decode Server sent events into {@link ServerSentEvent}
*/
public class ServerSentEventDecoder extends ByteToMessageDecoder {
private static final Logger logger = LoggerFactory.getLogger(ServerSentEventDecoder.class);
public static final int DEFAULT_MAX_FIELD_LENGTH = 100;
private static final char[] EVENT_ID_FIELD_NAME = "event".toCharArray();
private static final char[] DATA_FIELD_NAME = "data".toCharArray();
private static final char[] ID_FIELD_NAME = "id".toCharArray();
protected static final ByteProcessor SKIP_TILL_LINE_DELIMITER_PROCESSOR = new ByteProcessor() {
@Override
public boolean process(byte value) throws Exception {
return !isLineDelimiter((char) value);
}
};
protected static final ByteProcessor SKIP_LINE_DELIMITERS_AND_SPACES_PROCESSOR = new ByteProcessor() {
@Override
public boolean process(byte value) throws Exception {
return isLineDelimiter((char) value) || (char) value == ' ';
}
};
protected static final ByteProcessor SKIP_COLON_AND_WHITE_SPACE_PROCESSOR = new ByteProcessor() {
@Override
public boolean process(byte value) throws Exception {
char valueChar = (char) value;
return valueChar == ':' || valueChar == ' ';
}
};
protected static final ByteProcessor SCAN_COLON_PROCESSOR = new ByteProcessor() {
@Override
public boolean process(byte value) throws Exception {
return (char) value != ':';
}
};
protected static final ByteProcessor SCAN_EOL_PROCESSOR = new ByteProcessor() {
@Override
public boolean process(byte value) throws Exception {
return !isLineDelimiter((char) value);
}
};
private static Charset sseEncodingCharset;
static {
try {
sseEncodingCharset = Charset.forName("UTF-8");
} catch (Exception e) {
logger.error("UTF-8 charset not available. Since SSE only contains UTF-8 data, we can not read SSE data.");
sseEncodingCharset = null;
}
}
private enum State {
SkipColonAndWhiteSpaces,// Skip colon and all whitespaces after reading field name.
SkipLineDelimitersAndSpaces,// Skip all line delimiters after field value end.
DiscardTillEOL,// On recieving an illegal/unidentified field, ignore everything till EOL.
ReadFieldName, // Read till a colon to get the name of the field.
ReadFieldValue // Read value till the line delimiter.
}
/**
* Release of these buffers happens in the following ways:
*
* 1) If this was a data buffer, it is released when ServerSentEvent is released.
* 2) If this was an eventId buffer, it is released when next Id arrives or when the connection
* is closed.
* 3) If this was an eventType buffer, it is released when next type arrives or when the connection
* is closed.
*/
private ByteBuf lastEventId;
private ByteBuf lastEventType;
private ByteBuf incompleteData; // Can be field value of name, according to the current state.
private ServerSentEvent.Type currentFieldType;
private State state = State.ReadFieldName;
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List