示例#1
0
        public void SendError(string msg, int status)
        {
            try
            {
                HttpListenerResponse response = _context.Response;
                response.StatusCode  = status;
                response.ContentType = "text/html";
                string description = HttpStatusDescription.Get(status);
                string str;
                if (msg != null)
                {
                    str = string.Format("<h1>{0} ({1})</h1>", description, msg);
                }
                else
                {
                    str = string.Format("<h1>{0}</h1>", description);
                }

                byte[] error = _textEncoding.GetDefaultEncoding().GetBytes(str);
                response.Close(error, false);
            }
            catch
            {
                // response was already closed
            }
        }
        internal void SetRequestLine(string req)
        {
            string[] parts = req.Split(s_separators, 3);
            if (parts.Length != 3)
            {
                _context.ErrorMessage = "Invalid request line (parts).";
                return;
            }

            _method = parts[0];
            foreach (char c in _method)
            {
                int ic = (int)c;

                if ((ic >= 'A' && ic <= 'Z') ||
                    (ic > 32 && c < 127 && c != '(' && c != ')' && c != '<' &&
                     c != '<' && c != '>' && c != '@' && c != ',' && c != ';' &&
                     c != ':' && c != '\\' && c != '"' && c != '/' && c != '[' &&
                     c != ']' && c != '?' && c != '=' && c != '{' && c != '}'))
                {
                    continue;
                }

                _context.ErrorMessage = "(Invalid verb)";
                return;
            }

            _rawUrl = parts[1];
            if (parts[2].Length != 8 || !parts[2].StartsWith("HTTP/"))
            {
                _context.ErrorMessage = "Invalid request line (version).";
                return;
            }

            try
            {
                _version = new Version(parts[2].Substring(5));
            }
            catch
            {
                _context.ErrorMessage = "Invalid request line (version).";
                return;
            }

            if (_version.Major < 1)
            {
                _context.ErrorMessage = "Invalid request line (version).";
                return;
            }
            if (_version.Major > 1)
            {
                _context.ErrorStatus  = (int)HttpStatusCode.HttpVersionNotSupported;
                _context.ErrorMessage = HttpStatusDescription.Get(HttpStatusCode.HttpVersionNotSupported);
                return;
            }
        }
        internal void AddHeader(string header)
        {
            int colon = header.IndexOf(':');

            if (colon == -1 || colon == 0)
            {
                _context.ErrorMessage = HttpStatusDescription.Get(400);
                _context.ErrorStatus  = 400;
                return;
            }

            string name = header.Substring(0, colon).Trim();
            string val  = header.Substring(colon + 1).Trim();

            if (name.Equals("content-length", StringComparison.OrdinalIgnoreCase))
            {
                // To match Windows behavior:
                // Content lengths >= 0 and <= long.MaxValue are accepted as is.
                // Content lengths > long.MaxValue and <= ulong.MaxValue are treated as 0.
                // Content lengths < 0 cause the requests to fail.
                // Other input is a failure, too.
                long parsedContentLength =
                    ulong.TryParse(val, out ulong parsedUlongContentLength) ? (parsedUlongContentLength <= long.MaxValue ? (long)parsedUlongContentLength : 0) :
                    long.Parse(val);
                if (parsedContentLength < 0 || (_clSet && parsedContentLength != _contentLength))
                {
                    _context.ErrorMessage = "Invalid Content-Length.";
                }
                else
                {
                    _contentLength = parsedContentLength;
                    _clSet         = true;
                }
            }
            else if (name.Equals("transfer-encoding", StringComparison.OrdinalIgnoreCase))
            {
                if (Headers[HttpKnownHeaderNames.TransferEncoding] != null)
                {
                    _context.ErrorStatus  = (int)HttpStatusCode.NotImplemented;
                    _context.ErrorMessage = HttpStatusDescription.Get(HttpStatusCode.NotImplemented);
                }
            }

            if (_context.ErrorMessage == null)
            {
                _headers.Set(name, val);
            }
        }
示例#4
0
        private void OnReadInternal(IAsyncResult ares)
        {
            //_timer.Change(Timeout.Infinite, Timeout.Infinite);
            int nread = -1;

            try
            {
                nread = _stream.EndRead(ares);
                _memoryStream.Write(_buffer, 0, nread);
                if (_memoryStream.Length > 32768)
                {
                    SendError("Bad Request", 400);
                    Close(true);
                    return;
                }
            }
            catch
            {
                if (_memoryStream != null && _memoryStream.Length > 0)
                {
                    SendError();
                }
                if (_socket != null)
                {
                    CloseSocket();
                    Unbind();
                }
                return;
            }

            if (nread == 0)
            {
                CloseSocket();
                Unbind();
                return;
            }

            if (ProcessInput(_memoryStream))
            {
                if (!_context.HaveError)
                {
                    _context.Request.FinishInitialization();
                }

                if (_context.HaveError)
                {
                    SendError();
                    Close(true);
                    return;
                }

                if (!_epl.BindContext(_context))
                {
                    const int NotFoundErrorCode = 404;
                    SendError(HttpStatusDescription.Get(NotFoundErrorCode), NotFoundErrorCode);
                    Close(true);
                    return;
                }
                HttpListener listener = _epl.Listener;
                if (_lastListener != listener)
                {
                    RemoveConnection();
                    listener.AddConnection(this);
                    _lastListener = listener;
                }

                _contextBound = true;
                listener.RegisterContext(_context);
                return;
            }
            _stream.BeginRead(_buffer, 0, BufferSize, s_onreadCallback, this);
        }