|
| Writing an HTTP module to act as a proxy for a POST Request |
 |
Tue, 26 Feb 2008 17:57:11 +000 |
Hello,
To cut a long story short I'm calling Web Services on an application server from
a page running on a seperate WSS server. The WebService / Page both work well
but I'm calling the services through client script and I keep getting a security
warning when I try to access the remote service.
With the restrictions that are caused by running under WSS I decided that a good
solution would be to write an HTTP Module that redirects when a particular URL
is entered. For example; I could post to
http://MyWssServer/Services/MyService.asmx and on the server it will route the
request through to http://MyApplicationServer/Services/MyService.asmx and return
the response. I'm not concerned about maintaining the credentials so I've been
trying to make a new WebClient request in the module and return the response
from that that. Unfortunately I need to use the services via POST and I've
struggled to transfer the request body to the new request.
This struck me as a simple thing to do but I can't figure out how to do it. What
code I do have is below. If anyone can fill in the blank then I'd be very
grateful. Alternatively, if I'm going about this all wrong then it would be
great to be put back on the straight and narrow.
Thanks,
public class ResourceRedirect : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new
EventHandler(context_PreRequestHandlerExecute);
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication httpApp = sender as HttpApplication;
if (httpApp != null)
{
Page page = httpApp.Context.CurrentHandler as Page;
if (page != null)
page.PreInit += new EventHandler(page_PreInit);
}
}
void page_PreInit(object sender, EventArgs e)
{
Page page = sender as Page;
string currentPath =
page.Server.HtmlDecode(HttpContext.Current.Request.RawUrl.ToLower());
if (page != null)
{
if (currentPath.Contains("/service/myservices.asmx"))
{
//HELP!!
}
}
}
public void Dispose() {}
}
|
| Post Reply
|
| Re: Writing an HTTP module to act as a proxy for a POST Request |
 |
Fri, 29 Feb 2008 12:12:37 +000 |
I figured this out in the end. To cut a long story short, I was doing everything
correctly with the HttpWebRequest (which is the class to focus on when doing
this) my problem was due to incorrect SOAP packets which were causing the server
to throw a 500 error.
My code is below but I also advise downloading an app called "Fiddler"
(www.fiddlertool.com/). This fantastic piece of software sits in the background
and monitors all the HTTP traffic to/from your computer. It makes any task of
this nature considerably easier to debug.
Cheers,
(Web.config)
<configSections>
<sectionGroup name="MyWebServiceProxy">
<section name="UrlSettings"
type="System.Configuration.NameValueSectionHandler" />
<section name="ServiceList"
type="System.Configuration.NameValueSectionHandler" />
</sectionGroup>
</configSections>
<MyWebServiceProxy>
<UrlSettings>
<add key="urlpath" value="/webserviceproxy/" />
</UrlSettings>
<ServiceList>
<add key="myservice.asmx"
value="http://newHost/services/newMyService.asmx" />
</ServiceList>
</MyWebServiceProxy>
(Module)
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Xml;
using System.Collections.Specialized;
namespace CWRedirect
{
class ResourceRedirect : IHttpModule
{
#region IHttpModule Memberspublic void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
static string path = "";
void context_BeginRequest(object sender, EventArgs e)
{
if (path.Length == 0)
{
NameValueCollection UrlPath
=
(NameValueCollection)System.Configuration.ConfigurationManager.GetSection("
CWWebServiceProxy/UrlSettings");
path = UrlPath["urlpath"];
}
string data;
HttpApplication context = sender as HttpApplication;
if (context.Request.RawUrl.StartsWith(path,
StringComparison.CurrentCultureIgnoreCase))
{
HttpWebResponse newResponse = null;
NameValueCollection Redirect
=
(NameValueCollection)System.Configuration.ConfigurationManager.GetSection("
CWWebServiceProxy/ServiceList");
string redirUrl =
Redirect[context.Request.Url.Segments[context.Request.Url.Segments.Length -
1]];
if ((redirUrl ?? "").Length == 0)
{
data = "No Service Redirect exists for this Web
Service. Please add an entry to the Service List in the web.config";
context.Response.ContentType = "text/html";
context.Response.Write(data);
}
else
{
data = WebServiceRedirect(context, redirUrl, out
newResponse);
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.ContentType = newResponse.ContentType;
context.Response.Write(data);
}
context.Response.End();
}
}
string WebServiceRedirect(HttpApplication context, string url, out
HttpWebResponse newResponse)
{
byte[] bytes =
context.Request.BinaryRead(context.Request.TotalBytes);
char[] responseBody = Encoding.UTF8.GetChars(bytes, 0,
bytes.Length);
HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(url);
newRequest.AllowAutoRedirect = false;
newRequest.ContentLength = context.Request.ContentLength;
newRequest.ContentType = context.Request.ContentType;
newRequest.UseDefaultCredentials = true;
newRequest.UserAgent = ".NET Web Proxy";
newRequest.Referer = url;
newRequest.Method = context.Request.RequestType;
if (context.Request.AcceptTypes.Length > 0)
newRequest.MediaType = context.Request.AcceptTypes[0];
foreach (string str in context.Request.Headers.Keys)
{
try { newRequest.Headers.Add(str, context.Request.Headers[str]);
}
catch { }
}
if (newRequest.Method.ToLower() == "post")
{
using (System.IO.StreamWriter sw = new
System.IO.StreamWriter((newRequest.GetRequestStream())))
{
sw.Write(responseBody); sw.Flush(); sw.Close();
}
}
string temp = "";
try
{
newResponse = (HttpWebResponse)newRequest.GetResponse();
using (System.IO.StreamReader sw = new
System.IO.StreamReader((newResponse.GetResponseStream())))
{
temp = sw.ReadToEnd();
sw.Close();
}
}
catch (WebException exc)
{
using (System.IO.StreamReader sw = new
System.IO.StreamReader((exc.Response.GetResponseStream())))
{
newResponse = (HttpWebResponse)exc.Response;
temp = sw.ReadToEnd();
sw.Close();
}
}
return temp;
}
#endregion
}
}
|
| Post Reply
|
|
|
|
|
|
|
|
|
|