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

(-)java/org/apache/coyote/AbstractProtocol.java (+1 lines)
Lines 571-576 Link Here
571
                        release(socket, processor, false, false);
571
                        release(socket, processor, false, false);
572
                        // Create the light-weight upgrade processor
572
                        // Create the light-weight upgrade processor
573
                        processor = createUpgradeProcessor(socket, inbound);
573
                        processor = createUpgradeProcessor(socket, inbound);
574
                        inbound.onUpgradeComplete();
574
                    }
575
                    }
575
                } while (state == SocketState.ASYNC_END ||
576
                } while (state == SocketState.ASYNC_END ||
576
                        state == SocketState.UPGRADING);
577
                        state == SocketState.UPGRADING);
(-)java/org/apache/catalina/websocket/StreamInbound.java (-6 / +46 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 113-119 Link Here
113
            try {
114
            try {
114
                // TODO User defined extensions may define values for rsv
115
                // TODO User defined extensions may define values for rsv
115
                if (frame.getRsv() > 0) {
116
                if (frame.getRsv() > 0) {
116
                    getWsOutbound().close(
117
                    closeOutboundConnection(
117
                            Constants.STATUS_PROTOCOL_ERROR, null);
118
                            Constants.STATUS_PROTOCOL_ERROR, null);
118
                    return SocketState.CLOSED;
119
                    return SocketState.CLOSED;
119
                }
120
                }
Lines 127-133 Link Here
127
                            new InputStreamReader(wsIs, new Utf8Decoder());
128
                            new InputStreamReader(wsIs, new Utf8Decoder());
128
                    onTextData(r);
129
                    onTextData(r);
129
                } else if (opCode == Constants.OPCODE_CLOSE){
130
                } else if (opCode == Constants.OPCODE_CLOSE){
130
                    getWsOutbound().close(frame);
131
                    closeOutboundConnection(frame);
131
                    return SocketState.CLOSED;
132
                    return SocketState.CLOSED;
132
                } else if (opCode == Constants.OPCODE_PING) {
133
                } else if (opCode == Constants.OPCODE_PING) {
133
                    getWsOutbound().pong(frame.getPayLoad());
134
                    getWsOutbound().pong(frame.getPayLoad());
Lines 135-161 Link Here
135
                    // NO-OP
136
                    // NO-OP
136
                } else {
137
                } else {
137
                    // Unknown OpCode
138
                    // Unknown OpCode
138
                    getWsOutbound().close(
139
                    closeOutboundConnection(
139
                            Constants.STATUS_PROTOCOL_ERROR, null);
140
                            Constants.STATUS_PROTOCOL_ERROR, null);
140
                    return SocketState.CLOSED;
141
                    return SocketState.CLOSED;
141
                }
142
                }
142
            } catch (MalformedInputException mie) {
143
            } catch (MalformedInputException mie) {
143
                // Invalid UTF-8
144
                // Invalid UTF-8
144
                getWsOutbound().close(Constants.STATUS_BAD_DATA, null);
145
                closeOutboundConnection(Constants.STATUS_BAD_DATA, null);
145
                return SocketState.CLOSED;
146
                return SocketState.CLOSED;
146
            } catch (UnmappableCharacterException uce) {
147
            } catch (UnmappableCharacterException uce) {
147
                // Invalid UTF-8
148
                // Invalid UTF-8
148
                getWsOutbound().close(Constants.STATUS_BAD_DATA, null);
149
                closeOutboundConnection(Constants.STATUS_BAD_DATA, null);
149
                return SocketState.CLOSED;
150
                return SocketState.CLOSED;
150
            } catch (IOException ioe) {
151
            } catch (IOException ioe) {
151
                // Given something must have gone to reach this point, this
152
                // Given something must have gone to reach this point, this
152
                // might not work but try it anyway.
153
                // might not work but try it anyway.
153
                getWsOutbound().close(Constants.STATUS_PROTOCOL_ERROR, null);
154
                closeOutboundConnection(Constants.STATUS_PROTOCOL_ERROR, null);
154
                return SocketState.CLOSED;
155
                return SocketState.CLOSED;
155
            }
156
            }
156
            frame = wsIs.nextFrame(false);
157
            frame = wsIs.nextFrame(false);
157
        }
158
        }
158
        return SocketState.UPGRADED;
159
        return SocketState.UPGRADED;
160
    }
161
162
    private void closeOutboundConnection(int status, ByteBuffer data) throws IOException {
163
        try {
164
            getWsOutbound().close(status, data);
165
        } finally {
166
            onClose(status);
167
        }
168
    }
169
170
    private void closeOutboundConnection(WsFrame frame) throws IOException {
171
        try {
172
            getWsOutbound().close(frame);
173
        } finally {
174
            onClose(Constants.OPCODE_CLOSE);
175
        }
176
    }
177
178
    @Override
179
    public void onUpgradeComplete() {
180
        onOpen(outbound);
181
    }
182
183
    /**
184
     * Intended to be overridden by sub-classes that wish to be notified
185
     * when the outbound connection is established.
186
     *
187
     * @param outbound    The outbound WebSocket connection.
188
     */
189
    protected void onOpen(WsOutbound outbound) {
190
    }
191
192
    /**
193
     * Intended to be overridden by sub-classes that wish to be notified
194
     * when the outbound connection is closed.
195
     *
196
     * @param status    The status code of the close reason.
197
     */
198
    protected void onClose(int status) {
159
    }
199
    }
160
200
161
201
(-)java/org/apache/coyote/http11/upgrade/UpgradeInbound.java (+2 lines)
Lines 28-33 Link Here
28
28
29
    void setUpgradeProcessor(UpgradeProcessor<?> processor);
29
    void setUpgradeProcessor(UpgradeProcessor<?> processor);
30
30
31
    void onUpgradeComplete();
32
31
    SocketState onData() throws IOException;
33
    SocketState onData() throws IOException;
32
34
33
    void setUpgradeOutbound(UpgradeOutbound upgradeOutbound);
35
    void setUpgradeOutbound(UpgradeOutbound upgradeOutbound);
(-)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