Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
 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;
        }
Example #5
0
 public ResponseStream GetResponseStream()
 {
     return(_oStream ??
            (_oStream =
                 new ResponseStream(Stream, _context.Response, _context.Listener?.IgnoreWriteExceptions ?? true)));
 }
Example #6
0
        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();
            }
        }
Example #7
0
        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();
        }