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 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(CookieHelper.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; }
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 (UriHelper.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); 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); } else { input_stream = context.Connection.GetRawStream(); } if (Headers ["Expect"] == "100-continue") { ResponseStream output = context.Connection.GetResponseStream(); output.InternalWrite(_100continue, 0, _100continue.Length); } }