Last active
November 20, 2019 04:05
-
-
Save lwl5219/4d273ead9d56f295e5bc2efdaa37b591 to your computer and use it in GitHub Desktop.
Http simulator for Unit Test. You can get more detail at https://haacked.com/archive/2005/06/11/simulating_httpcontext.aspx/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Specialized; | |
using System.IO; | |
using System.Security.Principal; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using System.Web; | |
using System.Web.Configuration; | |
using System.Web.Hosting; | |
using System.Web.SessionState; | |
namespace Subtext.TestLibrary { | |
public enum HttpVerb { | |
GET, | |
HEAD, | |
POST, | |
PUT, | |
DELETE, | |
} | |
/// <summary> | |
/// Useful class for simulating the HttpContext. This does not actually | |
/// make an HttpRequest, it merely simulates the state that your code | |
/// would be in "as if" handling a request. Thus the HttpContext.Current | |
/// property is populated. | |
/// </summary> | |
public class HttpSimulator : IDisposable { | |
private const string defaultPhysicalAppPath = @"c:\InetPub\wwwRoot\"; | |
private StringBuilder builder; | |
private Uri _referer; | |
private NameValueCollection _formVars = new NameValueCollection(); | |
private NameValueCollection _headers = new NameValueCollection(); | |
private string appBinPath; | |
public HttpSimulator() : this("/", defaultPhysicalAppPath, defaultPhysicalAppPath) { | |
} | |
public HttpSimulator(string applicationPath) : | |
this(applicationPath, defaultPhysicalAppPath, defaultPhysicalAppPath) { | |
} | |
public HttpSimulator(string applicationPath, string physicalApplicationPath, string appBinPath) { | |
this.ApplicationPath = applicationPath; | |
this.PhysicalApplicationPath = physicalApplicationPath; | |
this.appBinPath = appBinPath; | |
} | |
/// <summary> | |
/// Sets up the HttpContext objects to simulate a GET request. | |
/// </summary> | |
/// <remarks> | |
/// Simulates a request to http://localhost/ | |
/// </remarks> | |
public HttpSimulator SimulateRequest() { | |
return SimulateRequest(new Uri("http://localhost/")); | |
} | |
/// <summary> | |
/// Sets up the HttpContext objects to simulate a GET request. | |
/// </summary> | |
/// <param name="url"></param> | |
public HttpSimulator SimulateRequest(Uri url) { | |
return SimulateRequest(url, HttpVerb.GET); | |
} | |
/// <summary> | |
/// Sets up the HttpContext objects to simulate a request. | |
/// </summary> | |
/// <param name="url"></param> | |
/// <param name="httpVerb"></param> | |
public HttpSimulator SimulateRequest(Uri url, HttpVerb httpVerb) { | |
return SimulateRequest(url, httpVerb, null, null); | |
} | |
/// <summary> | |
/// Sets up the HttpContext objects to simulate a POST request. | |
/// </summary> | |
/// <param name="url"></param> | |
/// <param name="formVariables"></param> | |
public HttpSimulator SimulateRequest(Uri url, NameValueCollection formVariables) { | |
return SimulateRequest(url, HttpVerb.POST, formVariables, null); | |
} | |
/// <summary> | |
/// Sets up the HttpContext objects to simulate a POST request. | |
/// </summary> | |
/// <param name="url"></param> | |
/// <param name="formVariables"></param> | |
/// <param name="headers"></param> | |
public HttpSimulator SimulateRequest(Uri url, NameValueCollection formVariables, NameValueCollection headers) { | |
return SimulateRequest(url, HttpVerb.POST, formVariables, headers); | |
} | |
/// <summary> | |
/// Sets up the HttpContext objects to simulate a request. | |
/// </summary> | |
/// <param name="url"></param> | |
/// <param name="httpVerb"></param> | |
/// <param name="headers"></param> | |
public HttpSimulator SimulateRequest(Uri url, HttpVerb httpVerb, NameValueCollection headers) { | |
return SimulateRequest(url, httpVerb, null, headers); | |
} | |
/// <summary> | |
/// Sets up the HttpContext objects to simulate a request. | |
/// </summary> | |
/// <param name="url"></param> | |
/// <param name="httpVerb"></param> | |
/// <param name="formVariables"></param> | |
/// <param name="headers"></param> | |
protected virtual HttpSimulator SimulateRequest(Uri url, HttpVerb httpVerb, NameValueCollection formVariables, | |
NameValueCollection headers) { | |
HttpContext.Current = null; | |
ParseRequestUrl(url); | |
if (this.responseWriter == null) { | |
this.builder = new StringBuilder(); | |
this.responseWriter = new StringWriter(builder); | |
} | |
SetHttpRuntimeInternals(); | |
string query = ExtractQueryStringPart(url); | |
if (formVariables != null) | |
_formVars.Add(formVariables); | |
if (_formVars.Count > 0) | |
httpVerb = HttpVerb.POST; //Need to enforce this. | |
if (headers != null) | |
_headers.Add(headers); | |
this.workerRequest = new SimulatedHttpRequest(ApplicationPath, PhysicalApplicationPath, PhysicalPath, Page, query, | |
this.responseWriter, host, port, httpVerb.ToString()); | |
this.workerRequest.Form.Add(_formVars); | |
this.workerRequest.Headers.Add(_headers); | |
if (_referer != null) | |
this.workerRequest.SetReferer(_referer); | |
InitializeSession(); | |
InitializeApplication(); | |
HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(""), new string[] { }); | |
#region Console Debug INfo | |
Console.WriteLine("host: " + host); | |
Console.WriteLine("virtualDir: " + applicationPath); | |
Console.WriteLine("page: " + localPath); | |
Console.WriteLine("pathPartAfterApplicationPart: " + _page); | |
Console.WriteLine("appPhysicalDir: " + physicalApplicationPath); | |
Console.WriteLine("Request.Url.LocalPath: " + HttpContext.Current.Request.Url.LocalPath); | |
Console.WriteLine("Request.Url.Host: " + HttpContext.Current.Request.Url.Host); | |
Console.WriteLine("Request.FilePath: " + HttpContext.Current.Request.FilePath); | |
Console.WriteLine("Request.Path: " + HttpContext.Current.Request.Path); | |
Console.WriteLine("Request.RawUrl: " + HttpContext.Current.Request.RawUrl); | |
Console.WriteLine("Request.Url: " + HttpContext.Current.Request.Url); | |
Console.WriteLine("Request.Url.Port: " + HttpContext.Current.Request.Url.Port); | |
Console.WriteLine("Request.ApplicationPath: " + HttpContext.Current.Request.ApplicationPath); | |
Console.WriteLine("Request.PhysicalPath: " + HttpContext.Current.Request.PhysicalPath); | |
Console.WriteLine("User.Identity.Name: " + HttpContext.Current.User.Identity.Name); | |
Console.WriteLine("HttpRuntime.AppDomainAppVirtualPath: " + HttpRuntime.AppDomainAppVirtualPath); | |
Console.WriteLine("HostingEnvironment.ApplicationPhysicalPath: " + HostingEnvironment.ApplicationPhysicalPath); | |
Console.WriteLine("HostingEnvironment.ApplicationVirtualPath: " + HostingEnvironment.ApplicationVirtualPath); | |
#endregion | |
return this; | |
} | |
private static void InitializeApplication() { | |
Type appFactoryType = | |
Type.GetType( | |
"System.Web.HttpApplicationFactory, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); | |
object appFactory = ReflectionHelper.GetStaticFieldValue<object>("_theApplicationFactory", appFactoryType); | |
ReflectionHelper.SetPrivateInstanceFieldValue("_state", appFactory, HttpContext.Current.Application); | |
} | |
private void InitializeSession() { | |
HttpContext.Current = new HttpContext(workerRequest); | |
HttpContext.Current.Items.Clear(); | |
HttpSessionState session = (HttpSessionState) ReflectionHelper.Instantiate(typeof(HttpSessionState), | |
new Type[] {typeof(IHttpSessionState)}, new FakeHttpSessionState()); | |
HttpContext.Current.Items.Add("AspSession", session); | |
} | |
public class FakeHttpSessionState : NameObjectCollectionBase, IHttpSessionState { | |
private string sessionID = Guid.NewGuid().ToString(); | |
private int timeout = 30; //minutes | |
private bool isNewSession = true; | |
private int lcid; | |
private int codePage; | |
private HttpStaticObjectsCollection staticObjects = new HttpStaticObjectsCollection(); | |
private object syncRoot = new Object(); | |
///<summary> | |
///Ends the current session. | |
///</summary> | |
/// | |
public void Abandon() { | |
BaseClear(); | |
} | |
///<summary> | |
///Adds a new item to the session-state collection. | |
///</summary> | |
/// | |
///<param name="name">The name of the item to add to the session-state collection. </param> | |
///<param name="value">The value of the item to add to the session-state collection. </param> | |
public void Add(string name, object value) { | |
BaseAdd(name, value); | |
} | |
///<summary> | |
///Deletes an item from the session-state item collection. | |
///</summary> | |
/// | |
///<param name="name">The name of the item to delete from the session-state item collection. </param> | |
public void Remove(string name) { | |
BaseRemove(name); | |
} | |
///<summary> | |
///Deletes an item at a specified index from the session-state item collection. | |
///</summary> | |
/// | |
///<param name="index">The index of the item to remove from the session-state collection. </param> | |
public void RemoveAt(int index) { | |
BaseRemoveAt(index); | |
} | |
///<summary> | |
///Clears all values from the session-state item collection. | |
///</summary> | |
/// | |
public void Clear() { | |
BaseClear(); | |
} | |
///<summary> | |
///Clears all values from the session-state item collection. | |
///</summary> | |
/// | |
public void RemoveAll() { | |
BaseClear(); | |
} | |
///<summary> | |
///Copies the collection of session-state item values to a one-dimensional array, starting at the specified index in the array. | |
///</summary> | |
/// | |
///<param name="array">The <see cref="T:System.Array"></see> that receives the session values. </param> | |
///<param name="index">The index in array where copying starts. </param> | |
public void CopyTo(Array array, int index) { | |
throw new NotImplementedException(); | |
} | |
///<summary> | |
///Gets the unique session identifier for the session. | |
///</summary> | |
/// | |
///<returns> | |
///The session ID. | |
///</returns> | |
/// | |
public string SessionID { | |
get { return sessionID; } | |
} | |
///<summary> | |
///Gets and sets the time-out period (in minutes) allowed between requests before the session-state provider terminates the session. | |
///</summary> | |
/// | |
///<returns> | |
///The time-out period, in minutes. | |
///</returns> | |
/// | |
public int Timeout { | |
get { return timeout; } | |
set { timeout = value; } | |
} | |
///<summary> | |
///Gets a value indicating whether the session was created with the current request. | |
///</summary> | |
/// | |
///<returns> | |
///true if the session was created with the current request; otherwise, false. | |
///</returns> | |
/// | |
public bool IsNewSession { | |
get { return isNewSession; } | |
} | |
///<summary> | |
///Gets the current session-state mode. | |
///</summary> | |
/// | |
///<returns> | |
///One of the <see cref="T:System.Web.SessionState.SessionStateMode"></see> values. | |
///</returns> | |
/// | |
public SessionStateMode Mode { | |
get { return SessionStateMode.InProc; } | |
} | |
///<summary> | |
///Gets a value indicating whether the session ID is embedded in the URL or stored in an HTTP cookie. | |
///</summary> | |
/// | |
///<returns> | |
///true if the session is embedded in the URL; otherwise, false. | |
///</returns> | |
/// | |
public bool IsCookieless { | |
get { return false; } | |
} | |
///<summary> | |
///Gets a value that indicates whether the application is configured for cookieless sessions. | |
///</summary> | |
/// | |
///<returns> | |
///One of the <see cref="T:System.Web.HttpCookieMode"></see> values that indicate whether the application is configured for cookieless sessions. The default is <see cref="F:System.Web.HttpCookieMode.UseCookies"></see>. | |
///</returns> | |
/// | |
public HttpCookieMode CookieMode { | |
get { return HttpCookieMode.UseCookies; } | |
} | |
///<summary> | |
///Gets or sets the locale identifier (LCID) of the current session. | |
///</summary> | |
/// | |
///<returns> | |
///A <see cref="T:System.Globalization.CultureInfo"></see> instance that specifies the culture of the current session. | |
///</returns> | |
/// | |
public int LCID { | |
get { return lcid; } | |
set { lcid = value; } | |
} | |
///<summary> | |
///Gets or sets the code-page identifier for the current session. | |
///</summary> | |
/// | |
///<returns> | |
///The code-page identifier for the current session. | |
///</returns> | |
/// | |
public int CodePage { | |
get { return codePage; } | |
set { codePage = value; } | |
} | |
///<summary> | |
///Gets a collection of objects declared by <object Runat="Server" Scope="Session"/> tags within the ASP.NET application file Global.asax. | |
///</summary> | |
/// | |
///<returns> | |
///An <see cref="T:System.Web.HttpStaticObjectsCollection"></see> containing objects declared in the Global.asax file. | |
///</returns> | |
/// | |
public HttpStaticObjectsCollection StaticObjects { | |
get { return staticObjects; } | |
} | |
///<summary> | |
///Gets or sets a session-state item value by name. | |
///</summary> | |
/// | |
///<returns> | |
///The session-state item value specified in the name parameter. | |
///</returns> | |
/// | |
///<param name="name">The key name of the session-state item value. </param> | |
public object this[string name] { | |
get { return BaseGet(name); } | |
set { BaseSet(name, value); } | |
} | |
///<summary> | |
///Gets or sets a session-state item value by numerical index. | |
///</summary> | |
/// | |
///<returns> | |
///The session-state item value specified in the index parameter. | |
///</returns> | |
/// | |
///<param name="index">The numerical index of the session-state item value. </param> | |
public object this[int index] { | |
get { return BaseGet(index); } | |
set { BaseSet(index, value); } | |
} | |
///<summary> | |
///Gets an object that can be used to synchronize access to the collection of session-state values. | |
///</summary> | |
/// | |
///<returns> | |
///An object that can be used to synchronize access to the collection. | |
///</returns> | |
/// | |
public object SyncRoot { | |
get { return syncRoot; } | |
} | |
///<summary> | |
///Gets a value indicating whether access to the collection of session-state values is synchronized (thread safe). | |
///</summary> | |
///<returns> | |
///true if access to the collection is synchronized (thread safe); otherwise, false. | |
///</returns> | |
/// | |
public bool IsSynchronized { | |
get { return true; } | |
} | |
///<summary> | |
///Gets a value indicating whether the session is read-only. | |
///</summary> | |
/// | |
///<returns> | |
///true if the session is read-only; otherwise, false. | |
///</returns> | |
/// | |
bool IHttpSessionState.IsReadOnly { | |
get { return true; } | |
} | |
} | |
/// <summary> | |
/// Sets the referer for the request. Uses a fluent interface. | |
/// </summary> | |
/// <param name="referer"></param> | |
/// <returns></returns> | |
public HttpSimulator SetReferer(Uri referer) { | |
if (this.workerRequest != null) | |
this.workerRequest.SetReferer(referer); | |
this._referer = referer; | |
return this; | |
} | |
/// <summary> | |
/// Sets a form variable. | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
/// <returns></returns> | |
public HttpSimulator SetFormVariable(string name, string value) { | |
//TODO: Change this ordering requirement. | |
if (this.workerRequest != null) | |
throw new InvalidOperationException("Cannot set form variables after calling Simulate()."); | |
_formVars.Add(name, value); | |
return this; | |
} | |
/// <summary> | |
/// Sets a header value. | |
/// </summary> | |
/// <param name="name"></param> | |
/// <param name="value"></param> | |
/// <returns></returns> | |
public HttpSimulator SetHeader(string name, string value) { | |
//TODO: Change this ordering requirement. | |
if (this.workerRequest != null) | |
throw new InvalidOperationException("Cannot set headers after calling Simulate()."); | |
_headers.Add(name, value); | |
return this; | |
} | |
private void ParseRequestUrl(Uri url) { | |
if (url == null) | |
return; | |
this.host = url.Host; | |
this.port = url.Port; | |
this.localPath = url.LocalPath; | |
this._page = StripPrecedingSlashes(RightAfter(url.LocalPath, ApplicationPath)); | |
this.physicalPath = Path.Combine(this.physicalApplicationPath, this._page.Replace("/", @"\")); | |
} | |
static string RightAfter(string original, string search) { | |
if (search.Length > original.Length || search.Length == 0) | |
return original; | |
int searchIndex = original.IndexOf(search, 0, StringComparison.InvariantCultureIgnoreCase); | |
if (searchIndex < 0) | |
return original; | |
return original.Substring(original.IndexOf(search) + search.Length); | |
} | |
public string Host { | |
get { return this.host; } | |
} | |
private string host; | |
public string LocalPath { | |
get { return this.localPath; } | |
} | |
private string localPath; | |
public int Port { | |
get { return this.port; } | |
} | |
private int port; | |
/// <summary> | |
/// Portion of the URL after the application. | |
/// </summary> | |
public string Page { | |
get { return this._page; } | |
} | |
private string _page; | |
/// <summary> | |
/// The same thing as the IIS Virtual directory. It's | |
/// what gets returned by Request.ApplicationPath. | |
/// </summary> | |
public string ApplicationPath { | |
get { return this.applicationPath; } | |
set { | |
this.applicationPath = value ?? "/"; | |
this.applicationPath = NormalizeSlashes(this.applicationPath); | |
} | |
} | |
private string applicationPath = "/"; | |
/// <summary> | |
/// Physical path to the application (used for simulation purposes). | |
/// </summary> | |
public string PhysicalApplicationPath { | |
get { return this.physicalApplicationPath; } | |
set { | |
this.physicalApplicationPath = value ?? defaultPhysicalAppPath; | |
//strip trailing backslashes. | |
this.physicalApplicationPath = StripTrailingBackSlashes(this.physicalApplicationPath) + @"\"; | |
} | |
} | |
private string physicalApplicationPath = defaultPhysicalAppPath; | |
/// <summary> | |
/// Physical path to the requested file (used for simulation purposes). | |
/// </summary> | |
public string PhysicalPath { | |
get { return this.physicalPath; } | |
} | |
private string physicalPath = defaultPhysicalAppPath; | |
public TextWriter ResponseWriter { | |
get { return this.responseWriter; } | |
set { this.responseWriter = value; } | |
} | |
/// <summary> | |
/// Returns the text from the response to the simulated request. | |
/// </summary> | |
public string ResponseText { | |
get { return (builder ?? new StringBuilder()).ToString(); } | |
} | |
private TextWriter responseWriter; | |
public SimulatedHttpRequest WorkerRequest { | |
get { return this.workerRequest; } | |
} | |
private SimulatedHttpRequest workerRequest; | |
private static string ExtractQueryStringPart(Uri url) { | |
string query = url.Query ?? string.Empty; | |
if (query.StartsWith("?")) | |
return query.Substring(1); | |
return query; | |
} | |
void SetHttpRuntimeInternals() { | |
//We cheat by using reflection. | |
// get singleton property value | |
HttpRuntime runtime = ReflectionHelper.GetStaticFieldValue<HttpRuntime>("_theRuntime", typeof(HttpRuntime)); | |
// set app path property value | |
ReflectionHelper.SetPrivateInstanceFieldValue("_appDomainAppPath", runtime, PhysicalApplicationPath); | |
// set app virtual path property value | |
string vpathTypeName = | |
"System.Web.VirtualPath, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; | |
object virtualPath = | |
ReflectionHelper.Instantiate(vpathTypeName, new Type[] {typeof(string)}, new object[] {ApplicationPath}); | |
ReflectionHelper.SetPrivateInstanceFieldValue("_appDomainAppVPath", runtime, virtualPath); | |
// set codegen dir property value | |
ReflectionHelper.SetPrivateInstanceFieldValue("_codegenDir", runtime, PhysicalApplicationPath); | |
HostingEnvironment environment = GetHostingEnvironment(); | |
ReflectionHelper.SetPrivateInstanceFieldValue("_appPhysicalPath", environment, PhysicalApplicationPath); | |
ReflectionHelper.SetPrivateInstanceFieldValue("_appVirtualPath", environment, virtualPath); | |
ReflectionHelper.SetPrivateInstanceFieldValue("_configMapPath", environment, new ConfigMapPath(this)); | |
} | |
protected static HostingEnvironment GetHostingEnvironment() { | |
HostingEnvironment environment; | |
try { | |
environment = new HostingEnvironment(); | |
} | |
catch (InvalidOperationException) { | |
//Shoot, we need to grab it via reflection. | |
environment = | |
ReflectionHelper.GetStaticFieldValue<HostingEnvironment>("_theHostingEnvironment", | |
typeof(HostingEnvironment)); | |
} | |
return environment; | |
} | |
#region --- Text Manipulation Methods for slashes --- | |
protected static string NormalizeSlashes(string s) { | |
if (String.IsNullOrEmpty(s) || s == "/") | |
return "/"; | |
s = s.Replace(@"\", "/"); | |
//Reduce multiple slashes in row to single. | |
string normalized = Regex.Replace(s, "(/)/+", "$1"); | |
//Strip left. | |
normalized = StripPrecedingSlashes(normalized); | |
//Strip right. | |
normalized = StripTrailingSlashes(normalized); | |
return "/" + normalized; | |
} | |
protected static string StripPrecedingSlashes(string s) { | |
return Regex.Replace(s, "^/*(.*)", "$1"); | |
} | |
protected static string StripTrailingSlashes(string s) { | |
return Regex.Replace(s, "(.*)/*$", "$1", RegexOptions.RightToLeft); | |
} | |
protected static string StripTrailingBackSlashes(string s) { | |
if (String.IsNullOrEmpty(s)) | |
return string.Empty; | |
return Regex.Replace(s, @"(.*)\\*$", "$1", RegexOptions.RightToLeft); | |
} | |
#endregion | |
internal class ConfigMapPath : IConfigMapPath { | |
private HttpSimulator _requestSimulation; | |
public ConfigMapPath(HttpSimulator simulation) { | |
_requestSimulation = simulation; | |
} | |
public string GetMachineConfigFilename() { | |
throw new NotImplementedException(); | |
} | |
public string GetRootWebConfigFilename() { | |
throw new NotImplementedException(); | |
} | |
public void GetPathConfigFilename(string siteID, string path, out string directory, out string baseName) { | |
throw new NotImplementedException(); | |
} | |
public void GetDefaultSiteNameAndID(out string siteName, out string siteID) { | |
throw new NotImplementedException(); | |
} | |
public void ResolveSiteArgument(string siteArgument, out string siteName, out string siteID) { | |
throw new NotImplementedException(); | |
} | |
public string MapPath(string siteID, string path) { | |
if (path.ToLowerInvariant().Equals("/bin")) { | |
return _requestSimulation.appBinPath; | |
} | |
string page = StripPrecedingSlashes(RightAfter(path, _requestSimulation.ApplicationPath)); | |
return Path.Combine(_requestSimulation.PhysicalApplicationPath, page.Replace("/", @"\")); | |
} | |
public string GetAppPathForPath(string siteID, string path) { | |
return _requestSimulation.ApplicationPath; | |
} | |
} | |
///<summary> | |
///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. | |
///</summary> | |
///<filterpriority>2</filterpriority> | |
public void Dispose() { | |
if (HttpContext.Current != null) { | |
HttpContext.Current = null; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Specialized; | |
using System.Reflection; | |
using System.Web; | |
using System.Web.Hosting; | |
using MbUnit.Framework; | |
using Subtext.TestLibrary; | |
namespace UnitTests.SUbtext | |
{ | |
[TestFixture] | |
public class HttpSimulatorTests | |
{ | |
internal class TestHttpHandler : IHttpHandler | |
{ | |
public void ProcessRequest(HttpContext context) | |
{ | |
string physicalPath = context.Request.MapPath("/MyHandler.ashx"); | |
string username = context.Request.Form["username"]; | |
string id = context.Request.QueryString["id"]; | |
string referer = context.Request.UrlReferrer.ToString(); | |
//Imagine, if you will, a bunch of complex interesting | |
//and fascinating logic here. | |
context.Response.Write(physicalPath + ":" + username + ":" + id + ":" + referer); | |
} | |
public bool IsReusable | |
{ | |
get { return true; } | |
} | |
} | |
[Test] | |
public void CanGetSetSession() | |
{ | |
using (new HttpSimulator("/", @"c:\inetpub\").SimulateRequest()) | |
{ | |
HttpContext.Current.Session["Test"] = "Success"; | |
Assert.AreEqual("Success", HttpContext.Current.Session["Test"], "Was not able to retrieve session variable."); | |
} | |
} | |
[Test] | |
public void CanGetSetApplicationVariables() | |
{ | |
using (new HttpSimulator("/", @"c:\inetpub\").SimulateRequest()) | |
{ | |
HttpContext.Current.Application["Test"] = "Success"; | |
Assert.AreEqual("Success", HttpContext.Current.Application["Test"], "Was not able to retrieve application variable."); | |
} | |
} | |
[Test] | |
public void TestHttpHandlerWritesCorrectResponse() | |
{ | |
using (HttpSimulator simulator = new HttpSimulator("/", @"c:\inetpub\")) | |
{ | |
simulator.SetFormVariable("username", "phil") | |
.SetReferer(new Uri("http://example.com/1/")) | |
.SimulateRequest(new Uri("http://localhost/MyHandler.ashx?id=1234")); | |
TestHttpHandler handler = new TestHttpHandler(); | |
handler.ProcessRequest(HttpContext.Current); | |
HttpContext.Current.Response.Flush(); | |
string expected = @"c:\inetpub\MyHandler.ashx:phil:1234:http://example.com/1/"; | |
Assert.AreEqual(expected, simulator.ResponseText, "The Expected Response is all wrong."); | |
} //HttpContext.Current is set to null again. | |
} | |
[Test] | |
public void CanDispose() | |
{ | |
using (HttpSimulator simulator = new HttpSimulator()) | |
{ | |
simulator.SimulateRequest(); | |
Assert.IsNotNull(HttpContext.Current); | |
} | |
Assert.IsNull(HttpContext.Current); | |
} | |
[RowTest] | |
[Row("http://localhost/Test/Default.aspx", "/Test", "/Test")] | |
[Row("http://localhost/Test/Default.aspx", "/Test/", "/Test")] | |
[Row("http://localhost/Test/Default.aspx", "//Test//", "/Test")] | |
[Row("http://localhost/Test/Subtest/Default.aspx", "/Test", "/Test")] | |
[Row("http://localhost/Test/Subtest/Default.aspx", "/Test/", "/Test")] | |
[Row("http://localhost/Test/Subtest/Default.aspx", "//Test//", "/Test")] | |
[Row("http://localhost/Test/Default.aspx", "", "/")] | |
[Row("http://localhost/Test/Default.aspx", "/", "/")] | |
[Row("http://localhost/Test/Default.aspx", null, "/")] | |
public void CanSetApplicationPathCorrectly(string url, string appPath, string expectedAppPath) | |
{ | |
HttpSimulator simulator = new HttpSimulator(appPath, @"c:\inetpub\wwwroot\site1\test"); | |
Assert.AreEqual(expectedAppPath, simulator.ApplicationPath); | |
simulator.SimulateRequest(new Uri(url)); | |
Assert.AreEqual(expectedAppPath, HttpContext.Current.Request.ApplicationPath); | |
Assert.AreEqual(expectedAppPath, HttpRuntime.AppDomainAppVirtualPath); | |
Assert.AreEqual(expectedAppPath, HostingEnvironment.ApplicationVirtualPath); | |
} | |
[RowTest] | |
[Row("http://localhost/Test/default.aspx", "/Test", @"c:\projects\test", @"c:\projects\test\", @"c:\projects\test\default.aspx")] | |
[Row("http://localhost/Test/Subtest/default.aspx", "/Test", @"c:\projects\test", @"c:\projects\test\", @"c:\projects\test\Subtest\default.aspx")] | |
[Row("http://localhost/test/default.aspx", "/", @"c:\inetpub\wwwroot\", @"c:\inetpub\wwwroot\", @"c:\inetpub\wwwroot\test\default.aspx")] | |
[Row("http://localhost/test/default.aspx", "/", @"c:\inetpub\wwwroot", @"c:\inetpub\wwwroot\", @"c:\inetpub\wwwroot\test\default.aspx")] | |
public void CanSetAppPhysicalPathCorrectly(string url, string appPath, string appPhysicalPath, string expectedPhysicalAppPath, string expectedPhysicalPath) | |
{ | |
HttpSimulator simulator = new HttpSimulator(appPath, appPhysicalPath); | |
Assert.AreEqual(expectedPhysicalAppPath, simulator.PhysicalApplicationPath); | |
simulator.SimulateRequest(new Uri(url), HttpVerb.GET); | |
Assert.AreEqual(expectedPhysicalPath, simulator.PhysicalPath); | |
Assert.AreEqual(expectedPhysicalAppPath, HttpRuntime.AppDomainAppPath); | |
Assert.AreEqual(expectedPhysicalAppPath, HostingEnvironment.ApplicationPhysicalPath); | |
Assert.AreEqual(expectedPhysicalPath, HttpContext.Current.Request.PhysicalPath); | |
} | |
[Test] | |
public void CanGetQueryString() | |
{ | |
HttpSimulator simulator = new HttpSimulator(); | |
simulator.SimulateRequest(new Uri("http://localhost/Test.aspx?param1=value1¶m2=value2¶m3=value3")); | |
for (int i = 1; i <= 3; i++) | |
Assert.AreEqual("value" + i, HttpContext.Current.Request.QueryString["param" + i], "Could not find query string field 'param{0}'", i); | |
simulator.SimulateRequest(new Uri("http://localhost/Test.aspx?param1=new-value1¶m2=new-value2¶m3=new-value3¶m4=new-value4")); | |
for (int i = 1; i <= 4; i++) | |
Assert.AreEqual("new-value" + i, HttpContext.Current.Request.QueryString["param" + i], "Could not find query string field 'param{0}'", i); | |
simulator.SimulateRequest(new Uri("http://localhost/Test.aspx?")); | |
Assert.AreEqual(string.Empty, HttpContext.Current.Request.QueryString.ToString()); | |
Assert.AreEqual(0, HttpContext.Current.Request.QueryString.Count); | |
simulator.SimulateRequest(new Uri("http://localhost/Test.aspx")); | |
Assert.AreEqual(string.Empty, HttpContext.Current.Request.QueryString.ToString()); | |
Assert.AreEqual(0, HttpContext.Current.Request.QueryString.Count); | |
simulator.SimulateRequest(new Uri("http://localhost/Test.aspx?param-name")); | |
Assert.AreEqual("param-name", HttpContext.Current.Request.QueryString.ToString()); | |
Assert.AreEqual(1, HttpContext.Current.Request.QueryString.Count); | |
Assert.IsNull(HttpContext.Current.Request.QueryString["param-name"]); | |
} | |
[Test] | |
public void CanSimulateFormPost() | |
{ | |
using (HttpSimulator simulator = new HttpSimulator()) | |
{ | |
NameValueCollection form = new NameValueCollection(); | |
form.Add("Test1", "Value1"); | |
form.Add("Test2", "Value2"); | |
simulator.SimulateRequest(new Uri("http://localhost/Test.aspx"), form); | |
Assert.AreEqual("Value1", HttpContext.Current.Request.Form["Test1"]); | |
Assert.AreEqual("Value2", HttpContext.Current.Request.Form["Test2"]); | |
} | |
using (HttpSimulator simulator = new HttpSimulator()) | |
{ | |
simulator.SetFormVariable("Test1", "Value1") | |
.SetFormVariable("Test2", "Value2") | |
.SimulateRequest(new Uri("http://localhost/Test.aspx")); | |
Assert.AreEqual("Value1", HttpContext.Current.Request.Form["Test1"]); | |
Assert.AreEqual("Value2", HttpContext.Current.Request.Form["Test2"]); | |
} | |
} | |
[Test] | |
public void CanGetResponse() | |
{ | |
HttpSimulator simulator = new HttpSimulator(); | |
simulator.SimulateRequest(); | |
HttpContext.Current.Response.Write("Hello World!"); | |
HttpContext.Current.Response.Flush(); | |
Assert.AreEqual("Hello World!", simulator.ResponseText); | |
} | |
[Test] | |
public void CanGetReferer() | |
{ | |
HttpSimulator simulator = new HttpSimulator(); | |
simulator.SetReferer(new Uri("http://example.com/Blah.aspx")).SimulateRequest(); | |
Assert.AreEqual(new Uri("http://example.com/Blah.aspx"), HttpContext.Current.Request.UrlReferrer); | |
simulator = new HttpSimulator(); | |
simulator.SimulateRequest().SetReferer(new Uri("http://x.example.com/Blah.aspx")); | |
Assert.AreEqual(new Uri("http://x.example.com/Blah.aspx"), HttpContext.Current.Request.UrlReferrer); | |
} | |
[RowTest] | |
[Row("http://localhost:60653/Test.aspx", null, null, "localhost", 60653, "/", "/Test.aspx", @"c:\InetPub\wwwRoot\")] | |
[Row("http://localhost:60653/Test.aspx?test=true", null, null, "localhost", 60653, "/", "/Test.aspx", @"c:\InetPub\wwwRoot\")] | |
[Row("http://localhost:60653/Test.aspx", "/", @"c:\InetPub\wwwRoot\", "localhost", 60653, "/", "/Test.aspx", @"c:\InetPub\wwwRoot\")] | |
[Row("http://localhost:60653/Test/Test.aspx", "/", @"c:\InetPub\wwwRoot\", "localhost", 60653, "/", "/Test/Test.aspx", @"c:\InetPub\wwwRoot\")] | |
[Row("http://localhost:60653/AppPath/Test.aspx", "/AppPath", @"c:\InetPub\wwwRoot\AppPath\", "localhost", 60653, "/AppPath", "/AppPath/Test.aspx", @"c:\InetPub\wwwRoot\AppPath\")] | |
[Row("http://localhost:60653/AppPath/Test.aspx", "/AppPath/", @"c:\InetPub\wwwRoot\AppPath\", "localhost", 60653, "/AppPath", "/AppPath/Test.aspx", @"c:\InetPub\wwwRoot\AppPath\")] | |
public void CanParseRequestUrl(string url, string appPath, string physicalPath, string expectedHost, int expectedPort, string expectedAppPath, string expectedPage, string expectedAppDomainAppPath) | |
{ | |
HttpSimulator simulator = new HttpSimulator(appPath, physicalPath); | |
Assert.AreEqual(expectedAppPath, simulator.ApplicationPath); | |
Assert.AreEqual(expectedAppDomainAppPath, simulator.PhysicalApplicationPath); | |
} | |
[RowTest] | |
[Row("http://localhost/AppPath/default.aspx", "/AppPath", "/AppPath/default.aspx")] | |
[Row("http://localhost/AppPath/default.aspx", "/", "/AppPath/default.aspx")] | |
public void CanGetLocalPathCorrectly(string url, string appPath, string expectedLocalPath) | |
{ | |
HttpSimulator simulator = new HttpSimulator(appPath, @"c:\inetpub\wwwroot\AppPath\"); | |
simulator.SimulateRequest(new Uri(url)); | |
Assert.AreEqual(expectedLocalPath, HttpContext.Current.Request.Path); | |
Assert.AreEqual(expectedLocalPath, HttpContext.Current.Request.Url.LocalPath); | |
} | |
[RowTest] | |
[Row("http://localhost:60653/Test.aspx", null, null, "localhost", 60653, "/", "/Test.aspx", @"c:\InetPub\wwwRoot\")] | |
[Row("http://localhost:60653/Test.aspx", "/", @"c:\InetPub\wwwRoot\", "localhost", 60653, "/", "/Test.aspx", @"c:\InetPub\wwwRoot\")] | |
[Row("http://localhost:60653/Test/Test.aspx", "/", @"c:\InetPub\wwwRoot\", "localhost", 60653, "/", "/Test/Test.aspx", @"c:\InetPub\wwwRoot\")] | |
[Row("http://localhost:60653/AppPath/Test.aspx", "/AppPath", @"c:\InetPub\wwwRoot\AppPath\", "localhost", 60653, "/AppPath", "/AppPath/Test.aspx", @"c:\InetPub\wwwRoot\AppPath\")] | |
[Row("http://localhost:60653/AppPath/Test.aspx", "/AppPath/", @"c:\InetPub\wwwRoot\AppPath\", "localhost", 60653, "/AppPath", "/AppPath/Test.aspx", @"c:\InetPub\wwwRoot\AppPath\")] | |
public void CanSimulateRequest(string url, string appPath, string physicalPath, string expectedHost, int expectedPort, string expectedAppPath, string expectedLocalPath, string expectedPhysicalPath) | |
{ | |
HttpSimulator simulator = new HttpSimulator(appPath, physicalPath); | |
simulator.SimulateRequest(new Uri(url)); | |
Assert.AreEqual(expectedHost, HttpContext.Current.Request.Url.Host); | |
Assert.AreEqual(expectedPort, HttpContext.Current.Request.Url.Port); | |
Assert.AreEqual(expectedAppPath, HttpContext.Current.Request.ApplicationPath); | |
Assert.AreEqual(expectedPhysicalPath, HttpContext.Current.Request.PhysicalApplicationPath); | |
Assert.AreEqual(expectedLocalPath, HttpContext.Current.Request.Url.LocalPath); | |
} | |
[RowTest] | |
[Row("/", "/", @"c:\inetpub\wwwroot\")] | |
[Row("/Test/Test.aspx", "/", @"c:\inetpub\wwwroot\Test\Test.aspx")] | |
[Row("/Test/Blah/Test.aspx", "/", @"c:\inetpub\wwwroot\Test\Blah\Test.aspx")] | |
[Row("/Test", "/Test", @"c:\inetpub\wwwroot")] | |
[Row("/Test/", "/Test", @"c:\inetpub\wwwroot\")] | |
public void CanMapPath(string virtualPath, string appPath, string expectedMapPath) | |
{ | |
Uri url = new Uri("http://localhost/Test/Test.aspx"); | |
HttpSimulator simulator = new HttpSimulator(appPath, @"c:\inetpub\wwwroot\"); | |
simulator.SimulateRequest(url); | |
//Create a virtual path object. | |
object vpath = ReflectionHelper.Instantiate("System.Web.VirtualPath, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", new Type[] { typeof(string) }, virtualPath); | |
Assert.IsNotNull(vpath); | |
HostingEnvironment environment = HttpSimulatorTester.CallGetEnvironment(); | |
string vpathString = ReflectionHelper.InvokeProperty<string>(vpath, "VirtualPathString"); | |
object appVirtPath = ReflectionHelper.GetPrivateInstanceFieldValue<object>("_appVirtualPath", environment); | |
Assert.IsNotNull(appVirtPath); | |
Console.WriteLine("VPATH: " + vpath); | |
Console.WriteLine("App-VPATH: " + appVirtPath); | |
Console.WriteLine("vpath.VirtualPathString == '{0}'", vpathString); | |
string mapping = ReflectionHelper.InvokeNonPublicMethod<string>(typeof(HostingEnvironment), "GetVirtualPathToFileMapping", vpath); | |
Console.WriteLine("GetVirtualPathToFileMapping: --->{0}<---", (mapping ?? "{NULL}")); | |
object o = ReflectionHelper.GetPrivateInstanceFieldValue<object>("_configMapPath", environment); | |
Console.WriteLine("_configMapPath: {0}", o ?? "{null}"); | |
string mappedPath = ReflectionHelper.InvokeNonPublicMethod<string>(environment, "MapPathActual", vpath, false); | |
Console.WriteLine("MAPPED: " + mappedPath); | |
Assert.AreEqual(expectedMapPath, HttpContext.Current.Request.MapPath(virtualPath)); | |
} | |
[Test] | |
public void CanInstantiateVirtualPath() | |
{ | |
Type virtualPathType = Type.GetType("System.Web.VirtualPath, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true); | |
ConstructorInfo constructor = virtualPathType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null); | |
Assert.IsNotNull(constructor); | |
} | |
[Test] | |
public void CanGetHostingEnvironment() | |
{ | |
HostingEnvironment environment = HttpSimulatorTester.CallGetEnvironment(); | |
Assert.IsNotNull(environment); | |
environment = HttpSimulatorTester.CallGetEnvironment(); | |
Assert.IsNotNull(environment); | |
} | |
[RowTest] | |
[Row("/", "/")] | |
[Row("", "/")] | |
[Row("/test", "/test")] | |
[Row("test/", "/test")] | |
[Row("/test/", "/test")] | |
[Row("/test/////", "/test")] | |
[Row("////test/", "/test")] | |
[Row("/test/test////", "/test/test")] | |
[Row("/////test/test////", "/test/test")] | |
[Row("/////test///test////", "/test/test")] | |
public void CanNormalizeSlashes(string s, string expected) | |
{ | |
Assert.AreEqual(expected, HttpSimulatorTester.CallNormalizeSlashes(s)); | |
} | |
[Test] | |
public void CanStripTrailing() | |
{ | |
Assert.AreEqual(@"c:\blah\blah2", HttpSimulatorTester.CallStripTrailingBackSlashes(@"c:\blah\blah2\")); | |
} | |
} | |
internal class HttpSimulatorTester : HttpSimulator | |
{ | |
public static string CallNormalizeSlashes(string s) | |
{ | |
return NormalizeSlashes(s); | |
} | |
public static string CallStripTrailingBackSlashes(string s) | |
{ | |
return StripTrailingBackSlashes(s); | |
} | |
public static HostingEnvironment CallGetEnvironment() | |
{ | |
return GetHostingEnvironment(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
namespace Subtext.TestLibrary | |
{ | |
/// <summary> | |
/// Helper class to simplify common reflection tasks. | |
/// </summary> | |
public sealed class ReflectionHelper | |
{ | |
private ReflectionHelper() {} | |
/// <summary> | |
/// Returns the value of the private member specified. | |
/// </summary> | |
/// <param name="fieldName">Name of the member.</param> | |
/// /// <param name="type">Type of the member.</param> | |
public static T GetStaticFieldValue<T>(string fieldName, Type type) | |
{ | |
FieldInfo field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static); | |
if(field != null) | |
{ | |
return (T)field.GetValue(type); | |
} | |
return default(T); | |
} | |
/// <summary> | |
/// Returns the value of the private member specified. | |
/// </summary> | |
/// <param name="fieldName">Name of the member.</param> | |
/// <param name="typeName"></param> | |
public static T GetStaticFieldValue<T>(string fieldName, string typeName) | |
{ | |
Type type = Type.GetType(typeName, true); | |
FieldInfo field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static); | |
if (field != null) | |
{ | |
return (T)field.GetValue(type); | |
} | |
return default(T); | |
} | |
/// <summary> | |
/// Sets the value of the private static member. | |
/// </summary> | |
/// <param name="fieldName"></param> | |
/// <param name="type"></param> | |
/// <param name="value"></param> | |
public static void SetStaticFieldValue<T>(string fieldName, Type type, T value) | |
{ | |
FieldInfo field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static); | |
if (field == null) | |
throw new ArgumentException(string.Format("Could not find the private instance field '{0}'", fieldName)); | |
field.SetValue(null, value); | |
} | |
/// <summary> | |
/// Sets the value of the private static member. | |
/// </summary> | |
/// <param name="fieldName"></param> | |
/// <param name="typeName"></param> | |
/// <param name="value"></param> | |
public static void SetStaticFieldValue<T>(string fieldName, string typeName, T value) | |
{ | |
Type type = Type.GetType(typeName, true); | |
FieldInfo field = type.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static); | |
if (field == null) | |
throw new ArgumentException(string.Format("Could not find the private instance field '{0}'", fieldName)); | |
field.SetValue(null, value); | |
} | |
/// <summary> | |
/// Returns the value of the private member specified. | |
/// </summary> | |
/// <param name="fieldName">Name of the member.</param> | |
/// <param name="source">The object that contains the member.</param> | |
public static T GetPrivateInstanceFieldValue<T>(string fieldName, object source) | |
{ | |
FieldInfo field = source.GetType().GetField(fieldName, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance); | |
if(field != null) | |
{ | |
return (T)field.GetValue(source); | |
} | |
return default(T); | |
} | |
/// <summary> | |
/// Returns the value of the private member specified. | |
/// </summary> | |
/// <param name="memberName">Name of the member.</param> | |
/// <param name="source">The object that contains the member.</param> | |
/// <param name="value">The value to set the member to.</param> | |
public static void SetPrivateInstanceFieldValue(string memberName, object source, object value) | |
{ | |
FieldInfo field = source.GetType().GetField(memberName, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance); | |
if (field == null) | |
throw new ArgumentException(string.Format("Could not find the private instance field '{0}'",memberName)); | |
field.SetValue(source, value); | |
} | |
public static object Instantiate(string typeName) | |
{ | |
return Instantiate(typeName, null, null); | |
} | |
public static object Instantiate(string typeName, Type[] constructorArgumentTypes, params object[] constructorParameterValues) | |
{ | |
return Instantiate(Type.GetType(typeName, true), constructorArgumentTypes, constructorParameterValues); | |
} | |
public static object Instantiate(Type type, Type[] constructorArgumentTypes, params object[] constructorParameterValues) | |
{ | |
ConstructorInfo constructor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, constructorArgumentTypes, null); | |
return constructor.Invoke(constructorParameterValues); | |
} | |
/// <summary> | |
/// Invokes a non-public static method. | |
/// </summary> | |
/// <typeparam name="TReturn"></typeparam> | |
/// <param name="type"></param> | |
/// <param name="methodName"></param> | |
/// <param name="parameters"></param> | |
/// <returns></returns> | |
public static TReturn InvokeNonPublicMethod<TReturn>(Type type, string methodName, params object[] parameters) | |
{ | |
Type[] paramTypes = Array.ConvertAll(parameters, new Converter<object, Type>(delegate(object o) { return o.GetType(); })); | |
MethodInfo method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Static, null, paramTypes, null); | |
if (method == null) | |
throw new ArgumentException(string.Format("Could not find a method with the name '{0}'", methodName), "method"); | |
return (TReturn)method.Invoke(null, parameters); | |
} | |
public static TReturn InvokeNonPublicMethod<TReturn>(object source, string methodName, params object[] parameters) | |
{ | |
Type[] paramTypes = Array.ConvertAll(parameters, new Converter<object, Type>(delegate(object o) { return o.GetType(); })); | |
MethodInfo method = source.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, paramTypes, null); | |
if (method == null) | |
throw new ArgumentException(string.Format("Could not find a method with the name '{0}'", methodName), "method"); | |
return (TReturn)method.Invoke(source, parameters); | |
} | |
public static TReturn InvokeProperty<TReturn>(object source, string propertyName) | |
{ | |
PropertyInfo propertyInfo = source.GetType().GetProperty(propertyName); | |
if (propertyInfo == null) | |
throw new ArgumentException(string.Format("Could not find a propertyName with the name '{0}'", propertyName), "propertyName"); | |
return (TReturn)propertyInfo.GetValue(source, null); | |
} | |
public static TReturn InvokeNonPublicProperty<TReturn>(object source, string propertyName) | |
{ | |
PropertyInfo propertyInfo = source.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance, null, typeof(TReturn), new Type[0], null); | |
if (propertyInfo == null) | |
throw new ArgumentException(string.Format("Could not find a propertyName with the name '{0}'", propertyName), "propertyName"); | |
return (TReturn) propertyInfo.GetValue(source, null); | |
} | |
public static object InvokeNonPublicProperty(object source, string propertyName) | |
{ | |
PropertyInfo propertyInfo = source.GetType().GetProperty(propertyName, BindingFlags.NonPublic | BindingFlags.Instance); | |
if (propertyInfo == null) | |
throw new ArgumentException(string.Format("Could not find a propertyName with the name '{0}'", propertyName), "propertyName"); | |
return propertyInfo.GetValue(source, null); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region Disclaimer/Info | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
// Subtext WebLog | |
// | |
// Subtext is an open source weblog system that is a fork of the .TEXT | |
// weblog system. | |
// | |
// For updated news and information please visit http://subtextproject.com/ | |
// Subtext is hosted at SourceForge at http://sourceforge.net/projects/subtext | |
// The development mailing list is at [email protected] | |
// | |
// This project is licensed under the BSD license. See the License.txt file for more information. | |
/////////////////////////////////////////////////////////////////////////////////////////////////// | |
#endregion | |
using System; | |
using System.Collections.Specialized; | |
using System.IO; | |
using System.Text; | |
using System.Web.Hosting; | |
namespace Subtext.TestLibrary | |
{ | |
/// <summary> | |
/// Used to simulate an HttpRequest. | |
/// </summary> | |
public class SimulatedHttpRequest : SimpleWorkerRequest | |
{ | |
Uri _referer; | |
string _host; | |
string _verb; | |
int _port; | |
string _physicalFilePath; | |
/// <summary> | |
/// Creates a new <see cref="SimulatedHttpRequest"/> instance. | |
/// </summary> | |
/// <param name="applicationPath">App virtual dir.</param> | |
/// <param name="physicalAppPath">Physical Path to the app.</param> | |
/// <param name="physicalFilePath">Physical Path to the file.</param> | |
/// <param name="page">The Part of the URL after the application.</param> | |
/// <param name="query">Query.</param> | |
/// <param name="output">Output.</param> | |
/// <param name="host">Host.</param> | |
/// <param name="port">Port to request.</param> | |
/// <param name="verb">The HTTP Verb to use.</param> | |
public SimulatedHttpRequest(string applicationPath, string physicalAppPath, string physicalFilePath, string page, string query, TextWriter output, string host, int port, string verb) : base(applicationPath, physicalAppPath, page, query, output) | |
{ | |
if (host == null) | |
throw new ArgumentNullException("host", "Host cannot be null."); | |
if(host.Length == 0) | |
throw new ArgumentException("Host cannot be empty.", "host"); | |
if (applicationPath == null) | |
throw new ArgumentNullException("applicationPath", "Can't create a request with a null application path. Try empty string."); | |
_host = host; | |
_verb = verb; | |
_port = port; | |
_physicalFilePath = physicalFilePath; | |
} | |
internal void SetReferer(Uri referer) | |
{ | |
_referer = referer; | |
} | |
/// <summary> | |
/// Returns the specified member of the request header. | |
/// </summary> | |
/// <returns> | |
/// The HTTP verb returned in the request | |
/// header. | |
/// </returns> | |
public override string GetHttpVerbName() | |
{ | |
return _verb; | |
} | |
/// <summary> | |
/// Gets the name of the server. | |
/// </summary> | |
/// <returns></returns> | |
public override string GetServerName() | |
{ | |
return _host; | |
} | |
public override int GetLocalPort() | |
{ | |
return this._port; | |
} | |
/// <summary> | |
/// Gets the headers. | |
/// </summary> | |
/// <value>The headers.</value> | |
public NameValueCollection Headers | |
{ | |
get | |
{ | |
return this.headers; | |
} | |
} | |
private NameValueCollection headers = new NameValueCollection(); | |
/// <summary> | |
/// Gets the format exception. | |
/// </summary> | |
/// <value>The format exception.</value> | |
public NameValueCollection Form | |
{ | |
get | |
{ | |
return formVariables; | |
} | |
} | |
private NameValueCollection formVariables = new NameValueCollection(); | |
/// <summary> | |
/// Get all nonstandard HTTP header name-value pairs. | |
/// </summary> | |
/// <returns>An array of header name-value pairs.</returns> | |
public override string[][] GetUnknownRequestHeaders() | |
{ | |
if(this.headers == null || this.headers.Count == 0) | |
{ | |
return null; | |
} | |
string[][] headersArray = new string[this.headers.Count][]; | |
for(int i = 0; i < this.headers.Count; i++) | |
{ | |
headersArray[i] = new string[2]; | |
headersArray[i][0] = this.headers.Keys[i]; | |
headersArray[i][1] = this.headers[i]; | |
} | |
return headersArray; | |
} | |
public override string GetKnownRequestHeader(int index) | |
{ | |
if (index == 0x24) | |
return _referer == null ? string.Empty : _referer.ToString(); | |
if (index == 12 && this._verb == "POST") | |
return "application/x-www-form-urlencoded"; | |
return base.GetKnownRequestHeader(index); | |
} | |
/// <summary> | |
/// Returns the virtual path to the currently executing | |
/// server application. | |
/// </summary> | |
/// <returns> | |
/// The virtual path of the current application. | |
/// </returns> | |
public override string GetAppPath() | |
{ | |
string appPath = base.GetAppPath(); | |
return appPath; | |
} | |
public override string GetAppPathTranslated() | |
{ | |
string path = base.GetAppPathTranslated(); | |
return path; | |
} | |
public override string GetUriPath() | |
{ | |
string uriPath = base.GetUriPath(); | |
return uriPath; | |
} | |
public override string GetFilePathTranslated() | |
{ | |
return _physicalFilePath; | |
} | |
/// <summary> | |
/// Reads request data from the client (when not preloaded). | |
/// </summary> | |
/// <returns>The number of bytes read.</returns> | |
public override byte[] GetPreloadedEntityBody() | |
{ | |
string formText = string.Empty; | |
foreach(string key in this.formVariables.Keys) | |
{ | |
formText += string.Format("{0}={1}&", key, this.formVariables[key]); | |
} | |
return Encoding.UTF8.GetBytes(formText); | |
} | |
/// <summary> | |
/// Returns a value indicating whether all request data | |
/// is available and no further reads from the client are required. | |
/// </summary> | |
/// <returns> | |
/// <see langword="true"/> if all request data is available; otherwise, | |
/// <see langword="false"/>. | |
/// </returns> | |
public override bool IsEntireEntityBodyIsPreloaded() | |
{ | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment