using System.Globalization;
using System.Security.Permissions;
using System.Web.Hosting;
+using System.Web.SessionState;
namespace System.Web {
CachedRawResponse cached_response;
string user_cache_control = "private";
string redirect_location;
+ string version_header;
+ bool version_header_checked;
//
// Negative Content-Length means we auto-compute the size of content-length
// The list of the headers that we will send back to the client, except
// the headers that we compute here.
//
- ArrayList headers = new ArrayList ();
+
+ NameValueCollection headers;
bool headers_sent;
- ArrayList cached_headers;
+ NameValueCollection cached_headers;
//
// Transfer encoding state
bool is_request_being_redirected;
Encoding headerEncoding;
#endif
-
+
internal HttpResponse ()
{
output_stream = new HttpResponseStream (this);
return prev;
}
+ internal string VersionHeader {
+ get {
+ if (!version_header_checked && version_header == null) {
+ version_header_checked = true;
+#if NET_2_0
+ HttpRuntimeSection config = WebConfigurationManager.GetWebApplicationSection ("system.web/httpRuntime") as HttpRuntimeSection;
+#else
+ HttpRuntimeConfig config = HttpContext.GetAppConfig ("system.web/httpRuntime") as HttpRuntimeConfig;
+#endif
+ if (config != null && config.EnableVersionHeader)
+ version_header = Environment.Version.ToString (3);
+ }
+
+ return version_header;
+ }
+ }
+
internal string[] FileDependencies {
get {
if (fileDependencies == null || fileDependencies.Count == 0)
headerEncoding = value;
}
}
+
+ public
+#else
+ internal
#endif
+ NameValueCollection Headers {
+ get {
+ if (headers == null)
+ headers = new NameValueCollection ();
+
+ return headers;
+ }
+ }
+
+
public bool IsClientConnected {
get {
if (WorkerRequest == null)
}
}
+#if NET_2_0
+ // We ignore the two properties on Mono as they are for use with IIS7, but there is
+ // no point in throwing PlatformNotSupportedException. We might find a use for them
+ // some day.
+ public int SubStatusCode {
+ get;
+ set;
+ }
+
+ public bool TrySkipIisCustomErrors {
+ get;
+ set;
+ }
+#endif
+
public int StatusCode {
get {
return status_code;
return;
}
- headers.Add (new UnknownResponseHeader (name, value));
+ Headers.Add (name, value);
}
[AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Medium)]
if (virtualPath == null)
return null;
- if (virtualPath == "")
+ if (virtualPath.Length == 0)
return context.Request.RootVirtualDir;
-
+
if (UrlUtils.IsRelativeUrl (virtualPath)) {
virtualPath = UrlUtils.Combine (context.Request.RootVirtualDir, virtualPath);
} else if (UrlUtils.IsRooted (virtualPath)) {
virtualPath = UrlUtils.Canonic (virtualPath);
}
-
+
+ bool cookieless = false;
+#if NET_2_0
+ SessionStateSection config = WebConfigurationManager.GetWebApplicationSection ("system.web/sessionState") as SessionStateSection;
+ cookieless = SessionStateModule.IsCookieLess (context, config);
+#else
+ SessionConfig config = HttpContext.GetAppConfig ("system.web/sessionState") as SessionConfig;
+ cookieless = config.CookieLess;
+#endif
+ if (!cookieless)
+ return virtualPath;
+
if (app_path_mod != null && virtualPath.IndexOf (app_path_mod) < 0) {
- string rvd = context.Request.RootVirtualDir;
- string basevd = rvd.Replace (app_path_mod, "");
-
- if (!StrUtils.StartsWith (virtualPath, basevd))
- return virtualPath;
-
- virtualPath = UrlUtils.Combine (rvd, virtualPath.Substring (basevd.Length));
+ if (UrlUtils.HasSessionId (virtualPath))
+ virtualPath = UrlUtils.RemoveSessionId (VirtualPathUtility.GetDirectory (virtualPath), virtualPath);
+ return UrlUtils.InsertSessionId (app_path_mod, virtualPath);
}
return virtualPath;
content_length = -1;
content_type = "text/html";
transfer_encoding = null;
- user_cache_control = null;
- headers.Clear ();
+ user_cache_control = "private";
+ if (cache_policy != null)
+ cache_policy.Cacheability = HttpCacheability.Private;
+
+ if (headers != null)
+ headers.Clear ();
}
internal bool HeadersSent {
closed = true;
}
+#if NET_2_0
+ public void DisableKernelCache ()
+ {
+ // does nothing in Mono
+ }
+#endif
+
public void End ()
{
if (context == null)
// Content-Type
// Transfer-Encoding (chunked)
// Cache-Control
- void AddHeadersNoCache (ArrayList write_headers, bool final_flush)
+ // X-AspNet-Version
+ void AddHeadersNoCache (NameValueCollection write_headers, bool final_flush)
{
#if !TARGET_J2EE
//
// Transfer-Encoding
//
if (use_chunked)
- write_headers.Add (new UnknownResponseHeader ("Transfer-Encoding", "chunked"));
+ write_headers.Add ("Transfer-Encoding", "chunked");
else if (transfer_encoding != null)
- write_headers.Add (new UnknownResponseHeader ("Transfer-Encoding", transfer_encoding));
+ write_headers.Add ("Transfer-Encoding", transfer_encoding);
#endif
if (redirect_location != null)
- write_headers.Add (new UnknownResponseHeader ("Location", redirect_location));
+ write_headers.Add ("Location", redirect_location);
#if !TARGET_J2EE
+ string vh = VersionHeader;
+ if (vh != null)
+ write_headers.Add ("X-AspNet-Version", vh);
+
//
// If Content-Length is set.
//
if (content_length >= 0) {
- write_headers.Add (new KnownResponseHeader (HttpWorkerRequest.HeaderContentLength,
- content_length.ToString (CultureInfo.InvariantCulture)));
+ write_headers.Add (HttpWorkerRequest.GetKnownResponseHeaderName (HttpWorkerRequest.HeaderContentLength),
+ content_length.ToString (CultureInfo.InvariantCulture));
} else if (BufferOutput) {
if (final_flush) {
//
// we know the content-length.
//
content_length = output_stream.total;
- write_headers.Add (new KnownResponseHeader (HttpWorkerRequest.HeaderContentLength,
- content_length.ToString (CultureInfo.InvariantCulture)));
+ write_headers.Add (HttpWorkerRequest.GetKnownResponseHeaderName (HttpWorkerRequest.HeaderContentLength),
+ content_length.ToString (CultureInfo.InvariantCulture));
} else {
//
// We are buffering, and this is a flush in the middle.
// If we are not chunked, we need to set "Connection: close".
//
if (use_chunked){
- write_headers.Add (new KnownResponseHeader (HttpWorkerRequest.HeaderConnection, "close"));
+ write_headers.Add (HttpWorkerRequest.GetKnownResponseHeaderName (HttpWorkerRequest.HeaderConnection), "close");
}
}
} else {
// close at the end.
//
if (use_chunked){
- write_headers.Add (new KnownResponseHeader (HttpWorkerRequest.HeaderConnection, "close"));
+ write_headers.Add (HttpWorkerRequest.GetKnownResponseHeaderName (HttpWorkerRequest.HeaderConnection), "close");
}
}
#endif
if (cache_policy != null)
cache_policy.SetHeaders (this, headers);
else
- write_headers.Add (new UnknownResponseHeader ("Cache-Control", CacheControl));
+ write_headers.Add ("Cache-Control", CacheControl);
//
// Content-Type
}
}
- write_headers.Add (new UnknownResponseHeader ("Content-Type", header));
+ write_headers.Add ("Content-Type", header);
}
if (cookies != null && cookies.Count != 0){
int n = cookies.Count;
for (int i = 0; i < n; i++)
- write_headers.Add (cookies.Get (i).GetCookieHeader ());
+ write_headers.Add ("Set-Cookie", cookies.Get (i).GetCookieHeaderValue ());
#if TARGET_J2EE
// For J2EE Portal support emulate cookies by storing them in the session.
context.Request.SetSessionCookiesForPortal (cookies);
// If this page is cached use the cached headers
// instead of the standard headers
- ArrayList write_headers = headers;
+ NameValueCollection write_headers;
if (cached_headers != null)
write_headers = cached_headers;
- else
+ else {
+ write_headers = Headers;
AddHeadersNoCache (write_headers, final_flush);
-
+ }
+
if (WorkerRequest != null)
WorkerRequest.SendStatus (status_code, StatusDescription);
if (WorkerRequest != null) {
- foreach (BaseResponseHeader header in write_headers){
- header.SendContent (WorkerRequest);
+ string header_name;
+ string[] values;
+ int header_index;
+
+ for (int i = 0; i < write_headers.Count; i++) {
+ header_name = write_headers.GetKey (i);
+ header_index = HttpWorkerRequest.GetKnownResponseHeaderIndex (header_name);
+ values = write_headers.GetValues (i);
+ if (values == null)
+ continue;
+
+ foreach (string val in values) {
+ if (header_index > -1)
+ WorkerRequest.SendKnownResponseHeader (header_index, val);
+ else
+ WorkerRequest.SendUnknownResponseHeader (header_name, val);
+ }
}
}
}
// Text for browsers that can't handle location header
Write ("<html><head><title>Object moved</title></head><body>\r\n");
- Write ("<h2>Object moved to <a href='" + url + "'>here</a></h2>\r\n");
+ Write ("<h2>Object moved to <a href=\"" + url + "\">here</a></h2>\r\n");
Write ("</body><html>\r\n");
if (endResponse)
}
#if NET_2_0
+ public void TransmitFile (string filename, long offset, long length)
+ {
+ output_stream.WriteFile (filename, offset, length);
+ output_stream.ApplyFilter (false);
+ Flush (false);
+ }
+
internal void TransmitFile (VirtualFile vf)
{
TransmitFile (vf, false);
}
-
+
+ const int bufLen = 65535;
internal void TransmitFile (VirtualFile vf, bool final_flush)
{
if (vf == null)
throw new ArgumentNullException ("vf");
+ if (vf is DefaultVirtualFile) {
+ TransmitFile (HostingEnvironment.MapPath (vf.VirtualPath), final_flush);
+ return;
+ }
+
+ byte[] buf = new byte [bufLen];
using (Stream s = vf.Open ()) {
- long len = s.Length;
- byte[] buf = new byte [len];
- int readBytes = s.Read (buf, 0, (int) len);
- output_stream.Write (buf, 0, readBytes);
- output_stream.ApplyFilter (final_flush);
- Flush (final_flush);
+ int readBytes;
+ while ((readBytes = s.Read (buf, 0, bufLen)) > 0) {
+ output_stream.Write (buf, 0, readBytes);
+ output_stream.ApplyFilter (final_flush);
+ Flush (false);
+ }
+ if (final_flush)
+ Flush (true);
}
}
#endif
#endregion
#region Cache Support
- internal void SetCachedHeaders (ArrayList headers)
+ internal void SetCachedHeaders (NameValueCollection headers)
{
cached_headers = headers;
+
}
internal bool IsCached {
- get {
- return cached_response != null;
+ get { return cached_response != null; }
+ set {
+ if (value)
+ cached_response = new CachedRawResponse (cache_policy);
+ else
+ cached_response = null;
}
}
public HttpCachePolicy Cache {
get {
- if (cache_policy == null) {
+ if (cache_policy == null)
cache_policy = new HttpCachePolicy ();
- cache_policy.CacheabilityUpdated += new CacheabilityUpdatedCallback (OnCacheabilityUpdated);
- }
return cache_policy;
}
- }
-
- private void OnCacheabilityUpdated (object sender, CacheabilityUpdatedEventArgs e)
- {
- if (e.Cacheability >= HttpCacheability.Server && !IsCached)
- cached_response = new CachedRawResponse (cache_policy);
- else if (e.Cacheability <= HttpCacheability.Private)
- cached_response = null;
- }
+ }
internal CachedRawResponse GetCachedResponse ()
{
- cached_response.StatusCode = StatusCode;
- cached_response.StatusDescription = StatusDescription;
+ if (cached_response != null) {
+ cached_response.StatusCode = StatusCode;
+ cached_response.StatusDescription = StatusDescription;
+ }
+
return cached_response;
}