/// <exception cref="BadRequestException"><c>BadRequestException</c>.</exception> private void OnReceive(IAsyncResult ar) { try { lock (_syncRoot) { int bytesRead = 0; if (Stream != null) { bytesRead = Stream.EndRead(ar); } if (bytesRead == 0) { Disconnect(SocketError.ConnectionReset); return; } _bytesLeft += bytesRead; if (_bytesLeft > _buffer.Length) { #if DEBUG throw new BadRequestException("Too large HTTP header: " + Encoding.UTF8.GetString(_buffer, 0, bytesRead)); #else throw new BadRequestException("Too large HTTP header: " + _bytesLeft); #endif } LogWriter.Write(this, LogPrio.Trace, "Received " + _bytesLeft + " bytes"); int offset = _parser.Parse(_buffer, 0, _bytesLeft); if (Stream == null) { return; // "Connection: Close" in effect. } // try again to see if we can parse another message (check parser to see if it is looking for a new message) int oldOffset = offset; while (_parser.CurrentState == RequestParserState.FirstLine && offset != 0 && _bytesLeft - offset > 0) { offset = _parser.Parse(_buffer, offset, _bytesLeft - offset); if (Stream == null) { return; // "Connection: Close" in effect. } } // need to be able to move prev bytes, so restore offset. if (offset == 0) { offset = oldOffset; } if (_bytesLeft - offset >= 0) { // copy unused bytes to the beginning of the array if (offset > 0 && _bytesLeft != offset) { Buffer.BlockCopy(_buffer, offset, _buffer, 0, _bytesLeft - offset); } _bytesLeft -= offset; } else { _log.Write(this, LogPrio.Warning, "Cannot copy bytes, _bytesLeft=" + _bytesLeft + ", offset=" + offset); } if (Stream != null && Stream.CanRead) { Stream.BeginRead(_buffer, _bytesLeft, _buffer.Length - _bytesLeft, OnReceive, null); } else { _log.Write(this, LogPrio.Warning, "Could not read any more from the socket."); Disconnect(SocketError.Success); } } } catch (BadRequestException err) { LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); try { Respond(HttpHelper.HTTP10, HttpStatusCode.BadRequest, err.Message); } catch (Exception err2) { LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2); } Disconnect(SocketError.NoRecovery); } catch (IOException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); if (err.InnerException is SocketException) { Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode); } else { Disconnect(SocketError.ConnectionReset); } } catch (ObjectDisposedException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message); Disconnect(SocketError.NotSocket); } }
private void OnReceive(IAsyncResult ar) { try { int bytesRead = 0; if (m_stream == null) { return; } try { bytesRead = m_stream.EndRead(ar); } catch (NullReferenceException) { Disconnect(SocketError.ConnectionReset); return; } if (bytesRead == 0) { Disconnect(SocketError.Success); return; } if (m_isClosing) { return; } m_ReceiveBytesLeft += bytesRead; int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft); if (m_stream == null) { return; // "Connection: Close" in effect. } while (offset != 0) { int nextBytesleft = m_ReceiveBytesLeft - offset; if (nextBytesleft <= 0) { break; } int nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft); if (m_stream == null) { return; // "Connection: Close" in effect. } if (nextOffset == 0) { break; } offset = nextOffset; } // copy unused bytes to the beginning of the array if (offset > 0 && m_ReceiveBytesLeft > offset) { Buffer.BlockCopy(m_ReceiveBuffer, offset, m_ReceiveBuffer, 0, m_ReceiveBytesLeft - offset); } m_ReceiveBytesLeft -= offset; if (StreamPassedOff) { return; //? } m_stream.BeginRead(m_ReceiveBuffer, m_ReceiveBytesLeft, m_ReceiveBuffer.Length - m_ReceiveBytesLeft, OnReceive, null); } catch (BadRequestException err) { LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); try { Respond("HTTP/1.1", HttpStatusCode.BadRequest, err.Message); } catch (Exception err2) { LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2); } //Disconnect(SocketError.NoRecovery); Disconnect(SocketError.Success); // try to flush } catch (IOException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); if (err.InnerException is SocketException) { Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode); } else { Disconnect(SocketError.ConnectionReset); } } catch (ObjectDisposedException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message); Disconnect(SocketError.NotSocket); } catch (NullReferenceException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message); Disconnect(SocketError.NoRecovery); } catch (Exception err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); Disconnect(SocketError.NoRecovery); } }
/// <exception cref="BadRequestException"><c>BadRequestException</c>.</exception> private void OnReceive(IAsyncResult ar) { try { int bytesRead = Stream.EndRead(ar); if (bytesRead == 0) { Disconnect(SocketError.ConnectionReset); return; } _bytesLeft += bytesRead; if (_bytesLeft > _buffer.Length) { #if DEBUG throw new BadRequestException("Too large HTTP header: " + Encoding.UTF8.GetString(_buffer, 0, bytesRead)); #else throw new BadRequestException("Too large HTTP header: " + _bytesLeft); #endif } #if DEBUG #pragma warning disable 219 string temp = Encoding.ASCII.GetString(_buffer, 0, _bytesLeft); LogWriter.Write(this, LogPrio.Trace, "Received: " + temp); #pragma warning restore 219 #endif int offset = _parser.Parse(_buffer, 0, _bytesLeft); if (Stream == null) { return; // "Connection: Close" in effect. } // try again to see if we can parse another message (check parser to see if it is looking for a new message) int oldOffset = offset; while (_parser.CurrentState == RequestParserState.FirstLine && offset != 0 && _bytesLeft - offset > 0) { #if DEBUG temp = Encoding.ASCII.GetString(_buffer, offset, _bytesLeft - offset); LogWriter.Write(this, LogPrio.Trace, "Processing: " + temp); #endif offset = _parser.Parse(_buffer, offset, _bytesLeft - offset); if (Stream == null) { return; // "Connection: Close" in effect. } } // need to be able to move prev bytes, so restore offset. if (offset == 0) { offset = oldOffset; } // workaround until the source of the bug can be identified. if (_bytesLeft < offset) { _log.Write(this, LogPrio.Error, "Have a bug where _bytesLeft is less then offset, trying to fix. BytsLeft: " + _bytesLeft + ", offset: " + offset); _bytesLeft = offset; } // copy unused bytes to the beginning of the array if (offset > 0 && _bytesLeft != offset) { Buffer.BlockCopy(_buffer, offset, _buffer, 0, _bytesLeft - offset); } _bytesLeft -= offset; if (Stream != null && Stream.CanRead) { Stream.BeginRead(_buffer, _bytesLeft, _buffer.Length - _bytesLeft, OnReceive, null); } else { _log.Write(this, LogPrio.Warning, "Could not read any more from the socket."); Disconnect(SocketError.Success); } } catch (BadRequestException err) { LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); try { Respond("HTTP/1.0", HttpStatusCode.BadRequest, err.Message); } catch (Exception err2) { LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2); } Disconnect(SocketError.NoRecovery); } catch (IOException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); if (err.InnerException is SocketException) { Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode); } else { Disconnect(SocketError.ConnectionReset); } } catch (ObjectDisposedException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message); Disconnect(SocketError.NotSocket); } catch (NullReferenceException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message); Disconnect(SocketError.NoRecovery); } catch (Exception err) { LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); try { Respond("HTTP/1.0", HttpStatusCode.BadRequest, err.Message); } catch (Exception err2) { LogWriter.Write(this, LogPrio.Error, "Failed to reply to a bad request. " + err2); } Disconnect(SocketError.NoRecovery); } }
private async void ReceiveLoop() { m_ReceiveBytesLeft = 0; try { while (true) { if (m_stream == null || !m_stream.CanRead) { return; } int bytesRead = await m_stream.ReadAsync(m_ReceiveBuffer, m_ReceiveBytesLeft, m_ReceiveBuffer.Length - m_ReceiveBytesLeft).ConfigureAwait(false); if (bytesRead == 0) { Disconnect(SocketError.Success); return; } if (m_isClosing) { continue; } m_ReceiveBytesLeft += bytesRead; if (m_ReceiveBytesLeft > m_ReceiveBuffer.Length) { throw new BadRequestException("HTTP header Too large: " + m_ReceiveBytesLeft); } int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft); if (m_stream == null) { return; // "Connection: Close" in effect. } // try again to see if we can parse another message (check parser to see if it is looking for a new message) int nextOffset; int nextBytesleft = m_ReceiveBytesLeft - offset; while (offset != 0 && nextBytesleft > 0) { nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft); if (m_stream == null) { return; // "Connection: Close" in effect. } if (nextOffset == 0) { break; } offset = nextOffset; nextBytesleft = m_ReceiveBytesLeft - offset; } // copy unused bytes to the beginning of the array if (offset > 0 && m_ReceiveBytesLeft > offset) { Buffer.BlockCopy(m_ReceiveBuffer, offset, m_ReceiveBuffer, 0, m_ReceiveBytesLeft - offset); } m_ReceiveBytesLeft -= offset; if (StreamPassedOff) { return; //? } } } catch (BadRequestException err) { LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); try { Respond("HTTP/1.1", HttpStatusCode.BadRequest, err.Message); } catch (Exception err2) { LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2); } //Disconnect(SocketError.NoRecovery); Disconnect(SocketError.Success); // try to flush } catch (IOException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); if (err.InnerException is SocketException) { Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode); } else { Disconnect(SocketError.ConnectionReset); } } catch (ObjectDisposedException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message); Disconnect(SocketError.NotSocket); } catch (NullReferenceException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message); Disconnect(SocketError.NoRecovery); } catch (Exception err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); Disconnect(SocketError.NoRecovery); } }
/// <exception cref="BadRequestException"><c>BadRequestException</c>.</exception> private void OnReceive(IAsyncResult ar) { try { int bytesRead = Stream.EndRead(ar); if (bytesRead == 0) { Disconnect(SocketError.ConnectionReset); return; } // Albert, Team MediaPortal: Replaced usage of _bytesLeft by a local variable bytesLeft in this method // to minimize multithreading issues - to fix it finally, the multithreading capability of this method has to be reworked. int bytesLeft = _bytesLeft + bytesRead; if (bytesLeft > _buffer.Length) { #if DEBUG throw new BadRequestException("Too large HTTP header: " + Encoding.UTF8.GetString(_buffer, 0, bytesRead)); #else throw new BadRequestException("Too large HTTP header: " + _bytesLeft); #endif } #if DEBUG #pragma warning disable 219 string temp = Encoding.ASCII.GetString(_buffer, 0, bytesLeft); LogWriter.Write(this, LogPrio.Trace, "Received: " + temp); #pragma warning restore 219 #endif int offset = _parser.Parse(_buffer, 0, bytesLeft); if (Stream == null) { return; // "Connection: Close" in effect. } // try again to see if we can parse another message (check parser to see if it is looking for a new message) int oldOffset = offset; while (_parser.CurrentState == RequestParserState.FirstLine && offset != 0 && bytesLeft - offset > 0) { #if DEBUG temp = Encoding.ASCII.GetString(_buffer, offset, bytesLeft - offset); LogWriter.Write(this, LogPrio.Trace, "Processing: " + temp); #endif offset = _parser.Parse(_buffer, offset, bytesLeft - offset); if (Stream == null) { return; // "Connection: Close" in effect. } } // need to be able to move prev bytes, so restore offset. if (offset == 0) { offset = oldOffset; } // copy unused bytes to the beginning of the array if (offset > 0 && bytesLeft != offset) { Buffer.BlockCopy(_buffer, offset, _buffer, 0, bytesLeft - offset); } bytesLeft -= offset; if (Stream != null && Stream.CanRead) { Stream.BeginRead(_buffer, bytesLeft, _buffer.Length - bytesLeft, OnReceive, null); } else { _log.Write(this, LogPrio.Warning, "Could not read any more from the socket."); Disconnect(SocketError.Success); } // Albert, Team MediaPortal: Write the value back to the object's field _bytesLeft = bytesLeft; } catch (BadRequestException err) { LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); try { Respond("HTTP/1.0", HttpStatusCode.BadRequest, err.Message); } catch (Exception err2) { LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2); } Disconnect(SocketError.NoRecovery); } catch (IOException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); if (err.InnerException is SocketException) { Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode); } else { Disconnect(SocketError.ConnectionReset); } } catch (ObjectDisposedException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message); Disconnect(SocketError.NotSocket); } catch (NullReferenceException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message); Disconnect(SocketError.NoRecovery); } }
private void OnReceive(IAsyncResult ar) { try { int bytesRead = 0; if (Stream == null) { return; } try { bytesRead = Stream.EndRead(ar); } catch (NullReferenceException) { Disconnect(SocketError.ConnectionReset); return; } if (bytesRead == 0) { Disconnect(SocketError.ConnectionReset); return; } m_ReceiveBytesLeft += bytesRead; if (m_ReceiveBytesLeft > m_ReceiveBuffer.Length) { throw new BadRequestException("HTTP header Too large: " + m_ReceiveBytesLeft); } int offset = m_parser.Parse(m_ReceiveBuffer, 0, m_ReceiveBytesLeft); if (Stream == null) { return; // "Connection: Close" in effect. } // try again to see if we can parse another message (check parser to see if it is looking for a new message) int nextOffset; int nextBytesleft = m_ReceiveBytesLeft - offset; while (offset != 0 && nextBytesleft > 0) { nextOffset = m_parser.Parse(m_ReceiveBuffer, offset, nextBytesleft); if (Stream == null) { return; // "Connection: Close" in effect. } if (nextOffset == 0) { break; } offset = nextOffset; nextBytesleft = m_ReceiveBytesLeft - offset; } // copy unused bytes to the beginning of the array if (offset > 0 && m_ReceiveBytesLeft > offset) { Buffer.BlockCopy(m_ReceiveBuffer, offset, m_ReceiveBuffer, 0, m_ReceiveBytesLeft - offset); } m_ReceiveBytesLeft -= offset; if (Stream != null && Stream.CanRead) { if (!StreamPassedOff) { Stream.BeginRead(m_ReceiveBuffer, m_ReceiveBytesLeft, m_ReceiveBuffer.Length - m_ReceiveBytesLeft, OnReceive, null); } else { _log.Write(this, LogPrio.Warning, "Could not read any more from the socket."); Disconnect(SocketError.Success); } } } catch (BadRequestException err) { LogWriter.Write(this, LogPrio.Warning, "Bad request, responding with it. Error: " + err); try { Respond("HTTP/1.0", HttpStatusCode.BadRequest, err.Message); } catch (Exception err2) { LogWriter.Write(this, LogPrio.Fatal, "Failed to reply to a bad request. " + err2); } Disconnect(SocketError.NoRecovery); } catch (IOException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); if (err.InnerException is SocketException) { Disconnect((SocketError)((SocketException)err.InnerException).ErrorCode); } else { Disconnect(SocketError.ConnectionReset); } } catch (ObjectDisposedException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : " + err.Message); Disconnect(SocketError.NotSocket); } catch (NullReferenceException err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive : NullRef: " + err.Message); Disconnect(SocketError.NoRecovery); } catch (Exception err) { LogWriter.Write(this, LogPrio.Debug, "Failed to end receive: " + err.Message); Disconnect(SocketError.NoRecovery); } }