1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.rtsp;
17
18 import java.util.regex.Pattern;
19
20 import io.netty.buffer.Unpooled;
21 import io.netty.handler.codec.http.DefaultFullHttpRequest;
22 import io.netty.handler.codec.http.DefaultFullHttpResponse;
23 import io.netty.handler.codec.http.DefaultHttpRequest;
24 import io.netty.handler.codec.http.DefaultHttpResponse;
25 import io.netty.handler.codec.http.HttpDecoderConfig;
26 import io.netty.handler.codec.http.HttpMessage;
27 import io.netty.handler.codec.http.HttpObjectDecoder;
28 import io.netty.handler.codec.http.HttpResponseStatus;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class RtspDecoder extends HttpObjectDecoder {
60
61
62
63 private static final HttpResponseStatus UNKNOWN_STATUS =
64 new HttpResponseStatus(999, "Unknown");
65
66
67
68
69 private boolean isDecodingRequest;
70
71
72
73
74 private static final Pattern versionPattern = Pattern.compile("RTSP/\\d\\.\\d");
75
76
77
78
79 public static final int DEFAULT_MAX_CONTENT_LENGTH = 8192;
80
81
82
83
84
85
86 public RtspDecoder() {
87 this(DEFAULT_MAX_INITIAL_LINE_LENGTH,
88 DEFAULT_MAX_HEADER_SIZE,
89 DEFAULT_MAX_CONTENT_LENGTH);
90 }
91
92
93
94
95
96
97
98 public RtspDecoder(final int maxInitialLineLength,
99 final int maxHeaderSize,
100 final int maxContentLength) {
101 super(new HttpDecoderConfig()
102 .setMaxInitialLineLength(maxInitialLineLength)
103 .setMaxHeaderSize(maxHeaderSize)
104 .setMaxChunkSize(maxContentLength * 2)
105 .setChunkedSupported(false));
106 }
107
108
109
110
111
112
113
114
115
116
117 @Deprecated
118 public RtspDecoder(final int maxInitialLineLength,
119 final int maxHeaderSize,
120 final int maxContentLength,
121 final boolean validateHeaders) {
122 super(new HttpDecoderConfig()
123 .setMaxInitialLineLength(maxInitialLineLength)
124 .setMaxHeaderSize(maxHeaderSize)
125 .setMaxChunkSize(maxContentLength * 2)
126 .setChunkedSupported(false)
127 .setValidateHeaders(validateHeaders));
128 }
129
130
131
132
133 public RtspDecoder(HttpDecoderConfig config) {
134 super(config.clone()
135 .setMaxChunkSize(2 * config.getMaxChunkSize())
136 .setChunkedSupported(false));
137 }
138
139 @Override
140 protected HttpMessage createMessage(final String[] initialLine)
141 throws Exception {
142
143
144 if (versionPattern.matcher(initialLine[0]).matches()) {
145 isDecodingRequest = false;
146 return new DefaultHttpResponse(RtspVersions.valueOf(initialLine[0]),
147 new HttpResponseStatus(Integer.parseInt(initialLine[1]),
148 initialLine[2]),
149 headersFactory);
150 } else {
151 isDecodingRequest = true;
152 return new DefaultHttpRequest(RtspVersions.valueOf(initialLine[2]),
153 RtspMethods.valueOf(initialLine[0]),
154 initialLine[1],
155 headersFactory);
156 }
157 }
158
159 @Override
160 protected boolean isContentAlwaysEmpty(final HttpMessage msg) {
161
162
163 return super.isContentAlwaysEmpty(msg) || !msg.headers().contains(RtspHeaderNames.CONTENT_LENGTH);
164 }
165
166 @Override
167 protected HttpMessage createInvalidMessage() {
168 if (isDecodingRequest) {
169 return new DefaultFullHttpRequest(RtspVersions.RTSP_1_0,
170 RtspMethods.OPTIONS, "/bad-request", Unpooled.buffer(0), headersFactory, trailersFactory);
171 } else {
172 return new DefaultFullHttpResponse(
173 RtspVersions.RTSP_1_0, UNKNOWN_STATUS, Unpooled.buffer(0), headersFactory, trailersFactory);
174 }
175 }
176
177 @Override
178 protected boolean isDecodingRequest() {
179 return isDecodingRequest;
180 }
181 }