public static HandshakeResponse Parse (string [] response) { var statusLine = response [0].Split (' '); if (statusLine.Length < 3) throw new ArgumentException ("Invalid status line."); var reason = new StringBuilder (statusLine [2], 64); for (int i = 3; i < statusLine.Length; i++) reason.AppendFormat (" {0}", statusLine [i]); var headers = new WebHeaderCollection (); for (int i = 1; i < response.Length; i++) headers.SetInternal (response [i], true); return new HandshakeResponse { Headers = headers, Reason = reason.ToString (), StatusCode = statusLine [1], ProtocolVersion = new Version (statusLine [0].Substring (5)) }; }
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; }
public static HandshakeResponse Parse(string [] headerParts) { var statusLine = headerParts [0].Split (new char [] { ' ' }, 3); if (statusLine.Length != 3) throw new ArgumentException ("Invalid status line: " + headerParts [0]); var headers = new WebHeaderCollection (); for (int i = 1; i < headerParts.Length; i++) headers.SetInternal (headerParts [i], true); return new HandshakeResponse { Headers = headers, ProtocolVersion = new Version (statusLine [0].Substring (5)), Reason = statusLine [2], StatusCode = statusLine [1] }; }
internal void AddHeader(string header) { var colon = header.IndexOf(':'); if (colon <= 0) { _context.ErrorMessage = "Invalid header"; return; } var name = header.Substring(0, colon).Trim(); var val = header.Substring(colon + 1).Trim(); var lower = name.ToLower(CultureInfo.InvariantCulture); _headers.SetInternal(name, val, false); if (lower == "accept") { _acceptTypes = val.SplitHeaderValue(',').ToArray(); return; } if (lower == "accept-language") { _userLanguages = val.Split(','); return; } if (lower == "content-length") { long length; if (Int64.TryParse(val, out length) && length >= 0) { _contentLength = length; _contentLengthWasSet = true; } else { _context.ErrorMessage = "Invalid Content-Length header"; } return; } if (lower == "content-type") { var contents = val.Split(';'); foreach (var content in contents) { var tmp = content.Trim(); if (tmp.StartsWith("charset")) { var charset = tmp.GetValue("="); if (!charset.IsNullOrEmpty()) { try { _contentEncoding = Encoding.GetEncoding(charset); } catch { _context.ErrorMessage = "Invalid Content-Type header"; } } break; } } return; } if (lower == "referer") { _referer = val.ToUri(); } }
internal void AddHeader(string header) { int colon = header.IndexOf(':'); if (colon == -1 || colon == 0) { context.ErrorMessage = "Bad Request"; context.ErrorStatus = 400; return; } string name = header.Substring(0, colon).Trim(); string val = header.Substring(colon + 1).Trim(); string lower = name.ToLower(CultureInfo.InvariantCulture); headers.SetInternal(name, val); switch (lower) { case "accept-language": user_languages = val.Split(','); // yes, only split with a ',' break; case "accept": accept_types = val.Split(','); // yes, only split with a ',' break; case "content-length": try { //TODO: max. content_length? content_length = Int64.Parse(val.Trim()); if (content_length < 0) { context.ErrorMessage = "Invalid Content-Length."; } cl_set = true; } catch { context.ErrorMessage = "Invalid Content-Length."; } break; case "referer": try { referrer = new Uri(val); } catch { referrer = new Uri("http://someone.is.screwing.with.the.headers.com/"); } break; case "cookie": if (cookies == null) { cookies = new CookieCollection(); } string[] cookieStrings = val.Split(new char[] { ',', ';' }); Cookie current = null; int version = 0; foreach (string cookieString in cookieStrings) { string str = cookieString.Trim(); if (str.Length == 0) { continue; } if (str.StartsWith("$Version")) { version = Int32.Parse(Unquote(str.Substring(str.IndexOf('=') + 1))); } else if (str.StartsWith("$Path")) { if (current != null) { current.Path = str.Substring(str.IndexOf('=') + 1).Trim(); } } else if (str.StartsWith("$Domain")) { if (current != null) { current.Domain = str.Substring(str.IndexOf('=') + 1).Trim(); } } else if (str.StartsWith("$Port")) { if (current != null) { current.Port = str.Substring(str.IndexOf('=') + 1).Trim(); } } else { if (current != null) { cookies.Add(current); } current = new Cookie(); int idx = str.IndexOf('='); if (idx > 0) { current.Name = str.Substring(0, idx).Trim(); current.Value = str.Substring(idx + 1).Trim(); } else { current.Name = str.Trim(); current.Value = String.Empty; } current.Version = version; } } if (current != null) { cookies.Add(current); } break; } }
public static RequestHandshake Parse(string[] request) { var requestLine = request[0].Split(' '); if (requestLine.Length != 3) { var msg = "Invalid HTTP Request-Line: " + request[0]; throw new ArgumentException(msg, "request"); } var headers = new WebHeaderCollection(); for (int i = 1; i < request.Length; i++) headers.SetInternal(request[i], false); return new RequestHandshake { Headers = headers, HttpMethod = requestLine[0], RequestUri = requestLine[1].ToUri(), ProtocolVersion = new Version(requestLine[2].Substring(5)) }; }
public static HandshakeRequest Parse(string [] headerParts) { var requestLine = headerParts [0].Split (new char [] { ' ' }, 3); if (requestLine.Length != 3) throw new ArgumentException ("Invalid request line: " + headerParts [0]); var headers = new WebHeaderCollection (); for (int i = 1; i < headerParts.Length; i++) headers.SetInternal (headerParts [i], false); return new HandshakeRequest { Headers = headers, HttpMethod = requestLine [0], ProtocolVersion = new Version (requestLine [2].Substring (5)), RawUrl = requestLine [1], RequestUri = requestLine [1].ToUri () }; }
internal void SendHeaders(bool closing, MemoryStream stream) { if (_contentType != null) { if (_contentEncoding != null && _contentType.IndexOf("charset=", StringComparison.Ordinal) == -1) { var charset = _contentEncoding.WebName; _headers.SetInternal( "Content-Type", _contentType + "; charset=" + charset, true); } else { _headers.SetInternal("Content-Type", _contentType, true); } } if (_headers ["Server"] == null) { _headers.SetInternal("Server", "websocket-sharp/1.0", true); } var provider = CultureInfo.InvariantCulture; if (_headers ["Date"] == null) { _headers.SetInternal( "Date", DateTime.UtcNow.ToString("r", provider), true); } if (!_chunked) { if (!_contentLengthSet && closing) { _contentLengthSet = true; _contentLength = 0; } if (_contentLengthSet) { _headers.SetInternal( "Content-Length", _contentLength.ToString(provider), true); } } var version = _context.Request.ProtocolVersion; if (!_contentLengthSet && !_chunked && version >= 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) { connClose = !_context.Request.KeepAlive; } // They sent both KeepAlive: true and Connection: close!? if (!_keepAlive || connClose) { _headers.SetInternal("Connection", "close", true); connClose = true; } if (_chunked) { _headers.SetInternal("Transfer-Encoding", "chunked", true); } int reuses = _context.Connection.Reuses; if (reuses >= 100) { _forceCloseChunked = true; if (!connClose) { _headers.SetInternal("Connection", "close", true); connClose = true; } } if (!connClose) { _headers.SetInternal( "Keep-Alive", String.Format("timeout=15,max={0}", 100 - reuses), true); if (_context.Request.ProtocolVersion <= HttpVersion.Version10) { _headers.SetInternal("Connection", "keep-alive", true); } } if (_location != null) { _headers.SetInternal("Location", _location, true); } if (_cookies != null) { foreach (Cookie cookie in _cookies) { _headers.SetInternal("Set-Cookie", cookie.ToResponseString(), true); } } var encoding = _contentEncoding ?? Encoding.Default; var writer = new StreamWriter(stream, encoding, 256); writer.Write( "HTTP/{0} {1} {2}\r\n", _version, _statusCode, _statusDescription); var headers = _headers.ToStringMultiValue(true); writer.Write(headers); writer.Flush(); var preamble = encoding.CodePage == 65001 ? 3 : encoding.GetPreamble().Length; if (_outputStream == null) { _outputStream = _context.Connection.GetResponseStream(); } // Assumes that the stream was at position 0. stream.Position = preamble; HeadersSent = true; }