MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как получить заголовки запросов в WebBrowser"
Answer 1019378
Логичным решением было бы использовать прокси-сервер. Но, насколько я знаю, для WebBrowser нельзя локально изменить настройки прокси-сервера в конкретном экземпляре (только глобально для Internet Explorer). Поэтому можно использовать другой подход - перехват пакетов на интерфейсах:
using System; using System.IO; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Threading; using System.Net; using System.Net.Sockets; using System.Net.NetworkInformation; namespace WpfApplication1 { public partial class MainWindow : Window { string navigated_host=""; object sync = new object(); public MainWindow() { InitializeComponent(); webbrowser.Navigating += webbrowser_Navigating; var ips = GetIpAddresses(); foreach (IPAddress ip in ips) { Thread th = new Thread(ThreadProc); th.IsBackground = true; th.Start((object)ip); } } void TextBoxWriteLine(string s) { this.Dispatcher.Invoke(() => { textbox.Text += s + Environment.NewLine; }); } void webbrowser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e) { lock (sync) { navigated_host = e.Uri.Host; } } //Получает все локальные IP-адреса public static List<IPAddress> GetIpAddresses() { List<IPAddress> res = new List<IPAddress>(10); var ifs = NetworkInterface.GetAllNetworkInterfaces(); foreach (var interf in ifs) { var ipprop = interf.GetIPProperties(); if (ipprop == null) continue; var unicast = ipprop.UnicastAddresses; if (unicast == null) continue; //находим первый Unicast-адрес foreach (var addr in unicast) { if (addr.Address.AddressFamily != AddressFamily.InterNetwork) continue; res.Add(addr.Address); break; } } return res; } const byte PROTO_TCP = 6; public string ParseIpPacket(byte[] data, IPAddress src_ip) { ushort dummy; byte b; MemoryStream ms = new MemoryStream(data); BinaryReader br = new BinaryReader(ms); uint header_len; uint total_len; IPAddress src,dst; string host=""; //parse IP packet header using (ms) using (br) { b = br.ReadByte(); byte ver = (byte)((b & (byte)0xF0) >> 4); //IP version if (ver != 4) { TextBoxWriteLine("Unsupported IP version: "+ ver.ToString()); return null; } byte ihl = (byte)(b & (byte)0x0F);//header length header_len = ihl * 4u; b = br.ReadByte(); //packet length byte[] temp = new byte[2]; temp[1] = br.ReadByte(); temp[0] = br.ReadByte(); total_len = BitConverter.ToUInt16(temp, 0); dummy = br.ReadUInt16(); dummy = br.ReadUInt16(); byte ttl = br.ReadByte(); byte proto = br.ReadByte(); dummy = br.ReadUInt16(); //source IP temp = new byte[4]; temp[0] = br.ReadByte(); temp[1] = br.ReadByte(); temp[2] = br.ReadByte(); temp[3] = br.ReadByte(); src = new IPAddress(temp); //destination IP temp[0] = br.ReadByte(); temp[1] = br.ReadByte(); temp[2] = br.ReadByte(); temp[3] = br.ReadByte(); dst = new IPAddress(temp); if (proto != PROTO_TCP) return null; } //Parse TCP packet uint tcp_size = total_len - header_len; byte[] tcp_data = new byte[tcp_size]; Array.Copy(data, header_len, tcp_data, 0, tcp_size); ms = new MemoryStream(tcp_data); br = new BinaryReader(ms); byte tcp_header_size; uint http_size; using (ms) using (br) { var src_port = br.ReadUInt16(); var dst_port = br.ReadUInt16(); br.ReadUInt32(); br.ReadUInt32(); tcp_header_size = (byte)(br.ReadByte() >> 4); tcp_header_size *= 4; http_size = tcp_size - tcp_header_size; } byte[] http_data = new byte[http_size]; Array.Copy(tcp_data, tcp_header_size, http_data, 0, http_size); //Parse HTTP data string res = Encoding.UTF8.GetString(http_data); string[] arr = res.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 2 && arr[0].StartsWith("GET") && arr[0].Contains("HTTP/")) { //найдем поле Host for (int i = 1; i < arr.Length; i++) { if (arr[i].StartsWith("Host: ")) { host = arr[i].Replace("Host: ", ""); break; } } if (host == "") { //пытаемся получить имя узла из обратного DNS try { host = Dns.GetHostEntry(dst).HostName; } catch (SocketException) { host = ""; } } lock (sync) { if (host == navigated_host) { return res; } } } return null; } public void ThreadProc(object args) { var mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); IPAddress ipaddr=(IPAddress)args; //начинаем прослушивание пакетов на интерфейсе... mainSocket.Bind(new IPEndPoint(ipaddr, 0)); mainSocket.SetSocketOption(SocketOptionLevel.IP, //Applies only to IP packets SocketOptionName.HeaderIncluded, //Set the include header true); //option to true byte[] byTrue = new byte[4] { 1, 0, 0, 0 }; byte[] byOut = new byte[4]; //Socket.IOControl is analogous to the WSAIoctl method of Winsock 2 mainSocket.IOControl(IOControlCode.ReceiveAll, //SIO_RCVALL of Winsock byTrue, byOut); byte[] buffer = new byte[1024*20]; int res; while (true) { try { res = mainSocket.Receive(buffer); var result = ParseIpPacket(buffer, ipaddr); if (result != null) { TextBoxWriteLine(result); } } catch (Exception ex) { if (ex.GetType() != typeof(System.Threading.Tasks.TaskCanceledException)) { TextBoxWriteLine(ex.ToString()); } } } } } }
Работает только с IPv4-интерфейсами и протоколом HTTP (не HTTPS). Для запуска требуются права администратора.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.