Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: plugins/org.chromium.sdk.wipbackend.dev/src/org/chromium/sdk/internal/websocket/Hybi17WsConnection.java

Issue 9959080: Issue 66: closing browser results into "SocketException: Broken pipe" (Closed) Base URL: https://chromedevtools.googlecode.com/svn/trunk
Patch Set: format Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.sdk.internal.websocket; 5 package org.chromium.sdk.internal.websocket;
6 6
7 import java.io.IOException; 7 import java.io.IOException;
8 import java.net.InetSocketAddress; 8 import java.net.InetSocketAddress;
9 import java.util.Random; 9 import java.util.Random;
10 import java.util.logging.Level; 10 import java.util.logging.Level;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 sendMessage(OpCode.TEXT, payload, false); 140 sendMessage(OpCode.TEXT, payload, false);
141 } 141 }
142 142
143 @Override 143 @Override
144 protected CloseReason runListenLoop(LoggableInput loggableReader) 144 protected CloseReason runListenLoop(LoggableInput loggableReader)
145 throws IOException, InterruptedException { 145 throws IOException, InterruptedException {
146 try { 146 try {
147 return runListenLoopImpl(loggableReader); 147 return runListenLoopImpl(loggableReader);
148 } catch (IOException e) { 148 } catch (IOException e) {
149 String stackTrace = BasicUtil.getStacktraceString(e); 149 String stackTrace = BasicUtil.getStacktraceString(e);
150 sendClosingMessage(StatusCode.PROTOCOL_ERROR, stackTrace); 150 try {
151 sendClosingMessage(StatusCode.PROTOCOL_ERROR, stackTrace);
152 } catch (IOException e2) {
153 // Connection may be closed by this time. We probably don't want to log this exception.
154 }
151 throw new IOException(e); 155 throw new IOException(e);
152 } catch (IncomingProtocolException e) { 156 } catch (IncomingProtocolException e) {
153 String stackTrace = BasicUtil.getStacktraceString(e); 157 String stackTrace = BasicUtil.getStacktraceString(e);
154 sendClosingMessage(e.getStatusCode(), stackTrace); 158 sendClosingMessage(e.getStatusCode(), stackTrace);
155 throw new IOException(e); 159 throw new IOException(e);
156 } 160 }
157 } 161 }
158 162
159 private CloseReason runListenLoopImpl(LoggableInput loggableReader) 163 private CloseReason runListenLoopImpl(LoggableInput loggableReader)
160 throws IOException, InterruptedException, IncomingProtocolException { 164 throws IOException, InterruptedException, IncomingProtocolException {
161 while (true) { 165 while (true) {
162 loggableReader.markSeparatorForLog(); 166 loggableReader.markSeparatorForLog();
163 int firstByte; 167 int firstByte;
164 try { 168 try {
165 firstByte = loggableReader.readByteOrEos(); 169 firstByte = loggableReader.readByteOrEos();
166 } catch (IOException e) { 170 } catch (IOException e) {
167 if (isClosingGracefully()) { 171 if (isClosingGracefully()) {
168 return CloseReason.USER_REQUEST; 172 return CloseReason.USER_REQUEST;
169 } else { 173 } else {
170 throw e; 174 throw e;
171 } 175 }
172 } 176 }
173 if (firstByte == -1) { 177 if (firstByte == -1) {
174 if (isClosingGracefully()) { 178 if (isClosingGracefully()) {
175 return CloseReason.USER_REQUEST; 179 return CloseReason.USER_REQUEST;
176 } else { 180 } else {
177 throw new IOException("Unexpected end of stream"); 181 return CloseReason.REMOTE_SILENTLY_CLOSED;
178 } 182 }
179 } 183 }
180 184
181 if ((firstByte & FrameBits.FIN_BIT) == 0) { 185 if ((firstByte & FrameBits.FIN_BIT) == 0) {
182 throw new IncomingProtocolException("Fragments unsupported", 186 throw new IncomingProtocolException("Fragments unsupported",
183 StatusCode.CANNOT_ACCEPT, null); 187 StatusCode.CANNOT_ACCEPT, null);
184 } 188 }
185 if ((firstByte & FrameBits.RESERVED_MASK) != 0) { 189 if ((firstByte & FrameBits.RESERVED_MASK) != 0) {
186 throw new IncomingProtocolException("Unexpected reserved bits", 190 throw new IncomingProtocolException("Unexpected reserved bits",
187 StatusCode.PROTOCOL_ERROR, null); 191 StatusCode.PROTOCOL_ERROR, null);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 int length = loggablePayload.getLength(); 384 int length = loggablePayload.getLength();
381 LoggableOutput output = getSocketWrapper().getLoggableOutput(); 385 LoggableOutput output = getSocketWrapper().getLoggableOutput();
382 386
383 byte[] maskBytes = maskStrategy.generate(); 387 byte[] maskBytes = maskStrategy.generate();
384 388
385 synchronized (this) { 389 synchronized (this) {
386 if (isOutputClosed()) { 390 if (isOutputClosed()) {
387 throw new IOException("WebSocket is already closed for output"); 391 throw new IOException("WebSocket is already closed for output");
388 } 392 }
389 393
394 if (isClosingMessage) {
395 // Close it before actually sending, because we can fail on it.
396 setOutputClosed(true);
397 }
398
390 byte firstByte = (byte) (FrameBits.FIN_BIT | OpCode.TEXT); 399 byte firstByte = (byte) (FrameBits.FIN_BIT | OpCode.TEXT);
391 400
392 output.writeByte(firstByte); 401 output.writeByte(firstByte);
393 402
394 int maskFlag = maskBytes == null ? 0 : FrameBits.MASK_BIT; 403 int maskFlag = maskBytes == null ? 0 : FrameBits.MASK_BIT;
395 404
396 if (length <= 125) { 405 if (length <= 125) {
397 output.writeByte((byte) (length | maskFlag)); 406 output.writeByte((byte) (length | maskFlag));
398 } else if (length <= FrameBits.MAX_TWO_BYTE_INT) { 407 } else if (length <= FrameBits.MAX_TWO_BYTE_INT) {
399 output.writeByte((byte) (FrameBits.LENGTH_2_BYTE_CODE | maskFlag)); 408 output.writeByte((byte) (FrameBits.LENGTH_2_BYTE_CODE | maskFlag));
400 output.writeByte((byte) ((length >> 8) & 0xFF)); 409 output.writeByte((byte) ((length >> 8) & 0xFF));
401 output.writeByte((byte) (length & 0xFF)); 410 output.writeByte((byte) (length & 0xFF));
402 } else { 411 } else {
403 output.writeByte((byte) (FrameBits.LENGTH_8_BYTE_CODE | maskFlag)); 412 output.writeByte((byte) (FrameBits.LENGTH_8_BYTE_CODE | maskFlag));
404 output.writeByte((byte) 0); 413 output.writeByte((byte) 0);
405 output.writeByte((byte) 0); 414 output.writeByte((byte) 0);
406 output.writeByte((byte) 0); 415 output.writeByte((byte) 0);
407 output.writeByte((byte) 0); 416 output.writeByte((byte) 0);
408 output.writeByte((byte) (length >>> 24)); 417 output.writeByte((byte) (length >>> 24));
409 output.writeByte((byte) ((length >> 16) & 0xFF)); 418 output.writeByte((byte) ((length >> 16) & 0xFF));
410 output.writeByte((byte) ((length >> 8) & 0xFF)); 419 output.writeByte((byte) ((length >> 8) & 0xFF));
411 output.writeByte((byte) (length & 0xFF)); 420 output.writeByte((byte) (length & 0xFF));
412 } 421 }
413 422
414 if (maskBytes != null) { 423 if (maskBytes != null) {
415 output.writeBytes(maskBytes); 424 output.writeBytes(maskBytes);
416 } 425 }
417 loggablePayload.send(output, maskBytes); 426 loggablePayload.send(output, maskBytes);
418
419 if (isClosingMessage) {
420 setOutputClosed(true);
421 }
422 } 427 }
423 428
424 output.markSeparatorForLog(); 429 output.markSeparatorForLog();
425 } 430 }
426 431
427 private static void performHandshakeOrFail(ManualLoggingSocketWrapper socket, 432 private static void performHandshakeOrFail(ManualLoggingSocketWrapper socket,
428 InetSocketAddress endpoint, String resourceId) throws IOException { 433 InetSocketAddress endpoint, String resourceId) throws IOException {
429 Hybi17Handshake.Result result = 434 Hybi17Handshake.Result result =
430 Hybi17Handshake.performHandshake(socket, endpoint, resourceId, RANDOM); 435 Hybi17Handshake.performHandshake(socket, endpoint, resourceId, RANDOM);
431 result.accept(HANDSHAKE_RESULT_VISITOR).get(); 436 result.accept(HANDSHAKE_RESULT_VISITOR).get();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 } 513 }
509 514
510 private interface StatusCode { 515 private interface StatusCode {
511 int NORMAL = 1000; 516 int NORMAL = 1000;
512 int PROTOCOL_ERROR = 1002; 517 int PROTOCOL_ERROR = 1002;
513 int CANNOT_ACCEPT = 1003; 518 int CANNOT_ACCEPT = 1003;
514 } 519 }
515 520
516 private static final int STATUS_CODE_LENTGH = 2; 521 private static final int STATUS_CODE_LENTGH = 2;
517 } 522 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698