public ResponseStream GetResponseStream()
        {
            // TODO: can we get this stream before reading the input?
            if (o_stream == null)
            {
                HttpListener listener = context.Listener;

                if (listener == null)
                {
                    return(new ResponseStream(stream, context.Response, true));
                }

                o_stream = new ResponseStream(stream, context.Response, listener.IgnoreWriteExceptions);
            }
            return(o_stream);
        }
Exemple #2
0
        void Init()
        {
            if (ssl_stream != null)
            {
                ssl_stream.AuthenticateAsServer(cert, true, (SslProtocols)ServicePointManager.SecurityProtocol, false);
            }

            context_bound = false;
            i_stream      = null;
            o_stream      = null;
            prefix        = null;
            chunked       = false;
            ms            = new MemoryStream();
            position      = 0;
            input_state   = InputState.RequestLine;
            line_state    = LineState.None;
            context       = new HttpListenerContext(this);
        }
Exemple #3
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;
            _chunked      = false;
            _ms           = new MemoryStream();
            _position     = 0;
            _inputState   = InputState.RequestLine;
            _lineState    = LineState.None;
            _context      = new HttpListenerContext(this);
        }
Exemple #4
0
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (this.disposed)
            {
                throw new ObjectDisposedException(base.GetType().ToString());
            }
            MemoryStream headers     = this.GetHeaders(false);
            bool         sendChunked = this.response.SendChunked;

            if (headers != null)
            {
                long position = headers.Position;
                headers.Position = headers.Length;
                if (sendChunked)
                {
                    byte[] chunkSizeBytes = ResponseStream.GetChunkSizeBytes(count, false);
                    headers.Write(chunkSizeBytes, 0, chunkSizeBytes.Length);
                }
                int num = Math.Min(count, 16384 - (int)headers.Position + (int)position);
                headers.Write(buffer, offset, num);
                count  -= num;
                offset += num;
                this.InternalWrite(headers.GetBuffer(), (int)position, (int)(headers.Length - position));
                headers.SetLength(0L);
                headers.Capacity = 0;
            }
            else if (sendChunked)
            {
                byte[] chunkSizeBytes = ResponseStream.GetChunkSizeBytes(count, false);
                this.InternalWrite(chunkSizeBytes, 0, chunkSizeBytes.Length);
            }
            if (count > 0)
            {
                this.InternalWrite(buffer, offset, count);
            }
            if (sendChunked)
            {
                this.InternalWrite(ResponseStream.crlf, 0, 2);
            }
        }
        internal void Close(bool force_close)
        {
            if (sock != null)
            {
                Stream st = GetResponseStream();
                if (st != null)
                {
                    st.Close();
                }

                o_stream = null;
            }

            if (sock != null)
            {
                force_close |= !context.Request.KeepAlive;
                if (!force_close)
                {
                    force_close = (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 (!force_close && context.Request.FlushInput())
                {
                    if (chunked && context.Response.ForceCloseChunked == false)
                    {
                        // Don't close. Keep working.
                        reuses++;
                        Unbind();
                        Init();
                        BeginReadRequest();
                        return;
                    }

                    reuses++;
                    Unbind();
                    Init();
                    BeginReadRequest();
                    return;
                }

                Socket s = sock;
                sock = null;
                try {
                    if (s != null)
                    {
                        s.Shutdown(SocketShutdown.Both);
                    }
                } catch {
                } finally {
                    if (s != null)
                    {
                        s.Close();
                    }
                }
                Unbind();
                RemoveConnection();
                return;
            }
        }
		internal void SendHeaders (bool closing, MemoryStream ms)
		{
			Encoding encoding = content_encoding;
			if (encoding == null)
				encoding = Encoding.Default;

			if (content_type != null) {
				if (content_encoding != null && content_type.IndexOf ("charset=") == -1) {
					string enc_name = content_encoding.WebName;
					headers.SetInternal ("Content-Type", content_type + "; charset=" + enc_name);
				} else {
					headers.SetInternal ("Content-Type", content_type);
				}
			}

			if (headers ["Server"] == null)
				headers.SetInternal ("Server", "Mono-HTTPAPI/1.0");

			CultureInfo inv = CultureInfo.InvariantCulture;
			if (headers ["Date"] == null)
				headers.SetInternal ("Date", DateTime.UtcNow.ToString ("r", inv));

			if (!chunked) {
				if (!cl_set && closing) {
					cl_set = true;
					content_length = 0;
				}

				if (cl_set)
					headers.SetInternal ("Content-Length", content_length.ToString (inv));
			}

			Version v = context.Request.ProtocolVersion;
			if (!cl_set && !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
			 */
			bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
					status_code == 413 || status_code == 414 || status_code == 500 ||
					status_code == 503);

			if (conn_close == false)
				conn_close = !context.Request.KeepAlive;

			// They sent both KeepAlive: true and Connection: close!?
			if (!keep_alive || conn_close) {
				headers.SetInternal ("Connection", "close");
				conn_close = true;
			}

			if (chunked)
				headers.SetInternal ("Transfer-Encoding", "chunked");

			int reuses = context.Connection.Reuses;
			if (reuses >= 100) {
				force_close_chunked = true;
				if (!conn_close) {
					headers.SetInternal ("Connection", "close");
					conn_close = true;
				}
			}

			if (!conn_close) {
				headers.SetInternal ("Keep-Alive", String.Format ("timeout=15,max={0}", 100 - reuses));
				if (context.Request.ProtocolVersion <= HttpVersion.Version10)
					headers.SetInternal ("Connection", "keep-alive");
			}

			if (location != null)
				headers.SetInternal ("Location", location);

			if (cookies != null) {
				bool firstDone = false;
				StringBuilder cookieSB = new StringBuilder ();
				foreach (Cookie cookie in cookies) {
					if (firstDone)
						cookieSB.Append (",");
					firstDone = true;
					cookieSB.Append (cookie.ToClientString ());
				}
				headers.SetInternal("Set-Cookie2", cookieSB.ToString ());
			}

			StreamWriter writer = new StreamWriter (ms, encoding);
			writer.Write ("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
			string headers_str = headers.ToString ();
			writer.Write (headers_str);
			writer.Flush ();
			int preamble = encoding.GetPreamble ().Length;
			if (output_stream == null)
				output_stream = context.Connection.GetResponseStream ();

			/* Assumes that the ms was at position 0 */
			ms.Position = preamble;
			HeadersSent = true;
		}
Exemple #7
0
        internal void SendHeaders(bool closing, MemoryStream ms)
        {
            Encoding encoding = content_encoding;

            if (encoding == null)
            {
                encoding = Encoding.Default;
            }

            if (content_type != null)
            {
                if (content_encoding != null && content_type.IndexOf("charset=", StringComparison.Ordinal) == -1)
                {
                    string enc_name = content_encoding.WebName;
                    headers.SetInternal("Content-Type", content_type + "; charset=" + enc_name);
                }
                else
                {
                    headers.SetInternal("Content-Type", content_type);
                }
            }

            if (headers ["Server"] == null)
            {
                headers.SetInternal("Server", "Mono-HTTPAPI/1.0");
            }

            CultureInfo inv = CultureInfo.InvariantCulture;

            if (headers ["Date"] == null)
            {
                headers.SetInternal("Date", DateTime.UtcNow.ToString("r", inv));
            }

            if (!chunked)
            {
                if (!cl_set && closing)
                {
                    cl_set         = true;
                    content_length = 0;
                }

                if (cl_set)
                {
                    headers.SetInternal("Content-Length", content_length.ToString(inv));
                }
            }

            Version v = context.Request.ProtocolVersion;

            if (!cl_set && !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
             */
            bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
                               status_code == 413 || status_code == 414 || status_code == 500 ||
                               status_code == 503);

            if (conn_close == false)
            {
                conn_close = !context.Request.KeepAlive;
            }

            // They sent both KeepAlive: true and Connection: close!?
            if (!keep_alive || conn_close)
            {
                headers.SetInternal("Connection", "close");
                conn_close = true;
            }

            if (chunked)
            {
                headers.SetInternal("Transfer-Encoding", "chunked");
            }

            int reuses = context.Connection.Reuses;

            if (reuses >= 100)
            {
                force_close_chunked = true;
                if (!conn_close)
                {
                    headers.SetInternal("Connection", "close");
                    conn_close = true;
                }
            }

            if (!conn_close)
            {
                headers.SetInternal("Keep-Alive", String.Format("timeout=15,max={0}", 100 - reuses));
                if (context.Request.ProtocolVersion <= HttpVersion.Version10)
                {
                    headers.SetInternal("Connection", "keep-alive");
                }
            }

            if (location != null)
            {
                headers.SetInternal("Location", location);
            }

            if (cookies != null)
            {
                foreach (Cookie cookie in cookies)
                {
                    headers.SetInternal("Set-Cookie", cookie.ToClientString());
                }
            }

            StreamWriter writer = new StreamWriter(ms, encoding, 256);

            writer.Write("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
            string headers_str = headers.ToStringMultiValue();

            writer.Write(headers_str);
            writer.Flush();
            int preamble = (encoding.CodePage == 65001) ? 3 : encoding.GetPreamble().Length;

            if (output_stream == null)
            {
                output_stream = context.Connection.GetResponseStream();
            }

            /* Assumes that the ms was at position 0 */
            ms.Position = preamble;
            HeadersSent = true;
        }
Exemple #8
0
        internal void FinishInitialization()
        {
            string host = UserHostName;

            if (version > HttpVersion.Version10 && (host == null || host.Length == 0))
            {
                context.ErrorMessage = "Invalid host name";
                return;
            }

            if (host == null || host.Length == 0)
            {
                host = UserHostAddress;
            }

            int colon = host.IndexOf(':');

            if (colon >= 0)
            {
                host = host.Substring(0, colon);
            }

            string base_uri = String.Format("{0}://{1}:{2}",
                                            (IsSecureConnection) ? "https" : "http",
                                            host,
                                            LocalEndPoint.Port);

            try {
                url = new Uri(base_uri + raw_url);
            } catch {
                context.ErrorMessage = "Invalid url";
                return;
            }

            CreateQueryString(url.Query);

            string t_encoding = null;

            if (version >= HttpVersion.Version11)
            {
                t_encoding = Headers ["Transfer-Encoding"];
                // 'identity' is not valid!
                if (t_encoding != null && t_encoding != "chunked")
                {
                    context.Connection.SendError(null, 501);
                    return;
                }
            }

            is_chunked = (t_encoding == "chunked");

            foreach (string m in no_body_methods)
            {
                if (string.Compare(method, m, StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    return;
                }
            }

            if (!is_chunked && !cl_set)
            {
                context.Connection.SendError(null, 411);
                return;
            }

            if (is_chunked || content_length > 0)
            {
                input_stream = context.Connection.GetRequestStream(is_chunked, content_length);
            }

            if (Headers ["Expect"] == "100-continue")
            {
                ResponseStream output = context.Connection.GetResponseStream();
                output.InternalWrite(_100continue, 0, _100continue.Length);
            }
        }
Exemple #9
0
		public ResponseStream GetResponseStream ()
		{
			// TODO: can we get this stream before reading the input?
			if (o_stream == null) {
				HttpListener listener = context.Listener;
				bool ign = (listener == null) ? true : listener.IgnoreWriteExceptions;
				o_stream = new ResponseStream (stream, context.Response, ign);
			}
			return o_stream;
		}
        internal void FinishInitialization()
        {
            string text = this.UserHostName;

            if (this.version > HttpVersion.Version10 && (text == null || text.Length == 0))
            {
                this.context.ErrorMessage = "Invalid host name";
                return;
            }
            System.Uri uri;
            string     pathAndQuery;

            if (System.Uri.MaybeUri(this.raw_url) && System.Uri.TryCreate(this.raw_url, System.UriKind.Absolute, out uri))
            {
                pathAndQuery = uri.PathAndQuery;
            }
            else
            {
                pathAndQuery = this.raw_url;
            }
            if (text == null || text.Length == 0)
            {
                text = this.UserHostAddress;
            }
            if (uri != null)
            {
                text = uri.Host;
            }
            int num = text.IndexOf(':');

            if (num >= 0)
            {
                text = text.Substring(0, num);
            }
            string text2 = string.Format("{0}://{1}:{2}", (!this.IsSecureConnection) ? "http" : "https", text, this.LocalEndPoint.Port);

            if (!System.Uri.TryCreate(text2 + pathAndQuery, System.UriKind.Absolute, out this.url))
            {
                this.context.ErrorMessage = "Invalid url: " + text2 + pathAndQuery;
                return;
            }
            this.CreateQueryString(this.url.Query);
            string text3 = null;

            if (this.version >= HttpVersion.Version11)
            {
                text3 = this.Headers["Transfer-Encoding"];
                if (text3 != null && text3 != "chunked")
                {
                    this.context.Connection.SendError(null, 501);
                    return;
                }
            }
            this.is_chunked = (text3 == "chunked");
            foreach (string strB in HttpListenerRequest.no_body_methods)
            {
                if (string.Compare(this.method, strB, StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    return;
                }
            }
            if (!this.is_chunked && !this.cl_set)
            {
                this.context.Connection.SendError(null, 411);
                return;
            }
            if (this.is_chunked || this.content_length > 0L)
            {
                this.input_stream = this.context.Connection.GetRequestStream(this.is_chunked, this.content_length);
            }
            if (this.Headers["Expect"] == "100-continue")
            {
                ResponseStream responseStream = this.context.Connection.GetResponseStream();
                responseStream.InternalWrite(HttpListenerRequest._100continue, 0, HttpListenerRequest._100continue.Length);
            }
        }
Exemple #11
0
		internal Socket Hijack (out ArraySegment<byte> buffered)
		{
			// TODO: disable normal request/response.
			buffered = new ArraySegment<byte> (ms.GetBuffer(), position, (int)ms.Length - position);
			RemoveConnection ();
			var s = sock;
			sock = null;
			o_stream = null;
			return s;
		}
Exemple #12
0
        internal void Close(bool force_close)
        {
            if (sock != null)
            {
                Stream st = GetResponseStream();
                st.Close();
                o_stream = null;
            }

            if (sock != null)
            {
                if (force_close == false)
                {
                    int  status_code = context.Response.StatusCode;
                    bool conn_close  = (status_code == 400 || status_code == 408 || status_code == 411 ||
                                        status_code == 413 || status_code == 414 || status_code == 500 ||
                                        status_code == 503);

                    if (conn_close == false)
                    {
                        conn_close  = (context.Request.Headers ["connection"] == "close");
                        conn_close |= (context.Request.ProtocolVersion <= HttpVersion.Version10);
                    }

                    if (conn_close)
                    {
                        force_close = true;
                    }
                }

                if (!force_close && chunked && context.Response.ForceCloseChunked == false)
                {
                    // Don't close. Keep working.
                    chunked_uses++;
                    Unbind();
                    Init();
                    BeginReadRequest();
                    return;
                }

                if (force_close || context.Response.Headers ["connection"] == "close")
                {
                    Socket s = sock;
                    sock = null;
                    try {
                        s.Shutdown(SocketShutdown.Both);
                    } catch {
                    } finally {
                        s.Close();
                    }
                    Unbind();
                }
                else
                {
                    Unbind();
                    Init();
                    BeginReadRequest();
                    return;
                }
            }
        }
        internal void SendHeaders(bool closing, MemoryStream ms)
        {
            var encoding = _contentEncoding;

            if (encoding == null)
            {
                encoding = Encoding.GetEncoding(0);
            }

            if (_contentType != null)
            {
                if (_contentEncoding != null && _contentType.IndexOf("charset=", StringComparison.Ordinal) == -1)
                {
                    var encName = _contentEncoding.WebName;
                    Headers.SetInternal("Content-Type", _contentType + "; charset=" + encName);
                }
                else
                {
                    Headers.SetInternal("Content-Type", _contentType);
                }
            }

            if (Headers["Server"] == null)
            {
                Headers.SetInternal("Server", "Mono-HTTPAPI/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", string.Format("timeout=15,max={0}", 100 - reuses));
                if (_context.Request.ProtocolVersion <= HttpVersion.Version10)
                {
                    Headers.SetInternal("Connection", "keep-alive");
                }
            }

            if (_location != null)
            {
                Headers.SetInternal("Location", _location);
            }

            if (_cookies != null)
            {
                foreach (Cookie cookie in _cookies)
                {
                    Headers.SetInternal("Set-Cookie", CookieToClientString(cookie));
                }
            }

            var writer = new StreamWriter(ms, encoding, 256);

            writer.Write("HTTP/{0} {1} {2}\r\n", _version, _statusCode, StatusDescription);
            var headersStr = FormatHeaders(Headers);

            writer.Write(headersStr);
            writer.Flush();
            var preamble = encoding.GetPreamble().Length;

            if (_outputStream == null)
            {
                _outputStream = _context.Connection.GetResponseStream();
            }

            /* Assumes that the ms was at position 0 */
            ms.Position = preamble;
            HeadersSent = true;
        }
Exemple #14
0
        internal void SendHeaders(bool closing)
        {
            //TODO: When do we send KeepAlive?
            MemoryStream ms       = new MemoryStream();
            Encoding     encoding = content_encoding;

            if (encoding == null)
            {
                encoding = Encoding.Default;
            }

            if (content_type != null)
            {
                if (content_encoding != null && content_type.IndexOf("charset=") == -1)
                {
                    string enc_name = content_encoding.WebName;
                    headers.SetInternal("Content-Type", content_type + "; charset=" + enc_name);
                }
                else
                {
                    headers.SetInternal("Content-Type", content_type);
                }
            }

            if (headers ["Server"] == null)
            {
                headers.SetInternal("Server", "Mono-HTTPAPI/1.0");
            }

            CultureInfo inv = CultureInfo.InvariantCulture;

            if (headers ["Date"] == null)
            {
                headers.SetInternal("Date", DateTime.UtcNow.ToString("r", inv));
            }

            if (!chunked)
            {
                if (!cl_set && closing)
                {
                    cl_set         = true;
                    content_length = 0;
                }

                if (cl_set)
                {
                    headers.SetInternal("Content-Length", content_length.ToString(inv));
                }
            }

            Version v = context.Request.ProtocolVersion;

            if (!cl_set && !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
             */
            bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 ||
                               status_code == 413 || status_code == 414 || status_code == 500 ||
                               status_code == 503);

            if (conn_close == false)
            {
                conn_close = (context.Request.Headers ["connection"] == "close");
            }

            // They sent both KeepAlive: true and Connection: close!?
            if (!chunked || conn_close)
            {
                headers.SetInternal("Connection", "close");
            }

            if (chunked)
            {
                headers.SetInternal("Transfer-Encoding", "chunked");
            }

            int chunked_uses = context.Connection.ChunkedUses;

            if (chunked_uses >= 100)
            {
                force_close_chunked = true;
                if (!conn_close)
                {
                    headers.SetInternal("Connection", "close");
                }
            }

            if (location != null)
            {
                headers.SetInternal("Location", location);
            }

            if (cookies != null)
            {
                bool          firstDone = false;
                StringBuilder cookieSB  = new StringBuilder();
                foreach (Cookie cookie in cookies)
                {
                    if (firstDone)
                    {
                        cookieSB.Append(",");
                    }
                    firstDone = true;
                    cookieSB.Append(cookie.ToClientString());
                }
                headers.SetInternal("Set-Cookie2", cookieSB.ToString());
            }

            StreamWriter writer = new StreamWriter(ms, encoding);

            writer.Write("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
            string headers_str = headers.ToString();

            writer.Write(headers_str);
            writer.Flush();
            // Perf.: use TCP_CORK if we're writing more?
            int preamble = encoding.GetPreamble().Length;

            if (output_stream == null)
            {
                output_stream = context.Connection.GetResponseStream();
            }

            output_stream.InternalWrite(ms.GetBuffer(), 0 + preamble, (int)ms.Length - preamble);
            HeadersSent = true;
        }
Exemple #15
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();
            }
        }
Exemple #16
0
        internal void FinishInitialization()
        {
            string host = UserHostName;

            if (version > HttpVersion.Version10 && (host == null || host.Length == 0))
            {
                context.ErrorMessage = "Invalid host name";
                return;
            }

            string path;
            Uri    raw_uri = null;

            if (Uri.MaybeUri(raw_url) && Uri.TryCreate(raw_url, UriKind.Absolute, out raw_uri))
            {
                path = raw_uri.PathAndQuery;
            }
            else
            {
                path = raw_url;
            }

            if ((host == null || host.Length == 0))
            {
                host = UserHostAddress;
            }

            if (raw_uri != null)
            {
                host = raw_uri.Host;
            }

            int colon = host.IndexOf(':');

            if (colon >= 0)
            {
                host = host.Substring(0, colon);
            }

            string base_uri = String.Format("{0}://{1}:{2}",
                                            (IsSecureConnection) ? "https" : "http",
                                            host, LocalEndPoint.Port);

            if (!Uri.TryCreate(base_uri + path, UriKind.Absolute, out url))
            {
                context.ErrorMessage = "Invalid url: " + base_uri + path;
                return;
            }

            CreateQueryString(url.Query);

            if (version >= HttpVersion.Version11)
            {
                string t_encoding = Headers ["Transfer-Encoding"];
                is_chunked = (t_encoding != null && String.Compare(t_encoding, "chunked", StringComparison.OrdinalIgnoreCase) == 0);
                // 'identity' is not valid!
                if (t_encoding != null && !is_chunked)
                {
                    context.Connection.SendError(null, 501);
                    return;
                }
            }

            if (!is_chunked && !cl_set)
            {
                if (String.Compare(method, "POST", StringComparison.OrdinalIgnoreCase) == 0 ||
                    String.Compare(method, "PUT", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    context.Connection.SendError(null, 411);
                    return;
                }
            }

            if (String.Compare(Headers ["Expect"], "100-continue", StringComparison.OrdinalIgnoreCase) == 0)
            {
                ResponseStream output = context.Connection.GetResponseStream();
                output.InternalWrite(_100continue, 0, _100continue.Length);
            }
        }
Exemple #17
0
		void Init ()
		{
			if (ssl_stream != null) {
				ssl_stream.AuthenticateAsServer (cert, true, (SslProtocols)ServicePointManager.SecurityProtocol, false);
			}

			context_bound = false;
			i_stream = null;
			o_stream = null;
			prefix = null;
			chunked = false;
			ms = new MemoryStream ();
			position = 0;
			input_state = InputState.RequestLine;
			line_state = LineState.None;
			context = new HttpListenerContext (this);
		}
Exemple #18
0
		void Init ()
		{
			context_bound = false;
			i_stream = null;
			o_stream = null;
			prefix = null;
			chunked = false;
			ms = new MemoryStream ();
			position = 0;
			input_state = InputState.RequestLine;
			line_state = LineState.None;
			context = new HttpListenerContext (this);
		}
Exemple #19
0
		internal void Close (bool force_close)
		{
			if (sock != null) {
				Stream st = GetResponseStream ();
				if (st != null)
					st.Close ();

				o_stream = null;
			}

			if (sock != null) {
				force_close |= !context.Request.KeepAlive;
				if (!force_close)
					force_close = (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 (!force_close && context.Request.FlushInput ()) {
					if (chunked && context.Response.ForceCloseChunked == false) {
						// Don't close. Keep working.
						reuses++;
						Unbind ();
						Init ();
						BeginReadRequest ();
						return;
					}

					reuses++;
					Unbind ();
					Init ();
					BeginReadRequest ();
					return;
				}

				Socket s = sock;
				sock = null;
				try {
					if (s != null)
						s.Shutdown (SocketShutdown.Both);
				} catch {
				} finally {
					if (s != null)
						s.Close ();
				}
				Unbind ();
				RemoveConnection ();
				return;
			}
		}
Exemple #20
0
        internal void SendHeaders(bool closing, MemoryStream ms)
        {
            Encoding @default = content_encoding;

            if (@default == null)
            {
                @default = Encoding.Default;
            }
            if (content_type != null)
            {
                if (content_encoding != null && content_type.IndexOf("charset=") == -1)
                {
                    string webName = content_encoding.WebName;
                    headers.SetInternal("Content-Type", content_type + "; charset=" + webName);
                }
                else
                {
                    headers.SetInternal("Content-Type", content_type);
                }
            }
            if (headers["Server"] == null)
            {
                headers.SetInternal("Server", "Mono-HTTPAPI/1.0");
            }
            CultureInfo invariantCulture = CultureInfo.InvariantCulture;

            if (headers["Date"] == null)
            {
                headers.SetInternal("Date", DateTime.UtcNow.ToString("r", invariantCulture));
            }
            if (!chunked)
            {
                if (!cl_set && closing)
                {
                    cl_set         = true;
                    content_length = 0L;
                }
                if (cl_set)
                {
                    headers.SetInternal("Content-Length", content_length.ToString(invariantCulture));
                }
            }
            Version protocolVersion = context.Request.ProtocolVersion;

            if (!cl_set && !chunked && protocolVersion >= HttpVersion.Version11)
            {
                chunked = true;
            }
            bool flag = status_code == 400 || status_code == 408 || status_code == 411 || status_code == 413 || status_code == 414 || status_code == 500 || status_code == 503;

            if (!flag)
            {
                flag  = (context.Request.Headers["connection"] == "close");
                flag |= (protocolVersion <= HttpVersion.Version10);
            }
            if (!keep_alive || flag)
            {
                headers.SetInternal("Connection", "close");
            }
            if (chunked)
            {
                headers.SetInternal("Transfer-Encoding", "chunked");
            }
            int chunkedUses = context.Connection.ChunkedUses;

            if (chunkedUses >= 100)
            {
                force_close_chunked = true;
                if (!flag)
                {
                    headers.SetInternal("Connection", "close");
                }
            }
            if (location != null)
            {
                headers.SetInternal("Location", location);
            }
            if (cookies != null)
            {
                foreach (Cookie cooky in cookies)
                {
                    headers.SetInternal("Set-Cookie", cooky.ToClientString());
                }
            }
            StreamWriter streamWriter = new StreamWriter(ms, @default);

            streamWriter.Write("HTTP/{0} {1} {2}\r\n", version, status_code, status_description);
            string value = headers.ToStringMultiValue();

            streamWriter.Write(value);
            streamWriter.Flush();
            int num = @default.GetPreamble().Length;

            if (output_stream == null)
            {
                output_stream = context.Connection.GetResponseStream();
            }
            ms.Position = num;
            HeadersSent = true;
        }