View | Details | Raw Unified | Return to bug 51181
Collapse All | Expand All

(-)java/org/apache/catalina/websocket/StreamInbound.java (-6 / +42 lines)
Lines 20-25 Link Here
20
import java.io.InputStream;
20
import java.io.InputStream;
21
import java.io.InputStreamReader;
21
import java.io.InputStreamReader;
22
import java.io.Reader;
22
import java.io.Reader;
23
import java.nio.ByteBuffer;
23
import java.nio.charset.MalformedInputException;
24
import java.nio.charset.MalformedInputException;
24
import java.nio.charset.UnmappableCharacterException;
25
import java.nio.charset.UnmappableCharacterException;
25
26
Lines 83-88 Link Here
83
    public final void setUpgradeOutbound(UpgradeOutbound upgradeOutbound) {
84
    public final void setUpgradeOutbound(UpgradeOutbound upgradeOutbound) {
84
        outbound = new WsOutbound(upgradeOutbound, outboundByteBufferSize,
85
        outbound = new WsOutbound(upgradeOutbound, outboundByteBufferSize,
85
                outboundCharBufferSize);
86
                outboundCharBufferSize);
87
        onOpen(outbound);
86
    }
88
    }
87
89
88
90
Lines 113-119 Link Here
113
            try {
115
            try {
114
                // TODO User defined extensions may define values for rsv
116
                // TODO User defined extensions may define values for rsv
115
                if (frame.getRsv() > 0) {
117
                if (frame.getRsv() > 0) {
116
                    getWsOutbound().close(
118
                    closeOutboundConnection(
117
                            Constants.STATUS_PROTOCOL_ERROR, null);
119
                            Constants.STATUS_PROTOCOL_ERROR, null);
118
                    return SocketState.CLOSED;
120
                    return SocketState.CLOSED;
119
                }
121
                }
Lines 127-133 Link Here
127
                            new InputStreamReader(wsIs, new Utf8Decoder());
129
                            new InputStreamReader(wsIs, new Utf8Decoder());
128
                    onTextData(r);
130
                    onTextData(r);
129
                } else if (opCode == Constants.OPCODE_CLOSE){
131
                } else if (opCode == Constants.OPCODE_CLOSE){
130
                    getWsOutbound().close(frame);
132
                    closeOutboundConnection(frame);
131
                    return SocketState.CLOSED;
133
                    return SocketState.CLOSED;
132
                } else if (opCode == Constants.OPCODE_PING) {
134
                } else if (opCode == Constants.OPCODE_PING) {
133
                    getWsOutbound().pong(frame.getPayLoad());
135
                    getWsOutbound().pong(frame.getPayLoad());
Lines 135-161 Link Here
135
                    // NO-OP
137
                    // NO-OP
136
                } else {
138
                } else {
137
                    // Unknown OpCode
139
                    // Unknown OpCode
138
                    getWsOutbound().close(
140
                    closeOutboundConnection(
139
                            Constants.STATUS_PROTOCOL_ERROR, null);
141
                            Constants.STATUS_PROTOCOL_ERROR, null);
140
                    return SocketState.CLOSED;
142
                    return SocketState.CLOSED;
141
                }
143
                }
142
            } catch (MalformedInputException mie) {
144
            } catch (MalformedInputException mie) {
143
                // Invalid UTF-8
145
                // Invalid UTF-8
144
                getWsOutbound().close(Constants.STATUS_BAD_DATA, null);
146
                closeOutboundConnection(Constants.STATUS_BAD_DATA, null);
145
                return SocketState.CLOSED;
147
                return SocketState.CLOSED;
146
            } catch (UnmappableCharacterException uce) {
148
            } catch (UnmappableCharacterException uce) {
147
                // Invalid UTF-8
149
                // Invalid UTF-8
148
                getWsOutbound().close(Constants.STATUS_BAD_DATA, null);
150
                closeOutboundConnection(Constants.STATUS_BAD_DATA, null);
149
                return SocketState.CLOSED;
151
                return SocketState.CLOSED;
150
            } catch (IOException ioe) {
152
            } catch (IOException ioe) {
151
                // Given something must have gone to reach this point, this
153
                // Given something must have gone to reach this point, this
152
                // might not work but try it anyway.
154
                // might not work but try it anyway.
153
                getWsOutbound().close(Constants.STATUS_PROTOCOL_ERROR, null);
155
                closeOutboundConnection(Constants.STATUS_PROTOCOL_ERROR, null);
154
                return SocketState.CLOSED;
156
                return SocketState.CLOSED;
155
            }
157
            }
156
            frame = wsIs.nextFrame(false);
158
            frame = wsIs.nextFrame(false);
157
        }
159
        }
158
        return SocketState.UPGRADED;
160
        return SocketState.UPGRADED;
161
    }
162
163
    private void closeOutboundConnection(int status, ByteBuffer data) throws IOException {
164
        try {
165
            getWsOutbound().close(status, data);
166
        } finally {
167
            onClose(status);
168
        }
169
    }
170
171
    private void closeOutboundConnection(WsFrame frame) throws IOException {
172
        try {
173
            getWsOutbound().close(frame);
174
        } finally {
175
            onClose(Constants.OPCODE_CLOSE);
176
        }
177
    }
178
179
    /**
180
     * Intended to be overridden by sub-classes that wish to be notified
181
     * when the outbound connection is established.
182
     *
183
     * @param outbound    The outbound WebSocket connection.
184
     */
185
    protected void onOpen(WsOutbound outbound) {
186
    }
187
188
    /**
189
     * Intended to be overridden by sub-classes that wish to be notified
190
     * when the outbound connection is closed.
191
     *
192
     * @param status    The status code of the close reason.
193
     */
194
    protected void onClose(int status) {
159
    }
195
    }
160
196
161
197
(-)java/org/apache/catalina/websocket/WsOutbound.java (-1 / +1 lines)
Lines 207-213 Link Here
207
     *
207
     *
208
     * @throws IOException  If an error occurs writing to the client
208
     * @throws IOException  If an error occurs writing to the client
209
     */
209
     */
210
    protected void close(WsFrame frame) throws IOException {
210
    protected synchronized void close(WsFrame frame) throws IOException {
211
        if (frame.getPayLoadLength() > 0) {
211
        if (frame.getPayLoadLength() > 0) {
212
            // Must be status (2 bytes) plus optional message
212
            // Must be status (2 bytes) plus optional message
213
            if (frame.getPayLoadLength() == 1) {
213
            if (frame.getPayLoadLength() == 1) {

Return to bug 51181