Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relaying a request in asp.net (Forwarding a request)

I have a web application that communicates between two different web applications (one receiver and one sender, the sender communicates with my application, and my application communicates with both).

A regular scenario is that the sender sends a HttpRequest to my application, and I receive it in an HttpHandler. This in turn sends the HttpContext to some businesslogic to do some plumbing.

After my business classes are finished storing data (some logging etc), I want to relay the same request with all the headers, form data etc to the receiver application. This must be sent from the class, and not the HttpHandler.

The question is really - how can I take a HttpContext object, and forward/relay the exact same request only modifying the URL from http://myserver.com/ to http://receiver.com.

Any code examples in preferable c# would be great!

like image 849
El Che Avatar asked Mar 30 '09 13:03

El Che


2 Answers

I have an extension method on HttpResponseBase to copy an incoming request to an outgoing request.

Usage:

    var externalRequest = (HttpWebRequest)WebRequest.Create("http://stackoverflow.com");     this.Request.CopyTo(externalRequest);     var externalResponse = (HttpWebResponse)externalRequest.GetResponse(); 

Source:

/// <summary> /// Copies all headers and content (except the URL) from an incoming to an outgoing /// request. /// </summary> /// <param name="source">The request to copy from</param> /// <param name="destination">The request to copy to</param> public static void CopyTo(this HttpRequestBase source, HttpWebRequest destination) {     destination.Method = source.HttpMethod;      // Copy unrestricted headers (including cookies, if any)     foreach (var headerKey in source.Headers.AllKeys)     {         switch (headerKey)         {             case "Connection":             case "Content-Length":             case "Date":             case "Expect":             case "Host":             case "If-Modified-Since":             case "Range":             case "Transfer-Encoding":             case "Proxy-Connection":                 // Let IIS handle these                 break;              case "Accept":             case "Content-Type":             case "Referer":             case "User-Agent":                 // Restricted - copied below                 break;              default:                 destination.Headers[headerKey] = source.Headers[headerKey];                 break;         }     }      // Copy restricted headers     if (source.AcceptTypes.Any())     {         destination.Accept = string.Join(",", source.AcceptTypes);     }     destination.ContentType = source.ContentType;     destination.Referer = source.UrlReferrer.AbsoluteUri;     destination.UserAgent = source.UserAgent;      // Copy content (if content body is allowed)     if (source.HttpMethod != "GET"         && source.HttpMethod != "HEAD"         && source.ContentLength > 0)     {         var destinationStream = destination.GetRequestStream();         source.InputStream.CopyTo(destinationStream);         destinationStream.Close();     } } 
like image 151
diachedelic Avatar answered Sep 24 '22 08:09

diachedelic


Actually, something like this worked well

HttpRequest original = context.Request; HttpWebRequest newRequest = (HttpWebRequest)WebRequest.Create(newUrl);  newRequest .ContentType = original.ContentType; newRequest .Method = original.HttpMethod; newRequest .UserAgent = original.UserAgent;  byte[] originalStream = ReadToByteArray(original.InputStream, 1024);  Stream reqStream = newRequest .GetRequestStream(); reqStream.Write(originalStream, 0, originalStream.Length); reqStream.Close();   newRequest .GetResponse(); 

edit: ReadToByteArray method just makes a byte array from the stream

like image 35
El Che Avatar answered Sep 25 '22 08:09

El Che