Skip to content

Package: ThriftFrameFilter

ThriftFrameFilter

nameinstructionbranchcomplexitylinemethod
ThriftFrameFilter()
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
ThriftFrameFilter(int)
M: 18 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
handleRead(FilterChainContext)
M: 110 C: 0
0%
M: 16 C: 0
0%
M: 9 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
handleWrite(FilterChainContext)
M: 50 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2011, 2017 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.glassfish.grizzly.thrift;
18:
19: import java.io.IOException;
20:
21: import org.glassfish.grizzly.Buffer;
22: import org.glassfish.grizzly.Connection;
23: import org.glassfish.grizzly.Grizzly;
24: import org.glassfish.grizzly.attributes.Attribute;
25: import org.glassfish.grizzly.filterchain.BaseFilter;
26: import org.glassfish.grizzly.filterchain.FilterChainContext;
27: import org.glassfish.grizzly.filterchain.NextAction;
28: import org.glassfish.grizzly.memory.Buffers;
29: import org.glassfish.grizzly.memory.MemoryManager;
30:
31: /**
32: * ThriftFrameFilter supports TFramedTranport that ensures a fully read message
33: * by preceding messages with a 4-byte frame size.
34: * <p>
35: * If the frame size exceeds the max size which you can set by constructor's
36: * parameter, exception will be thrown.
37: *
38: * @author Bongjae Chang
39: */
40: public class ThriftFrameFilter extends BaseFilter {
41:
42: private static final int THRIFT_FRAME_HEADER_LENGTH = 4;
43: private static final int DEFAULT_DEFAULT_MAX_THRIFT_FRAME_LENGTH = 512 * 1024;
44: private final int maxFrameLength;
45:
46: private final Attribute<Integer> lengthAttribute = Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute("ThriftFilter.FrameSize");
47:
48: public ThriftFrameFilter() {
49: this(DEFAULT_DEFAULT_MAX_THRIFT_FRAME_LENGTH);
50: }
51:
52: public ThriftFrameFilter(final int maxFrameLength) {
53:• if (maxFrameLength < DEFAULT_DEFAULT_MAX_THRIFT_FRAME_LENGTH) {
54: this.maxFrameLength = DEFAULT_DEFAULT_MAX_THRIFT_FRAME_LENGTH;
55: } else {
56: this.maxFrameLength = maxFrameLength;
57: }
58: }
59:
60: @Override
61: public NextAction handleRead(FilterChainContext ctx) throws IOException {
62: final Buffer input = ctx.getMessage();
63:• if (input == null) {
64: throw new IOException("input message could not be null");
65: }
66:• if (!input.hasRemaining()) {
67: return ctx.getStopAction();
68: }
69: final Connection connection = ctx.getConnection();
70:• if (connection == null) {
71: throw new IOException("connection could not be null");
72: }
73:
74: Integer frameLength = lengthAttribute.get(connection);
75:• if (frameLength == null) {
76:• if (input.remaining() < THRIFT_FRAME_HEADER_LENGTH) {
77: return ctx.getStopAction(input);
78: }
79: frameLength = input.getInt();
80:• if (frameLength > maxFrameLength) {
81: throw new IOException("current frame length(" + frameLength + ") exceeds the max frame length(" + maxFrameLength + ")");
82: }
83: lengthAttribute.set(connection, frameLength);
84: }
85:
86: final int inputBufferLength = input.remaining();
87:• if (inputBufferLength < frameLength) {
88: return ctx.getStopAction(input);
89: }
90: lengthAttribute.remove(connection);
91:
92: // Check if the input buffer has more than 1 complete thrift message
93: // If yes - split up the first message and the remainder
94:• final Buffer remainder = inputBufferLength > frameLength ? input.split(frameLength) : null;
95: ctx.setMessage(input);
96:
97: // Instruct FilterChain to store the remainder (if any) and continue execution
98: return ctx.getInvokeAction(remainder);
99: }
100:
101: @Override
102: public NextAction handleWrite(FilterChainContext ctx) throws IOException {
103: final Buffer body = ctx.getMessage();
104:• if (body == null) {
105: throw new IOException("Input message could not be null");
106: }
107:• if (!body.hasRemaining()) {
108: return ctx.getStopAction();
109: }
110:
111: final MemoryManager memoryManager = ctx.getMemoryManager();
112:
113: final int frameLength = body.remaining();
114: final Buffer header = memoryManager.allocate(THRIFT_FRAME_HEADER_LENGTH);
115: header.allowBufferDispose(true);
116: header.putInt(frameLength);
117: header.trim();
118:
119: final Buffer resultBuffer = Buffers.appendBuffers(memoryManager, header, body);
120: resultBuffer.allowBufferDispose(true);
121: ctx.setMessage(resultBuffer);
122: return ctx.getInvokeAction();
123: }
124: }