public ResponseStream GetResponseStream() { // TODO: Can we get this stream before reading the input? if (_outputStream != null || _socket == null) { return(_outputStream); } lock (_sync) { if (_socket == null) { return(_outputStream); } var lsnr = _context.Listener; var ignore = lsnr != null ? lsnr.IgnoreWriteExceptions : true; _outputStream = new ResponseStream(_stream, _context.Response, ignore); return(_outputStream); } }
internal void SendHeaders (MemoryStream stream, bool closing) { if (_contentType != null) { var type = _contentType.IndexOf ("charset=", StringComparison.Ordinal) == -1 && _contentEncoding != null ? String.Format ("{0}; charset={1}", _contentType, _contentEncoding.WebName) : _contentType; _headers.InternalSet ("Content-Type", type, true); } if (_headers["Server"] == null) _headers.InternalSet ("Server", "websocket-sharp/1.0", true); var prov = CultureInfo.InvariantCulture; if (_headers["Date"] == null) _headers.InternalSet ("Date", DateTime.UtcNow.ToString ("r", prov), true); if (!_chunked) { if (!_contentLengthWasSet && closing) { _contentLengthWasSet = true; _contentLength = 0; } if (_contentLengthWasSet) _headers.InternalSet ("Content-Length", _contentLength.ToString (prov), true); } var ver = _context.Request.ProtocolVersion; if (!_contentLengthWasSet && !_chunked && ver > HttpVersion.Version10) _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 closeConn = _statusCode == 400 || _statusCode == 408 || _statusCode == 411 || _statusCode == 413 || _statusCode == 414 || _statusCode == 500 || _statusCode == 503; if (!closeConn) closeConn = !_context.Request.KeepAlive; // They sent both KeepAlive: true and Connection: close!? if (!_keepAlive || closeConn) { _headers.InternalSet ("Connection", "close", true); closeConn = true; } if (_chunked) _headers.InternalSet ("Transfer-Encoding", "chunked", true); var reuses = _context.Connection.Reuses; if (reuses >= 100) { _forceCloseChunked = true; if (!closeConn) { _headers.InternalSet ("Connection", "close", true); closeConn = true; } } if (!closeConn) { _headers.InternalSet ( "Keep-Alive", String.Format ("timeout=15,max={0}", 100 - reuses), true); if (ver < HttpVersion.Version11) _headers.InternalSet ("Connection", "keep-alive", true); } if (_location != null) _headers.InternalSet ("Location", _location, true); if (_cookies != null) foreach (Cookie cookie in _cookies) _headers.InternalSet ("Set-Cookie", cookie.ToResponseString (), true); var enc = _contentEncoding ?? Encoding.Default; var writer = new StreamWriter (stream, enc, 256); writer.Write ("HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription); writer.Write (_headers.ToStringMultiValue (true)); writer.Flush (); // Assumes that the stream was at position 0. stream.Position = enc.CodePage == 65001 ? 3 : enc.GetPreamble ().Length; if (_outputStream == null) _outputStream = _context.Connection.GetResponseStream (); _headersWereSent = true; }
internal void SendHeaders(MemoryStream stream, bool closing) { if (_contentType != null) { var type = _contentType.IndexOf("charset=", StringComparison.Ordinal) == -1 && _contentEncoding != null ? String.Format("{0}; charset={1}", _contentType, _contentEncoding.WebName) : _contentType; _headers.InternalSet("Content-Type", type, true); } if (_headers["Server"] == null) { _headers.InternalSet("Server", "websocket-sharp/1.0", true); } var prov = CultureInfo.InvariantCulture; if (_headers["Date"] == null) { _headers.InternalSet("Date", DateTime.UtcNow.ToString("r", prov), true); } if (!_chunked) { if (!_contentLengthWasSet && closing) { _contentLengthWasSet = true; _contentLength = 0; } if (_contentLengthWasSet) { _headers.InternalSet("Content-Length", _contentLength.ToString(prov), true); } } var ver = _context.Request.ProtocolVersion; if (!_contentLengthWasSet && !_chunked && ver > HttpVersion.Version10) { _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 closeConn = _statusCode == 400 || _statusCode == 408 || _statusCode == 411 || _statusCode == 413 || _statusCode == 414 || _statusCode == 500 || _statusCode == 503; if (!closeConn) { closeConn = !_context.Request.KeepAlive; } // They sent both KeepAlive: true and Connection: close!? if (!_keepAlive || closeConn) { _headers.InternalSet("Connection", "close", true); closeConn = true; } if (_chunked) { _headers.InternalSet("Transfer-Encoding", "chunked", true); } var reuses = _context.Connection.Reuses; if (reuses >= 100) { _forceCloseChunked = true; if (!closeConn) { _headers.InternalSet("Connection", "close", true); closeConn = true; } } if (!closeConn) { _headers.InternalSet( "Keep-Alive", String.Format("timeout=15,max={0}", 100 - reuses), true); if (ver < HttpVersion.Version11) { _headers.InternalSet("Connection", "keep-alive", true); } } if (_location != null) { _headers.InternalSet("Location", _location, true); } if (_cookies != null) { foreach (Cookie cookie in _cookies) { _headers.InternalSet("Set-Cookie", cookie.ToResponseString(), true); } } var enc = _contentEncoding ?? Encoding.Default; var writer = new StreamWriter(stream, enc, 256); writer.Write("HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription); writer.Write(_headers.ToStringMultiValue(true)); writer.Flush(); // Assumes that the stream was at position 0. stream.Position = enc.CodePage == 65001 ? 3 : enc.GetPreamble().Length; if (_outputStream == null) { _outputStream = _context.Connection.GetResponseStream(); } _headersWereSent = true; }