You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
415
mcs/class/referencesource/System.Web/HttpServerVarsCollection.cs
Normal file
415
mcs/class/referencesource/System.Web/HttpServerVarsCollection.cs
Normal file
@ -0,0 +1,415 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="HttpServerVarsCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Collection of server variables with callback to HttpRequest for 'dynamic' ones
|
||||
*
|
||||
* Copyright (c) 2000 Microsoft Corporation
|
||||
*/
|
||||
|
||||
namespace System.Web {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Util;
|
||||
|
||||
internal class HttpServerVarsCollection : HttpValueCollection {
|
||||
private bool _populated;
|
||||
private HttpRequest _request;
|
||||
private IIS7WorkerRequest _iis7workerRequest;
|
||||
private List<HttpServerVarsCollectionEntry> _unsyncedEntries;
|
||||
|
||||
// We preallocate the base collection with a size that should be sufficient
|
||||
// to store all server variables w/o having to expand
|
||||
internal HttpServerVarsCollection(HttpWorkerRequest wr, HttpRequest request) : base(59) {
|
||||
// if this is an IIS7WorkerRequest, then the collection will be writeable and we will
|
||||
// call into IIS7 to update the server var block when changes are made.
|
||||
_iis7workerRequest = wr as IIS7WorkerRequest;
|
||||
_request = request;
|
||||
_populated = false;
|
||||
|
||||
Debug.Assert( _request != null );
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2236:CallBaseClassMethodsOnISerializableTypes",
|
||||
Justification = "this class, while derived from class implementing ISerializable, is not serializable")]
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
|
||||
throw new SerializationException();
|
||||
}
|
||||
|
||||
internal void Dispose() {
|
||||
_request = null;
|
||||
}
|
||||
|
||||
internal void AddStatic(String name, String value) {
|
||||
if (value == null)
|
||||
value = String.Empty;
|
||||
|
||||
InvalidateCachedArrays();
|
||||
BaseAdd(name, new HttpServerVarsCollectionEntry(name, value));
|
||||
}
|
||||
|
||||
internal void AddDynamic(String name, DynamicServerVariable var) {
|
||||
InvalidateCachedArrays();
|
||||
BaseAdd(name, new HttpServerVarsCollectionEntry(name, var));
|
||||
}
|
||||
|
||||
private String GetServerVar(Object e) {
|
||||
HttpServerVarsCollectionEntry entry = (HttpServerVarsCollectionEntry)e;
|
||||
return (entry != null) ? entry.GetValue(_request) : null;
|
||||
}
|
||||
|
||||
//
|
||||
// Support for deferred population of the collection
|
||||
//
|
||||
|
||||
private void Populate() {
|
||||
if (!_populated) {
|
||||
if (_request != null) {
|
||||
MakeReadWrite();
|
||||
_request.FillInServerVariablesCollection();
|
||||
|
||||
// Add all unsynchronized entries, if any
|
||||
if (_unsyncedEntries != null) {
|
||||
foreach (var entry in _unsyncedEntries) {
|
||||
var existingEntry = (HttpServerVarsCollectionEntry)BaseGet(entry.Name);
|
||||
if (existingEntry != null && existingEntry.IsDynamic) {
|
||||
// Exisiting dynamic server variables cannot be modified - ignore the new value
|
||||
continue;
|
||||
}
|
||||
|
||||
InvalidateCachedArrays();
|
||||
BaseSet(entry.Name, entry); // Update an existing entry, or create one if it's new
|
||||
}
|
||||
|
||||
_unsyncedEntries.Clear();
|
||||
}
|
||||
|
||||
if (_iis7workerRequest == null) {
|
||||
MakeReadOnly();
|
||||
}
|
||||
}
|
||||
_populated = true;
|
||||
}
|
||||
}
|
||||
|
||||
private String GetSimpleServerVar(String name) {
|
||||
// get server var without population of the collection
|
||||
// only most popular are included
|
||||
|
||||
if (name != null && name.Length > 1 && _request != null) {
|
||||
switch (name[0]) {
|
||||
case 'A':
|
||||
case 'a':
|
||||
if (StringUtil.EqualsIgnoreCase(name, "AUTH_TYPE"))
|
||||
return _request.CalcDynamicServerVariable(DynamicServerVariable.AUTH_TYPE);
|
||||
else if (StringUtil.EqualsIgnoreCase(name, "AUTH_USER"))
|
||||
return _request.CalcDynamicServerVariable(DynamicServerVariable.AUTH_USER);
|
||||
break;
|
||||
case 'H':
|
||||
case 'h':
|
||||
if (StringUtil.EqualsIgnoreCase(name, "HTTP_USER_AGENT"))
|
||||
return _request.UserAgent;
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
if (StringUtil.EqualsIgnoreCase(name, "QUERY_STRING"))
|
||||
return _request.QueryStringText;
|
||||
break;
|
||||
case 'P':
|
||||
case 'p':
|
||||
if (StringUtil.EqualsIgnoreCase(name, "PATH_INFO"))
|
||||
return _request.Path;
|
||||
else if (StringUtil.EqualsIgnoreCase(name, "PATH_TRANSLATED"))
|
||||
return _request.PhysicalPath;
|
||||
break;
|
||||
case 'R':
|
||||
case 'r':
|
||||
if (StringUtil.EqualsIgnoreCase(name, "REQUEST_METHOD"))
|
||||
return _request.HttpMethod;
|
||||
else if (StringUtil.EqualsIgnoreCase(name, "REMOTE_USER"))
|
||||
return _request.CalcDynamicServerVariable(DynamicServerVariable.AUTH_USER);
|
||||
else if (StringUtil.EqualsIgnoreCase(name, "REMOTE_HOST"))
|
||||
return _request.UserHostName;
|
||||
else if (StringUtil.EqualsIgnoreCase(name, "REMOTE_ADDRESS"))
|
||||
return _request.UserHostAddress;
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
if (StringUtil.EqualsIgnoreCase(name, "SCRIPT_NAME"))
|
||||
return _request.FilePath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do the default processing (populate the collection)
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
// Enumerator must pre-populate the collection
|
||||
//
|
||||
|
||||
public override IEnumerator GetEnumerator() {
|
||||
Populate();
|
||||
return base.GetEnumerator();
|
||||
}
|
||||
|
||||
//
|
||||
// NameValueCollection overrides
|
||||
//
|
||||
|
||||
public override int Count {
|
||||
get {
|
||||
Populate();
|
||||
return base.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Add(String name, String value) {
|
||||
// not supported because it appends the value to a comma separated list
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Clear() {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override String Get(String name) {
|
||||
if (!_populated) {
|
||||
String value = GetSimpleServerVar(name);
|
||||
|
||||
if (value != null)
|
||||
return value;
|
||||
|
||||
Populate();
|
||||
}
|
||||
|
||||
if (_iis7workerRequest != null) {
|
||||
string var = GetServerVar(BaseGet(name));
|
||||
|
||||
if (String.IsNullOrEmpty(var)) {
|
||||
var = _request.FetchServerVariable(name);
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
else {
|
||||
return GetServerVar(BaseGet(name));
|
||||
}
|
||||
}
|
||||
|
||||
public override String[] GetValues(String name) {
|
||||
String s = Get(name);
|
||||
return(s != null) ? new String[1] { s} : null;
|
||||
}
|
||||
|
||||
[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
|
||||
public override void Set(String name, String value) {
|
||||
if (_iis7workerRequest == null) {
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
if (name == null) {
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
SetNoDemand(name, value);
|
||||
}
|
||||
|
||||
internal void SetNoDemand(String name, String value) {
|
||||
if (value == null) {
|
||||
value = String.Empty;
|
||||
}
|
||||
|
||||
_iis7workerRequest.SetServerVariable(name, value);
|
||||
SetServerVariableManagedOnly(name, value);
|
||||
SynchronizeHeader(name, value);
|
||||
_request.InvalidateParams();
|
||||
}
|
||||
|
||||
private void SynchronizeHeader(String name, String value) {
|
||||
if (StringUtil.StringStartsWith(name, "HTTP_"))
|
||||
{
|
||||
// update managed copy of header
|
||||
string headerName = name.Substring("HTTP_".Length);
|
||||
headerName = headerName.Replace('_', '-');
|
||||
int knownIndex = HttpWorkerRequest.GetKnownRequestHeaderIndex(headerName);
|
||||
if (knownIndex > -1) {
|
||||
headerName = HttpWorkerRequest.GetKnownRequestHeaderName(knownIndex);
|
||||
}
|
||||
|
||||
HttpHeaderCollection headers = _request.Headers as HttpHeaderCollection;
|
||||
if (headers != null) {
|
||||
headers.SynchronizeHeader(headerName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updates managed copy of server variable with current value from native header block
|
||||
internal void SynchronizeServerVariable(String name, String value, bool ensurePopulated = true) {
|
||||
if (name == null) {
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
if (this._populated || ensurePopulated) {
|
||||
SetServerVariableManagedOnly(name, value);
|
||||
}
|
||||
else {
|
||||
// Lazy synchronization - when populate is indeed required
|
||||
if (_unsyncedEntries == null) {
|
||||
_unsyncedEntries = new List<HttpServerVarsCollectionEntry>();
|
||||
}
|
||||
|
||||
_unsyncedEntries.Add(new HttpServerVarsCollectionEntry(name, value));
|
||||
}
|
||||
}
|
||||
else {
|
||||
base.Remove(name);
|
||||
}
|
||||
|
||||
_request.InvalidateParams();
|
||||
}
|
||||
|
||||
// updates managed copy of server variable with current value from native header block
|
||||
private void SetServerVariableManagedOnly(String name, String value) {
|
||||
Debug.Assert(name != null);
|
||||
Debug.Assert(value != null);
|
||||
|
||||
// populate in order to identify dynamic variables
|
||||
Populate();
|
||||
|
||||
// dynamic server variables cannot be modified
|
||||
HttpServerVarsCollectionEntry entry = (HttpServerVarsCollectionEntry) BaseGet(name);
|
||||
if (entry != null && entry.IsDynamic) {
|
||||
throw new HttpException(SR.GetString(SR.Server_variable_cannot_be_modified));
|
||||
}
|
||||
|
||||
InvalidateCachedArrays();
|
||||
// this will update an existing entry, or create one if it's new
|
||||
BaseSet(name, new HttpServerVarsCollectionEntry(name, value));
|
||||
}
|
||||
|
||||
[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
|
||||
public override void Remove(String name) {
|
||||
if (_iis7workerRequest == null) {
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
if (name == null) {
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
RemoveNoDemand(name);
|
||||
}
|
||||
|
||||
internal void RemoveNoDemand(String name) {
|
||||
// delete by sending null value
|
||||
_iis7workerRequest.SetServerVariable(name, null /*value*/);
|
||||
|
||||
base.Remove(name);
|
||||
SynchronizeHeader(name, null);
|
||||
_request.InvalidateParams();
|
||||
}
|
||||
|
||||
public override String Get(int index) {
|
||||
Populate();
|
||||
return GetServerVar(BaseGet(index));
|
||||
}
|
||||
|
||||
public override String[] GetValues(int index) {
|
||||
String s = Get(index);
|
||||
return(s != null) ? new String[1] { s} : null;
|
||||
}
|
||||
|
||||
public override String GetKey(int index) {
|
||||
Populate();
|
||||
return base.GetKey(index);
|
||||
}
|
||||
|
||||
public override string[] AllKeys {
|
||||
get {
|
||||
Populate();
|
||||
return base.AllKeys;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// HttpValueCollection overrides
|
||||
//
|
||||
|
||||
internal override string ToString(bool urlencoded) {
|
||||
Populate();
|
||||
|
||||
StringBuilder s = new StringBuilder();
|
||||
int n = Count;
|
||||
String key, value;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0)
|
||||
s.Append('&');
|
||||
|
||||
key = GetKey(i);
|
||||
if (urlencoded)
|
||||
key = UrlEncodeForToString(key);
|
||||
s.Append(key);
|
||||
|
||||
s.Append('=');
|
||||
|
||||
value = Get(i);
|
||||
if (urlencoded)
|
||||
value = UrlEncodeForToString(value);
|
||||
s.Append(value);
|
||||
}
|
||||
|
||||
return s.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry in a server vars colleciton
|
||||
*/
|
||||
internal class HttpServerVarsCollectionEntry {
|
||||
internal readonly String Name;
|
||||
internal readonly bool IsDynamic;
|
||||
internal readonly String Value;
|
||||
internal readonly DynamicServerVariable Var;
|
||||
|
||||
internal HttpServerVarsCollectionEntry(String name, String value) {
|
||||
Name = name;
|
||||
Value = value;
|
||||
IsDynamic = false;
|
||||
}
|
||||
|
||||
internal HttpServerVarsCollectionEntry(String name, DynamicServerVariable var) {
|
||||
Name = name;
|
||||
Var = var;
|
||||
IsDynamic = true;
|
||||
}
|
||||
|
||||
internal String GetValue(HttpRequest request) {
|
||||
String v = null;
|
||||
|
||||
if (IsDynamic) {
|
||||
if (request != null)
|
||||
v = request.CalcDynamicServerVariable(Var);
|
||||
}
|
||||
else {
|
||||
v = Value;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user