Одним из способов является использование HttpSys
и создание локального прокси-сервера для обработки запроса по адресу обратной связи 127.0.0.1
. Вы бы поменяли системный прокси на этот адрес / порт и сели бы между клиентом и сервером.
Это позволит вам изменять пакеты запроса / ответа и заголовки. Здесь есть пример этого подхода в C #, и я исправил это ниже, чтобы показать, как это будет работать.
public class MyProxy
{
private readonly HttpListener listener;
public MyProxy()
{
listener = new HttpListener();
}
public void Start()
{
listener.Prefixes.Add("http://*:8888/");
listener.Prefixes.Add("https://*:8889/");
listener.Start();
Console.WriteLine("Proxy started, hit enter to stop");
listener.BeginGetContext(GetContextCallback, null);
Console.ReadLine();
listener.Stop();
}
public void GetContextCallback(IAsyncResult result)
{
var context = listener.EndGetContext(result);
listener.BeginGetContext(GetContextCallback, null);
var request = context.Request;
var response = context.Response;
var url = request.Url;
UriBuilder builder = new UriBuilder(url);
builder.Port = url.Port == 8888 ? 80 : 443;
url = builder.Uri;
WebRequest webRequest = WebRequest.Create(url);
webRequest.Proxy = GlobalProxySelection.GetEmptyWebProxy();
WebResponse webResponse = webRequest.GetResponse();
using (Stream reader = webResponse.GetResponseStream())
{
using (Stream writer = response.OutputStream)
{
reader.CopyTo(writer);
}
}
}
}
Недостатком этого подхода является его довольно низкий уровень, который влияет на весь трафик на пользовательском компьютере, что может быть нежелательно. Вам придется обрабатывать запросы SSL, что также повлияет на все существующие настроенные прокси.
Другим альтернативным подходом является использование COM-компонента Microsoft Internet Controls
и расширение класса WebBrowser
. Здесь есть вопрос SO , который показывает подход. К сожалению, версия WebBrowser
в пространстве имен .NET не реализует объекты ответа на запрос. Интересные биты ниже.
public class ExtendedWebBrowser : WebBrowser
{
...
void BeforeNavigate(object pDisp, ref object url, ref object flags,
ref object targetFrameName, ref object postData,
ref object headers, ref bool cancel)
{
if (!headers.Contains("X-RequestFlag")
{
headers += "X-RequestFlag: true\r\n";
// append custom header here
// cancel current request
cancel = true;
// re-request with amended details
Navigate((string)url, (string)targetFrameName, (byte[])postData,
(string)headers);
}
else
{
base.BeforeNavigate(...);
}
}
}