public ResponseStream GetResponseStream() { // TODO: can we get this stream before reading the input? if (_oStream == null) { var listener = _context.Listener; if (listener == null) { return(new ResponseStream(_stream, _context.Response, true)); } _oStream = new ResponseStream(_stream, _context.Response, listener.IgnoreWriteExceptions); } return(_oStream); }
private void Init() { #if SSL if (ssl_stream != null) { ssl_stream.AuthenticateAsServer(cert, true, (SslProtocols)ServicePointManager.SecurityProtocol, false); } #endif _contextBound = false; _iStream = null; _oStream = null; Prefix = null; _ms = new MemoryStream(); _position = 0; _inputState = InputState.RequestLine; _lineState = LineState.None; _context = new HttpListenerContext(this); }
public ResponseStream GetResponseStream() => _oStream ?? (_oStream = new ResponseStream(Stream, _context.HttpListenerResponse, _context.Listener?.IgnoreWriteExceptions ?? true));
internal void SendHeaders(bool closing, MemoryStream ms) { if (_contentType != null) { if (_contentType.IndexOf("charset=", StringComparison.Ordinal) == -1) { Headers.SetInternal("Content-Type", _contentType + "; charset=" + Encoding.UTF8.WebName); } else { Headers.SetInternal("Content-Type", _contentType); } } if (Headers["Server"] == null) { Headers.SetInternal("Server", "embedio/1.0"); } var inv = CultureInfo.InvariantCulture; if (Headers["Date"] == null) { Headers.SetInternal("Date", DateTime.UtcNow.ToString("r", inv)); } if (!_chunked) { if (!_clSet && closing) { _clSet = true; _contentLength = 0; } if (_clSet) { Headers.SetInternal("Content-Length", _contentLength.ToString(inv)); } } var v = _context.Request.ProtocolVersion; if (!_clSet && !_chunked && v >= HttpVersion.Version11) { _chunked = true; } /* Apache forces closing the connection for these status codes: * HttpStatusCode.BadRequest 400 * HttpStatusCode.RequestTimeout 408 * HttpStatusCode.LengthRequired 411 * HttpStatusCode.RequestEntityTooLarge 413 * HttpStatusCode.RequestUriTooLong 414 * HttpStatusCode.InternalServerError 500 * HttpStatusCode.ServiceUnavailable 503 */ var connClose = (_statusCode == 400 || _statusCode == 408 || _statusCode == 411 || _statusCode == 413 || _statusCode == 414 || _statusCode == 500 || _statusCode == 503); if (connClose == false) { connClose = !_context.Request.KeepAlive; } // They sent both KeepAlive: true and Connection: close!? if (!_keepAlive || connClose) { Headers.SetInternal("Connection", "close"); connClose = true; } if (_chunked) { Headers.SetInternal("Transfer-Encoding", "chunked"); } var reuses = _context.Connection.Reuses; if (reuses >= 100) { ForceCloseChunked = true; if (!connClose) { Headers.SetInternal("Connection", "close"); connClose = true; } } if (!connClose) { Headers.SetInternal("Keep-Alive", $"timeout=15,max={100 - reuses}"); if (_context.Request.ProtocolVersion <= HttpVersion.Version10) { Headers.SetInternal("Connection", "keep-alive"); } } if (_location != null) { Headers.SetInternal("Location", _location); } if (_cookies != null) { foreach (System.Net.Cookie cookie in _cookies) { Headers.SetInternal("Set-Cookie", CookieToClientString(cookie)); } } var writer = new StreamWriter(ms, Encoding.UTF8, 256); writer.Write("HTTP/{0} {1} {2}\r\n", _version, _statusCode, StatusDescription); var headersStr = FormatHeaders(Headers); writer.Write(headersStr); writer.Flush(); var preamble = Encoding.UTF8.GetPreamble().Length; if (_outputStream == null) { _outputStream = _context.Connection.GetResponseStream(); } /* Assumes that the ms was at position 0 */ ms.Position = preamble; HeadersSent = true; }
public ResponseStream GetResponseStream() { return(_oStream ?? (_oStream = new ResponseStream(Stream, _context.Response, _context.Listener?.IgnoreWriteExceptions ?? true))); }
internal void Close(bool forceClose) { if (_sock != null) { Stream st = GetResponseStream(); st?.Dispose(); _oStream = null; } if (_sock != null) { forceClose |= !_context.Request.KeepAlive; if (!forceClose) { forceClose = (_context.Response.Headers["connection"] == "close"); } /* * if (!force_close) { * // bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 || * // status_code == 413 || status_code == 414 || status_code == 500 || * // status_code == 503); * force_close |= (context.Request.ProtocolVersion <= HttpVersion.Version10); * } */ if (!forceClose && _context.Request.FlushInput()) { if (_chunked && _context.Response.ForceCloseChunked == false) { // Don't close. Keep working. Reuses++; Unbind(); Init(); BeginReadRequest(); return; } Reuses++; Unbind(); Init(); BeginReadRequest(); return; } var s = _sock; _sock = null; try { s?.Shutdown(SocketShutdown.Both); } catch { // ignored } finally { s?.Dispose(); } Unbind(); RemoveConnection(); } }
internal async Task CloseAsync(bool forceClose = false) { if (_sock != null) { Stream st = GetResponseStream(); st?.Dispose(); _oStream = null; } if (_sock == null) { return; } forceClose |= !_context.Request.KeepAlive; if (!forceClose) { forceClose = _context.Response.Headers["connection"] == "close"; } if (!forceClose) { var isValidInput = await _context.Request.FlushInput(); if (isValidInput) { if (_chunked && _context.Response.ForceCloseChunked == false) { // Don't close. Keep working. Reuses++; Unbind(); Init(); await BeginReadRequest().ConfigureAwait(false); return; } Reuses++; Unbind(); Init(); await BeginReadRequest().ConfigureAwait(false); return; } } var s = _sock; _sock = null; try { s?.Shutdown(SocketShutdown.Both); } catch { // ignored } finally { s?.Dispose(); } Unbind(); RemoveConnection(); }