1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
|
//------------------------------------------------------------------------------
// <copyright file="HttpHeaderCollection.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* Collection of headers with write through to IIS for Set, Add, and Remove
*
* Copyright (c) 2000 Microsoft Corporation
*/
namespace System.Web {
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.Security.Permissions;
using System.Runtime.Serialization;
using System.Web.Hosting;
using System.Web.Util;
[Serializable()]
internal class HttpHeaderCollection : HttpValueCollection {
private HttpRequest _request;
private HttpResponse _response;
private IIS7WorkerRequest _iis7WorkerRequest;
// This constructor creates the header collection for request headers.
// Try to preallocate the base collection with a size that should be sufficient
// to store the headers for most requests.
internal HttpHeaderCollection(HttpWorkerRequest wr, HttpRequest request, int capacity) : base(capacity) {
// if this is an IIS7WorkerRequest, then the collection will be writeable and we will
// call into IIS7 to update the header blocks when changes are made.
_iis7WorkerRequest = wr as IIS7WorkerRequest;
_request = request;
}
// This constructor creates the header collection for response headers.
// Try to preallocate the base collection with a size that should be sufficient
// to store the headers for most requests.
internal HttpHeaderCollection(HttpWorkerRequest wr, HttpResponse response, int capacity) : base(capacity) {
// if this is an IIS7WorkerRequest, then the collection will be writeable and we will
// call into IIS7 to update the header blocks when changes are made.
_iis7WorkerRequest = wr as IIS7WorkerRequest;
_response = response;
}
// This copy constructor is used by the granular request validation feature. Since these collections are immutable
// once created, it's ok for us to have two collections containing the same data.
internal HttpHeaderCollection(HttpHeaderCollection col)
: base(col) {
_request = col._request;
_response = col._response;
_iis7WorkerRequest = col._iis7WorkerRequest;
}
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
// WOS 127340: Request.Headers and Response.Headers are no longer serializable
base.GetObjectData(info, context);
// create an instance of HttpValueCollection since HttpHeaderCollection is tied to the request
info.SetType(typeof(HttpValueCollection));
}
public override void Add(String name, String value) {
if (_iis7WorkerRequest == null) {
throw new PlatformNotSupportedException();
}
// append to existing value
SetHeader(name, value, false /*replace*/);
}
public override void Clear() {
throw new NotSupportedException();
}
internal void ClearInternal() {
// clear is only supported for response headers
if (_request != null) {
throw new NotSupportedException();
}
base.Clear();
}
public override void Set(String name, String value) {
if (_iis7WorkerRequest == null) {
throw new PlatformNotSupportedException();
}
// set new value
SetHeader(name, value, true /*replace*/);
}
internal void SetHeader(String name, String value, bool replace) {
Debug.Assert(_iis7WorkerRequest != null, "_iis7WorkerRequest != null");
if (name == null) {
throw new ArgumentNullException("name");
}
if (value == null) {
throw new ArgumentNullException("value");
}
if (_request != null) {
_iis7WorkerRequest.SetRequestHeader(name, value, replace);
}
else {
if (_response.HeadersWritten) {
throw new HttpException(SR.GetString(SR.Cannot_append_header_after_headers_sent));
}
// IIS7 integrated pipeline mode needs to call the header encoding routine explicitly since it
// doesn't go through HttpResponse.WriteHeaders().
string encodedName = name;
string encodedValue = value;
if (HttpRuntime.EnableHeaderChecking) {
HttpEncoder.Current.HeaderNameValueEncode(name, value, out encodedName, out encodedValue);
}
// set the header encoding to the selected encoding
_iis7WorkerRequest.SetHeaderEncoding(_response.HeaderEncoding);
_iis7WorkerRequest.SetResponseHeader(encodedName, encodedValue, replace);
if (_response.HasCachePolicy && StringUtil.EqualsIgnoreCase("Set-Cookie", name)) {
_response.Cache.SetHasSetCookieHeader();
}
}
// update managed copy of header
if (replace) {
base.Set(name, value);
}
else {
base.Add(name, value);
}
if (_request != null) {
// update managed copy of server variable
string svValue = replace ? value : base.Get(name);
HttpServerVarsCollection serverVars = _request.ServerVariables as HttpServerVarsCollection;
if (serverVars != null) {
serverVars.SynchronizeServerVariable("HTTP_" + name.ToUpper(CultureInfo.InvariantCulture).Replace('-', '_'), svValue, ensurePopulated: false);
}
// invalidate Params collection
_request.InvalidateParams();
}
}
// updates managed copy of header with current value from native header block
internal void SynchronizeHeader(String name, String value) {
if (name == null) {
throw new ArgumentNullException("name");
}
if (value != null) {
base.Set(name, value);
}
else {
base.Remove(name);
}
if (_request != null) {
_request.InvalidateParams();
}
}
public override void Remove(String name) {
if (_iis7WorkerRequest == null) {
throw new PlatformNotSupportedException();
}
if (name == null) {
throw new ArgumentNullException("name");
}
if (_request != null) {
// delete by sending null value
_iis7WorkerRequest.SetRequestHeader(name, null /*value*/, false /*replace*/);
}
else {
_iis7WorkerRequest.SetResponseHeader(name, null /*value*/, false /*replace*/);
}
base.Remove(name);
if (_request != null) {
// update managed copy of server variable
HttpServerVarsCollection serverVars = _request.ServerVariables as HttpServerVarsCollection;
if (serverVars != null) {
serverVars.SynchronizeServerVariable("HTTP_" + name.ToUpper(CultureInfo.InvariantCulture).Replace('-', '_'), null, ensurePopulated: false);
}
// invalidate Params collection
_request.InvalidateParams();
}
}
}
}
|