def _read_to_buffer(self):
"""Reads from the socket and appends the result to the read buffer.
Returns the number of bytes read. Returns 0 if there is nothing
to read (i.e. the read returns EWOULDBLOCK or equivalent). On
error closes the socket and raises an exception.
"""
while True:
try:
chunk = self.read_from_fd()
except (socket.error, IOError, OSError) as e:
if errno_from_exception(e) == errno.EINTR:
continue
# ssl.SSLError is a subclass of socket.error
if self._is_connreset(e):
# Treat ECONNRESET as a connection close rather than
# an error to minimize log spam (the exception will
# be available on self.error for apps that care).
self.close(exc_info=True)
return
self.close(exc_info=True)
raise
break
if chunk is None:
return 0
self._read_buffer.append(chunk)
self._read_buffer_size += len(chunk)
if self._read_buffer_size > self.max_buffer_size:
gen_log.error("Reached maximum read buffer size")
self.close()
raise StreamBufferFullError("Reached maximum read buffer size")
return len(chunk)
python类ECONNRESET的实例源码
def _is_connreset(self, exc):
"""Return true if exc is ECONNRESET or equivalent.
May be overridden in subclasses.
"""
return (isinstance(exc, (socket.error, IOError)) and
errno_from_exception(exc) in _ERRNO_CONNRESET)
def _read_to_buffer(self):
"""Reads from the socket and appends the result to the read buffer.
Returns the number of bytes read. Returns 0 if there is nothing
to read (i.e. the read returns EWOULDBLOCK or equivalent). On
error closes the socket and raises an exception.
"""
while True:
try:
chunk = self.read_from_fd()
except (socket.error, IOError, OSError) as e:
if errno_from_exception(e) == errno.EINTR:
continue
# ssl.SSLError is a subclass of socket.error
if self._is_connreset(e):
# Treat ECONNRESET as a connection close rather than
# an error to minimize log spam (the exception will
# be available on self.error for apps that care).
self.close(exc_info=True)
return
self.close(exc_info=True)
raise
break
if chunk is None:
return 0
self._read_buffer.append(chunk)
self._read_buffer_size += len(chunk)
if self._read_buffer_size > self.max_buffer_size:
gen_log.error("Reached maximum read buffer size")
self.close()
raise StreamBufferFullError("Reached maximum read buffer size")
return len(chunk)
def _is_connreset(self, exc):
"""Return true if exc is ECONNRESET or equivalent.
May be overridden in subclasses.
"""
return (isinstance(exc, (socket.error, IOError)) and
errno_from_exception(exc) in _ERRNO_CONNRESET)
def _read_to_buffer(self):
"""Reads from the socket and appends the result to the read buffer.
Returns the number of bytes read. Returns 0 if there is nothing
to read (i.e. the read returns EWOULDBLOCK or equivalent). On
error closes the socket and raises an exception.
"""
while True:
try:
chunk = self.read_from_fd()
except (socket.error, IOError, OSError) as e:
if errno_from_exception(e) == errno.EINTR:
continue
# ssl.SSLError is a subclass of socket.error
if self._is_connreset(e):
# Treat ECONNRESET as a connection close rather than
# an error to minimize log spam (the exception will
# be available on self.error for apps that care).
self.close(exc_info=True)
return
self.close(exc_info=True)
raise
break
if chunk is None:
return 0
self._read_buffer.append(chunk)
self._read_buffer_size += len(chunk)
if self._read_buffer_size > self.max_buffer_size:
gen_log.error("Reached maximum read buffer size")
self.close()
raise StreamBufferFullError("Reached maximum read buffer size")
return len(chunk)
def write(self, obj):
try:
size = self.socket.send(obj)
if size == 0:
raise ConnectionClosed()
return size
except socket.error, e:
if e.errno == errno.EAGAIN:
raise ConnectionAgain(str(e))
if e.errno == errno.EPIPE:
raise ConnectionClosed(str(e))
if e.errno == errno.ECONNRESET:
raise ConnectionClosed(str(e))
raise
def read(self, size):
try:
tmp = self.socket.recv(size)
if not tmp:
raise ConnectionClosed()
return tmp
except socket.error, e:
if e.errno == errno.EAGAIN:
raise ConnectionAgain(str(e))
if e.errno == errno.EBADF:
raise ConnectionClosed(str(e))
if e.errno == errno.ECONNRESET:
raise ConnectionClosed(str(e))
raise
def write(self, obj):
try:
size = self.socket.send(obj)
if size == 0:
raise ConnectionClosed()
return size
except socket.error, e:
if e.errno == errno.EAGAIN:
raise ConnectionAgain(str(e))
if e.errno == errno.EPIPE:
raise ConnectionClosed(str(e))
if e.errno == errno.ECONNRESET:
raise ConnectionClosed(str(e))
raise
def read(self, size):
try:
tmp = self.socket.recv(size)
if not tmp:
raise ConnectionClosed()
return tmp
except socket.error, e:
if e.errno == errno.EAGAIN:
raise ConnectionAgain(str(e))
if e.errno == errno.EBADF:
raise ConnectionClosed(str(e))
if e.errno == errno.ECONNRESET:
raise ConnectionClosed(str(e))
raise
def _recvall_blocking(conn, amount):
data = []
while amount > 0:
with wrapped_socket_errnos(errno.ECONNRESET):
piece = conn.recv(amount)
if not piece:
raise _ConnectionLost("could not recv() all bytes")
data.append(piece)
amount -= len(piece)
return "".join(data)
def send_encoded(conn, obj):
msg_bytes = cPickle.dumps(obj, cPickle.HIGHEST_PROTOCOL)
data = struct.pack("!I", len(msg_bytes)) + msg_bytes
with wrapped_socket_errnos(errno.ECONNRESET, errno.EPIPE):
conn.sendall(data)
def _recvall_stream(sock, amount, timeout=None):
data = []
while amount > 0:
with wrapped_socket_errnos(errno.ECONNRESET):
piece = yield sock.recv(amount, timeout=timeout)
if not piece:
raise _ConnectionLost("could not recv() all bytes")
data.append(piece)
amount -= len(piece)
idiokit.stop("".join(data))
def io_op(func, *args):
try:
return func(*args), False
except OSError, e:
IOLOG.debug('io_op(%r) -> OSError: %s', func, e)
if e.errno not in (errno.EIO, errno.ECONNRESET, errno.EPIPE):
raise
return None, True
def forward_socket(local, remote, timeout, bufsize):
"""forward socket"""
def __io_copy(dest, source, timeout):
try:
dest.settimeout(timeout)
source.settimeout(timeout)
while 1:
data = source.recv(bufsize)
if not data:
break
dest.sendall(data)
except socket.timeout:
pass
except (socket.error, ssl.SSLError, OpenSSL.SSL.Error) as e:
if e.args[0] not in (errno.ECONNABORTED, errno.ECONNRESET, errno.ENOTCONN, errno.EPIPE):
raise
if e.args[0] in (errno.EBADF,):
return
finally:
for sock in (dest, source):
try:
sock.close()
except StandardError:
pass
thread.start_new_thread(__io_copy, (remote.dup(), local.dup(), timeout))
__io_copy(local, remote, timeout)
def finish_request(self, request, client_address):
try:
self.RequestHandlerClass(request, client_address, self)
except (socket.error, ssl.SSLError, OpenSSL.SSL.Error) as e:
if e[0] not in (errno.ECONNABORTED, errno.ECONNRESET, errno.EPIPE):
logging.error("error no:%d", e[0])
raise
def handle(self, handler, do_ssl_handshake=True):
"""strip connect"""
logging.info('%s "STRIP %s %s:%d %s" - -', handler.address_string(), handler.command, handler.host, handler.port, handler.protocol_version)
handler.send_response(200)
handler.end_headers()
if do_ssl_handshake:
try:
self.do_ssl_handshake(handler)
except (socket.error, ssl.SSLError, OpenSSL.SSL.Error) as e:
if e.args[0] not in (errno.ECONNABORTED, errno.ECONNRESET) or (e[0] == -1 and 'Unexpected EOF' in e[1]):
logging.exception('ssl.wrap_socket(connection=%r) failed: %s', handler.connection, e)
return
try:
handler.raw_requestline = handler.rfile.readline(65537)
if len(handler.raw_requestline) > 65536:
handler.requestline = ''
handler.request_version = ''
handler.command = ''
handler.send_error(414)
handler.wfile.close()
return
if not handler.raw_requestline:
handler.close_connection = 1
return
if not handler.parse_request():
handler.send_error(400)
handler.wfile.close()
return
except (socket.error, ssl.SSLError, OpenSSL.SSL.Error) as e:
if e.args[0] in (errno.ECONNABORTED, errno.ECONNRESET, errno.EPIPE):
handler.close_connection = 1
return
else:
raise
try:
handler.do_METHOD()
except (socket.error, ssl.SSLError, OpenSSL.SSL.Error) as e:
if e.args[0] not in (errno.ECONNABORTED, errno.ETIMEDOUT, errno.EPIPE):
raise
def finish(self):
"""make python2 BaseHTTPRequestHandler happy"""
try:
BaseHTTPServer.BaseHTTPRequestHandler.finish(self)
except (socket.error, ssl.SSLError, OpenSSL.SSL.Error) as e:
if e[0] not in (errno.ECONNABORTED, errno.ECONNRESET, errno.EPIPE):
raise
def _send_cb(self, frame, tolerate_peer_gone=False):
"""
This is the callback used by streams to send data on the connection.
It expects to receive a single frame, and then to serialize that frame
and send it on the connection. It does so obeying the connection-level
flow-control principles of HTTP/2.
"""
# Maintain our outgoing flow-control window.
if frame.type == DataFrame.type:
# If we don't have room in the flow control window, we need to look
# for a Window Update frame.
while self._out_flow_control_window < len(frame.data):
self._recv_cb()
self._out_flow_control_window -= len(frame.data)
data = frame.serialize()
max_frame_size = self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]
if frame.body_len > max_frame_size:
raise ValueError(
"Frame size %d exceeds maximum frame size setting %d" %
(frame.body_len,
self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE])
)
log.info(
"Sending frame %s on stream %d",
frame.__class__.__name__,
frame.stream_id
)
try:
self._sock.send(data)
except socket.error as e:
if (not tolerate_peer_gone or
e.errno not in (errno.EPIPE, errno.ECONNRESET)):
raise
def send_loop(self):
while connect_control.keep_running and self.keep_running:
frame = self.send_queue.get(True)
if not frame:
# None frame to exist
break
# xlog.debug("%s Send:%s", self.ip, str(frame))
data = frame.serialize()
try:
self._sock.send(data, flush=False)
# don't flush for small package
# reduce send api call
# wait for payload frame
time.sleep(0.001)
# combine header and payload in one tcp package.
if not self.send_queue._qsize():
self._sock.flush()
except socket.error as e:
if e.errno not in (errno.EPIPE, errno.ECONNRESET):
xlog.warn("%s http2 send fail:%r", self.ip, e)
else:
xlog.exceptiong("send error:%r", e)
self.close("send fail:%r", e)
def handle(self, listener, client, addr):
req = None
try:
if self.cfg.is_ssl:
client = ssl.wrap_socket(client, server_side=True,
**self.cfg.ssl_options)
parser = http.RequestParser(self.cfg, client)
req = six.next(parser)
self.handle_request(listener, req, client, addr)
except http.errors.NoMoreData as e:
self.log.debug("Ignored premature client disconnection. %s", e)
except StopIteration as e:
self.log.debug("Closing connection. %s", e)
except ssl.SSLError as e:
if e.args[0] == ssl.SSL_ERROR_EOF:
self.log.debug("ssl connection closed")
client.close()
else:
self.log.debug("Error processing SSL request.")
self.handle_error(req, client, addr, e)
except socket.error as e:
if e.args[0] not in (errno.EPIPE, errno.ECONNRESET):
self.log.exception("Socket error processing request.")
else:
if e.args[0] == errno.ECONNRESET:
self.log.debug("Ignoring connection reset")
else:
self.log.debug("Ignoring EPIPE")
except Exception as e:
self.handle_error(req, client, addr, e)
finally:
util.close(client)