Skip to content

Instantly share code, notes, and snippets.

@emiaj
Created July 8, 2011 00:33
Show Gist options
  • Select an option

  • Save emiaj/1070863 to your computer and use it in GitHub Desktop.

Select an option

Save emiaj/1070863 to your computer and use it in GitHub Desktop.
Hijacking Request indexer.
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using ZG.Utilities.Urls;
using ZG.Utilities.Web;
namespace ZG.Mvc.Engines.Endpoints
{
public class EngineHttpContextBuilder : IEngineHttpContextBuilder
{
private readonly IHttpContextFactory _factory;
private readonly IRequestSubstitutesBuilder _builder;
private readonly HttpContextBase _inner;
private readonly IUrlPrefixer _prefixer;
public EngineHttpContextBuilder(IHttpContextFactory factory, HttpContextBase inner, IRequestSubstitutesBuilder builder, IUrlPrefixer prefixer)
{
_factory = factory;
_inner = inner;
_builder = builder;
_prefixer = prefixer;
}
public HttpContextBase Build(string url, bool targeted)
{
const string queryStringName = "QUERY_STRING";
var serverVariables = new NameValueCollection(_inner.Request.ServerVariables);
serverVariables.Remove(queryStringName);
var requestParams = new NameValueCollection(serverVariables);
_inner.Request.Cookies.AllKeys.Each(key => requestParams[key] = _inner.Request.Cookies[key].Value);
var builder = _builder
.Add(x => x.AppRelativeCurrentExecutionFilePath, _prefixer.Root("~/").PrefixUrl(url))
.AddWhen(!targeted, x => x.HttpMethod, HttpVerbs.Get)
.AddWhen(!targeted, x => x.ServerVariables, serverVariables)
.AddWhen(!targeted, x => x.Params, requestParams)
.AddWhen(!targeted, x => x.Form, new NameValueCollection())
.AddWhen(!targeted, x => x.QueryString, new NameValueCollection());
var context = _factory.GetHttpContext(_inner, builder.Build());
return context;
}
}
public interface IEngineHttpContextBuilder
{
HttpContextBase Build(string url, bool targeted);
}
}
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
using Castle.DynamicProxy;
using FubuCore.Reflection;
namespace ZG.Utilities.Web
{
public interface IHttpContextFactory
{
HttpContextBase GetHttpContext(HttpContextBase innerContext,
IDictionary<string, object> requestPropertySubstitutes);
}
public class HttpContextFactory : IHttpContextFactory
{
private static readonly ProxyGenerator ProxyGenerator = new ProxyGenerator();
public HttpContextBase GetHttpContext(HttpContextBase innerContext,
IDictionary<string, object> requestPropertySubstitutes)
{
var interceptor = new HttpContextInterceptor(innerContext, requestPropertySubstitutes);
return ProxyGenerator.CreateClassProxy<HttpContextBase>(interceptor);
}
private class HttpContextInterceptor : IInterceptor
{
private readonly HttpContextBase _innerContext;
private readonly HttpRequestBase _requestProxy;
public HttpContextInterceptor(HttpContextBase innerContext,
IDictionary<string, object> requestPropertySubstitutes)
{
_innerContext = innerContext;
var interceptor = new HttpRequestInterceptor(innerContext.Request, requestPropertySubstitutes);
_requestProxy = ProxyGenerator.CreateClassProxy<HttpRequestBase>(interceptor);
}
public void Intercept(IInvocation invocation)
{
switch (invocation.Method.Name)
{
case "get_Request":
invocation.ReturnValue = _requestProxy;
break;
default:
invocation.ReturnValue = invocation.Method.Invoke(_innerContext, invocation.Arguments);
break;
}
}
}
private class HttpRequestInterceptor : IInterceptor
{
private readonly HttpRequestBase _innerRequest;
private readonly IDictionary<string, object> _propertySubstitutes;
public HttpRequestInterceptor(HttpRequestBase innerRequest, IDictionary<string, object> propertySubstitutes)
{
_innerRequest = innerRequest;
_propertySubstitutes = propertySubstitutes;
}
public void Intercept(IInvocation invocation)
{
var methodName = invocation.Method.Name;
var isPropertyGet = methodName.StartsWith("get_");
if (isPropertyGet)
{
var startIndex = "get_".Length;
var length = methodName.Length - startIndex;
var key = methodName.Substring(startIndex, length);
var containsKey = _propertySubstitutes.ContainsKey(key);
if (containsKey)
{
invocation.ReturnValue = _propertySubstitutes[key];
return;
}
}
if (methodName.Equals("get_Item"))
{
invocation.ReturnValue = InterceptIndexer(invocation.Arguments[0].ToString());
return;
}
invocation.ReturnValue = invocation.Method.Invoke(_innerRequest, invocation.Arguments);
return;
}
private NameValueCollection Params
{
get
{
var paramsVariableKey = ReflectionExtensions.GetName<HttpRequest>(x => x.Params);
var requestParams = _innerRequest.Params;
if (_propertySubstitutes.ContainsKey(paramsVariableKey))
{
requestParams = (NameValueCollection)_propertySubstitutes[paramsVariableKey];
}
return requestParams;
}
}
private string InterceptIndexer(string key)
{
return Params[key];
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using FubuCore.Reflection;
namespace ZG.Utilities.Web
{
public interface IRequestSubstitutesBuilder
{
RequestSubstitutesBuilder Add<T>(Expression<Func<HttpRequestBase, T>> property, T value);
RequestSubstitutesBuilder AddWhen<T>(bool condition, Expression<Func<HttpRequestBase, T>> property, T value);
IDictionary<string, object> Build();
}
public class RequestSubstitutesBuilder : IRequestSubstitutesBuilder
{
private readonly IDictionary<string, object> _substitutes = new Dictionary<string, object>();
public RequestSubstitutesBuilder Add<T>(Expression<Func<HttpRequestBase, T>> property, T value)
{
var propertyName = ReflectionHelper.GetProperty(property).Name;
_substitutes[propertyName] = value;
return this;
}
public RequestSubstitutesBuilder AddWhen<T>(bool condition, Expression<Func<HttpRequestBase, T>> property, T value)
{
return condition ? Add(property, value) : this;
}
public IDictionary<string, object> Build()
{
var substitutes = _substitutes.ToDictionary(x => x.Key, x => x.Value);
_substitutes.Clear();
return substitutes;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment