public void Close() { if (sock != null) { Stream st = GetResponseStream(); st.Close(); o_stream = null; } if (sock != null) { if (chunked && context.Response.ForceCloseChunked == false) { // Don't close. Keep working. chunked_uses++; Init(); BeginReadRequest(); return; } if (context.Response.Headers ["connection"] == "close") { Socket s = sock; sock = null; try { s.Shutdown(SocketShutdown.Both); } catch { } finally { s.Close(); } } else { Init(); BeginReadRequest(); return; } if (context_bound) { epl.UnbindContext(context); } } }
internal void Close(bool force_close) { if (sock != null) { Stream st = GetResponseStream(); st.Close(); o_stream = null; } if (sock != null) { 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 FinishInitialization() { string host = UserHostName; if (version > HttpVersion.Version10 && (host == null || host.Length == 0)) { context.ErrorMessage = "Invalid host name"; return; } string path; Uri raw_uri; #if NET_2_0 if (MonoHttp.Utility.MaybeUri(raw_url) && Uri.TryCreate(raw_url, UriKind.Absolute, out raw_uri)) #else try { raw_uri = new Uri(raw_url); } catch { raw_uri = null; } if (url != raw_uri && (raw_uri.Host == null || raw_uri.Host.Length == 0)) { raw_uri = null; } if (raw_uri != null) #endif { 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 NET_2_0 if (!Uri.TryCreate(base_uri + path, UriKind.Absolute, out url)) { #else try { url = new Uri(base_uri + path); } catch {}; if (url != null && (url.Host == null || url.Host.Length == 0)) { url = null; } if (url == null) { #endif context.ErrorMessage = "Invalid url: " + base_uri + path; 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, true, System.Globalization.CultureInfo.InvariantCulture) == 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); } }
internal void SendHeaders(bool closing, MemoryStream ms) { //TODO: When do we send KeepAlive? 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"); conn_close |= (v <= HttpVersion.Version10); } // They sent both KeepAlive: true and Connection: close!? if (!keep_alive || 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(MonoHttp.Utility.ToClientString(cookie)); } 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; }