Ретрансляция запроса в asp.net(пересылка запроса)
У меня есть веб-приложение, которое взаимодействует между двумя различными веб-приложениями (один приемник и один отправитель, отправитель общается с моим приложением, а мое приложение общается с обоими).
Обычный сценарий заключается в том, что отправитель отправляет HttpRequest в мое приложение, и я получаю его в HttpHandler. Это, в свою очередь, отправляет HttpContext для некоторых бизнес-логик, чтобы сделать некоторые сантехнические работы.
После того, как мои бизнес-классы завершили хранение данных (некоторые записи и т.д.), я хочу передать один и тот же запрос со всеми заголовками, данными формы и т.д. в приложение-получатель. Это должно быть отправлено из класса, а не из HttpHandler.
Вопрос в том, как я могу взять объект HttpContext и перенаправить/передать тот же запрос, только изменяя URL-адрес из http://myserver.com/ to http://receiver.com.
Любые примеры кода в предпочтительном С# были бы замечательными!
Ответы
Ответ 1
Собственно, что-то вроде этого хорошо работало
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 просто делает байтовый массив из потока
Ответ 2
У меня есть метод расширения на HttpResponseBase
, чтобы скопировать входящий запрос на исходящий запрос.
Использование:
var externalRequest = (HttpWebRequest)WebRequest.Create("http://stackoverflow.com");
this.Request.CopyTo(externalRequest);
var externalResponse = (HttpWebResponse)externalRequest.GetResponse();
Источник:
/// <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();
}
}
Ответ 3
Вот хороший код реле в VB.NET с использованием MVC.
GLOBAL.ASAX.VB
Public Class MvcApplication
Inherits System.Web.HttpApplication
Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.MapRoute("Default", "{*s}", New With {.controller = "Home", .action = "Index"})
End Sub
Sub Application_Start()
RegisterRoutes(RouteTable.Routes)
End Sub
End Class
HomeController.vb
Option Explicit On
Option Strict On
Imports System.Net
<HandleError()> _
Public Class HomeController
Inherits System.Web.Mvc.Controller
Function Index(ByVal s As String) As ActionResult
Server.ScriptTimeout = 60 * 60
If Request.QueryString.ToString <> "" Then s = s + "?" + Request.QueryString.ToString
Dim req As HttpWebRequest = CType(WebRequest.Create("http://stackoverflow.com/" + s), HttpWebRequest)
req.AllowAutoRedirect = False
req.Method = Request.HttpMethod
req.Accept = Request.Headers("Accept")
req.Referer = Request.Headers("Referer")
req.UserAgent = Request.UserAgent
For Each h In Request.Headers.AllKeys
If Not (New String() {"Connection", "Accept", "Host", "User-Agent", "Referer"}).Contains(h) Then
req.Headers.Add(h, Request.Headers(h))
End If
Next
If Request.HttpMethod <> "GET" Then
Using st = req.GetRequestStream
StreamCopy(Request.InputStream, st)
End Using
End If
Dim resp As WebResponse = Nothing
Try
Try
resp = req.GetResponse()
Catch ex As WebException
resp = ex.Response
End Try
If resp IsNot Nothing Then
Response.StatusCode = CType(resp, HttpWebResponse).StatusCode
For Each h In resp.Headers.AllKeys
If Not (New String() {"Content-Type"}).Contains(h) Then
Response.AddHeader(h, resp.Headers(h))
End If
Next
Response.ContentType = resp.ContentType
Using st = resp.GetResponseStream
StreamCopy(st, Response.OutputStream)
End Using
End If
Finally
If resp IsNot Nothing Then resp.Close()
End Try
Return Nothing
End Function
Sub StreamCopy(ByVal input As IO.Stream, ByVal output As IO.Stream)
Dim buf(0 To 16383) As Byte
Using br = New IO.BinaryReader(input)
Using bw = New IO.BinaryWriter(output)
Do
Dim rb = br.Read(buf, 0, buf.Length)
If rb = 0 Then Exit Do
bw.Write(buf, 0, rb)
Loop
End Using
End Using
End Sub
End Class
Ответ 4
HttpContext включает свойство Request, которое, в свою очередь, содержит коллекцию Headers. Это должна быть вся необходимая информация.
Ответ 5
возможно что-то вроде:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("www.testing.test");
request.Headers = (WebHeaderCollection)Request.Headers;
Затем вызовите ответ get
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Это будет иметь те же заголовки HTTP, что и исходный запрос.