~ubuntu-branches/ubuntu/trusty/tomcat7/trusty-security

« back to all changes in this revision

Viewing changes to java/org/apache/catalina/websocket/MessageInbound.java

  • Committer: Package Import Robot
  • Author(s): tony mancill
  • Date: 2012-06-07 22:43:21 UTC
  • mfrom: (11.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20120607224321-cfev8j681yueyov3
Tags: 7.0.27-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements.  See the NOTICE file distributed with
 
4
 * this work for additional information regarding copyright ownership.
 
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
6
 * (the "License"); you may not use this file except in compliance with
 
7
 * the License.  You may obtain a copy of the License at
 
8
 *
 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
 
10
 *
 
11
 * Unless required by applicable law or agreed to in writing, software
 
12
 * distributed under the License is distributed on an "AS IS" BASIS,
 
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
 * See the License for the specific language governing permissions and
 
15
 * limitations under the License.
 
16
 */
 
17
package org.apache.catalina.websocket;
 
18
 
 
19
import java.io.IOException;
 
20
import java.io.InputStream;
 
21
import java.io.Reader;
 
22
import java.nio.ByteBuffer;
 
23
import java.nio.CharBuffer;
 
24
 
 
25
import org.apache.tomcat.util.res.StringManager;
 
26
 
 
27
/**
 
28
 * Base implementation of the class used to process WebSocket connections based
 
29
 * on messages. Applications should extend this class to provide application
 
30
 * specific functionality. Applications that wish to operate on a stream basis
 
31
 * rather than a message basis should use {@link StreamInbound}.
 
32
 */
 
33
public abstract class MessageInbound extends StreamInbound {
 
34
 
 
35
    private static final StringManager sm =
 
36
            StringManager.getManager(Constants.Package);
 
37
 
 
38
 
 
39
    // 2MB - like maxPostSize
 
40
    private int byteBufferMaxSize = 2097152;
 
41
    private int charBufferMaxSize = 2097152;
 
42
 
 
43
    private ByteBuffer bb = ByteBuffer.allocate(8192);
 
44
    private CharBuffer cb = CharBuffer.allocate(8192);
 
45
 
 
46
 
 
47
    @Override
 
48
    protected final void onBinaryData(InputStream is) throws IOException {
 
49
        int read = 0;
 
50
        while (read > -1) {
 
51
            bb.position(bb.position() + read);
 
52
            if (bb.remaining() == 0) {
 
53
                resizeByteBuffer();
 
54
            }
 
55
            read = is.read(bb.array(), bb.position(), bb.remaining());
 
56
        }
 
57
        bb.flip();
 
58
        onBinaryMessage(bb);
 
59
        bb.clear();
 
60
    }
 
61
 
 
62
 
 
63
    @Override
 
64
    protected final void onTextData(Reader r) throws IOException {
 
65
        int read = 0;
 
66
        while (read > -1) {
 
67
            cb.position(cb.position() + read);
 
68
            if (cb.remaining() == 0) {
 
69
                resizeCharBuffer();
 
70
            }
 
71
            read = r.read(cb.array(), cb.position(), cb.remaining());
 
72
        }
 
73
        cb.flip();
 
74
        onTextMessage(cb);
 
75
        cb.clear();
 
76
    }
 
77
 
 
78
 
 
79
    private void resizeByteBuffer() throws IOException {
 
80
        int maxSize = getByteBufferMaxSize();
 
81
        if (bb.limit() >= maxSize) {
 
82
            throw new IOException(sm.getString("message.bufferTooSmall"));
 
83
        }
 
84
 
 
85
        long newSize = bb.limit() * 2;
 
86
        if (newSize > maxSize) {
 
87
            newSize = maxSize;
 
88
        }
 
89
 
 
90
        // Cast is safe. newSize < maxSize and maxSize is an int
 
91
        ByteBuffer newBuffer = ByteBuffer.allocate((int) newSize);
 
92
        bb.rewind();
 
93
        newBuffer.put(bb);
 
94
        bb = newBuffer;
 
95
    }
 
96
 
 
97
 
 
98
    private void resizeCharBuffer() throws IOException {
 
99
        int maxSize = getCharBufferMaxSize();
 
100
        if (cb.limit() >= maxSize) {
 
101
            throw new IOException(sm.getString("message.bufferTooSmall"));
 
102
        }
 
103
 
 
104
        long newSize = cb.limit() * 2;
 
105
        if (newSize > maxSize) {
 
106
            newSize = maxSize;
 
107
        }
 
108
 
 
109
        // Cast is safe. newSize < maxSize and maxSize is an int
 
110
        CharBuffer newBuffer = CharBuffer.allocate((int) newSize);
 
111
        cb.rewind();
 
112
        newBuffer.put(cb);
 
113
        cb = newBuffer;
 
114
    }
 
115
 
 
116
 
 
117
    /**
 
118
     * Obtain the current maximum size (in bytes) of the buffer used for binary
 
119
     * messages.
 
120
     */
 
121
    public final int getByteBufferMaxSize() {
 
122
        return byteBufferMaxSize;
 
123
    }
 
124
 
 
125
 
 
126
    /**
 
127
     * Set the maximum size (in bytes) of the buffer used for binary messages.
 
128
     */
 
129
    public final void setByteBufferMaxSize(int byteBufferMaxSize) {
 
130
        this.byteBufferMaxSize = byteBufferMaxSize;
 
131
    }
 
132
 
 
133
 
 
134
    /**
 
135
     * Obtain the current maximum size (in characters) of the buffer used for
 
136
     * binary messages.
 
137
     */
 
138
    public final int getCharBufferMaxSize() {
 
139
        return charBufferMaxSize;
 
140
    }
 
141
 
 
142
 
 
143
    /**
 
144
     * Set the maximum size (in characters) of the buffer used for textual
 
145
     * messages.
 
146
     */
 
147
    public final void setCharBufferMaxSize(int charBufferMaxSize) {
 
148
        this.charBufferMaxSize = charBufferMaxSize;
 
149
    }
 
150
 
 
151
 
 
152
    /**
 
153
     * This method is called when there is a binary WebSocket message available
 
154
     * to process. The message is presented via a ByteBuffer and may have been
 
155
     * formed from one or more frames. The number of frames used to transmit the
 
156
     * message is not made visible to the application.
 
157
     *
 
158
     * @param message       The WebSocket message
 
159
     *
 
160
     * @throws IOException  If a problem occurs processing the message. Any
 
161
     *                      exception will trigger the closing of the WebSocket
 
162
     *                      connection.
 
163
     */
 
164
    protected abstract void onBinaryMessage(ByteBuffer message)
 
165
            throws IOException;
 
166
 
 
167
 
 
168
    /**
 
169
     * This method is called when there is a textual WebSocket message available
 
170
     * to process. The message is presented via a CharBuffer and may have been
 
171
     * formed from one or more frames. The number of frames used to transmit the
 
172
     * message is not made visible to the application.
 
173
     *
 
174
     * @param message       The WebSocket message
 
175
     *
 
176
     * @throws IOException  If a problem occurs processing the message. Any
 
177
     *                      exception will trigger the closing of the WebSocket
 
178
     *                      connection.
 
179
     */
 
180
    protected abstract void onTextMessage(CharBuffer message)
 
181
            throws IOException;
 
182
}