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); } }
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); }