2009-09-20 32 views
5

Làm cách nào để đặt tiêu đề Máy chủ tùy chỉnh trong HttpWebRequest? Tôi biết rằng bình thường lớp này không cho phép bạn làm như vậy nhưng có anyway để sử dụng phản ánh hoặc một cái gì đó như thế mà không thực sự cần tôi để gửi toàn bộ gói với TCPClient?Cách đặt tiêu đề "Máy chủ" tùy chỉnh trong HttpWebRequest?

+0

Chính xác bạn muốn thay đổi gì trong tiêu đề? Bởi vì hầu hết các tham số tiêu đề có thể được sửa đổi gián tiếp bởi các thuộc tính –

+0

Tại sao bạn cần đặt tiêu đề "Máy chủ lưu trữ" một mình. Nếu bạn yêu cầu 'www.google.com', nó đơn giản trở thành tiêu đề máy chủ. –

+0

@Yannick Host và các thông số dành riêng khác không thể. –

Trả lời

4

Có một cách vòng xoay để làm điều này, như mô tả ở đây:

http://blogs.msdn.com/feroze_daud/archive/2005/03/31/404328.aspx

Tuy nhiên, phiên bản tiếp theo của khuôn khổ này (.NET Framework 4.0) sẽ làm cho nó dễ dàng hơn.

http://blogs.msdn.com/ncl/archive/2009/07/20/new-ncl-features-in-net-4-0-beta-2.aspx

Hy vọng điều này sẽ hữu ích.

+0

Tôi đã nhìn thấy trang đó mặc dù có rất nhiều vấn đề trong cách giải quyết đó bên cạnh đó đó là một giải pháp thực sự dơ bẩn :) –

+2

Xấu hổ Tôi không sử dụng .NET 4 có vẻ tốt. –

1

Bạn có thể sử dụng hack này, được thiết kế cho giải quyết vấn đề này trong Net 3.5.

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net; 
using System.Reflection; 


namespace ConsoleApplication6 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://198.252.206.16"); 

      FieldInfo headersFieldInfo = request.GetType().GetField("_HttpRequestHeaders", System.Reflection.BindingFlags.NonPublic 
                | System.Reflection.BindingFlags.Instance 
                | System.Reflection.BindingFlags.GetField); 

      CusteredHeaderCollection WssHeaders = new CusteredHeaderCollection("stackoverflow.com"); 

      headersFieldInfo.SetValue(request, WssHeaders); 

      request.Proxy = null; 
      HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

      StreamReader sr = new StreamReader(response.GetResponseStream()); 
      string result = sr.ReadToEnd(); 
      Console.WriteLine(result); 
      Console.ReadLine(); 

     } 
     public class CusteredHeaderCollection : WebHeaderCollection 
     { 
      public bool HostHeaderValueReplaced { get;private set; } 

      public string ClusterUrl { get; private set; } 

      public CusteredHeaderCollection(string commonClusterUrl) : base() 
      { 
       if (string.IsNullOrEmpty("commonClusterUrl")) 
        throw new ArgumentNullException("commonClusterUrl"); 

       this.ClusterUrl = commonClusterUrl; 
      } 

      public override string ToString() 
      { 
       this["Host"] = this.ClusterUrl; 
       string tmp = base.ToString(); 
       this.HostHeaderValueReplaced = true; 

       return tmp; 
      } 

     } 
    } 
} 
0

WebClient cho phép.

var client = new WebClient(); 
client.Headers.Add("Host", WebHeader); 

Tôi không thể cho bạn biết lý do. Tài liệu nêu rõ rằng Máy chủ là tiêu đề hệ thống.

+0

Đó là vì nó không hoạt động - không thể trực tiếp thay đổi tiêu đề máy chủ ngoại lệ. –

+0

Nó hoạt động. Tôi đang sử dụng nó, trong sản xuất – Patrick

+0

Không hoạt động. ArgumentException: Tiêu đề này phải được sửa đổi với thuộc tính appropiate. – Mikhail

3

Necromancing.
Đối với những người vẫn đang sử dụng .NET 2.0
Thực tế là khá dễ dàng, nếu bạn biết cách thực hiện.

Vấn đề là bạn không thể đặt tiêu đề máy chủ, vì khung sẽ không cho phép bạn thay đổi giá trị khi chạy. (.net framework 4.0+ sẽ cho phép bạn ghi đè lên máy chủ trong httpwebrequest).

Lần thử tiếp theo sẽ đặt tiêu đề có phản xạ, để xoay vòng, điều này sẽ cho phép bạn thay đổi giá trị tiêu đề. Nhưng tại thời gian chạy, nó sẽ ghi đè lên giá trị này với phần host của url, có nghĩa là sự phản chiếu sẽ mang lại cho bạn không có gì.

Nếu tên dns không tồn tại, đó là khá thẳng thắn trường hợp duy nhất mà bạn muốn làm điều này ở nơi đầu tiên, bạn không thể thiết lập nó, bởi vì .NET không thể giải quyết nó, và bạn không thể ghi đè lên trình phân giải DNS.

Nhưng những gì bạn có thể làm, là đặt một webproxy với cùng địa chỉ IP chính xác làm máy chủ đích.

Vì vậy, nếu chỉ IP máy chủ của bạn là 28.14.88.71:

public class myweb : System.Net.WebClient 
{ 
    protected override System.Net.WebRequest GetWebRequest(System.Uri address) 
    { 
     System.Net.WebRequest request = (System.Net.WebRequest)base.GetWebRequest(address); 
     //string host = "redmine.nonexistantdomain.com"; 

     //request.Headers.GetType().InvokeMember("ChangeInternal", 
     // System.Reflection.BindingFlags.NonPublic | 
     // System.Reflection.BindingFlags.Instance | 
     // System.Reflection.BindingFlags.InvokeMethod, null, 
     // request.Headers, new object[] { "Host", host } 
     //); 

     //server IP and port 
     request.Proxy = new System.Net.WebProxy("http://28.14.88.71:80"); 

     // .NET 4.0 only 
     System.Net.HttpWebRequest foo = (System.Net.HttpWebRequest)request; 
     //foo.Host = host; 

     // The below reflection-based operation is not necessary, 
     // if the server speaks HTTP 1.1 correctly 
     // and the firewall doesn't interfere 
     // https://yoursunny.com/t/2009/HttpWebRequest-IP/ 
     System.Reflection.FieldInfo horribleProxyServicePoint = (typeof(System.Net.ServicePoint)) 
      .GetField("m_ProxyServicePoint", System.Reflection.BindingFlags.NonPublic | 
      System.Reflection.BindingFlags.Instance); 

     horribleProxyServicePoint.SetValue(foo.ServicePoint, false); 
     return foo; 



     return request; 
    } 


    } 

và thì đấy, bây giờ

myweb wc = new myweb(); 
string str = wc.DownloadString("http://redmine.non-existant-domain.com"); 

và bạn sẽ có được đúng trang lại, nếu 28.14.88.71 là một máy chủ web với ảo lưu trữ dựa trên tên (dựa trên http-host-header).

+0

Tốt, với .NET 2.0. Rõ ràng, điều này sẽ không hoạt động nếu bạn thực sự cần phải sử dụng một máy chủ proxy;) Chỉ cần nâng cấp lên .NET 4.5 đã được - WebRequest và WebClient đều không được chấp nhận anyway. – User1

Các vấn đề liên quan