2009-09-17 62 views
0

我必須向第三方的https網址發佈帖子才能獲取數據併發回。而我作爲一例是這樣的:從Php到https的https POST#

$signature= foo_string; 
$data_to_post = json_dictionary; 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $base_url); 
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password"); 
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); 
curl_setopt($ch, CURLOPT_HEADER, 1); 
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json')); 
curl_setopt($ch, CURLOPT_HTTPHEADER,array("JSON-Signature: $signature")); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_to_post); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$data = curl_exec($ch); 
curl_close($ch); 

我們與ASP .NET C#2.0的工作,我有口,但我總是得到一個不autenticated錯誤。

下面是我在做什麼:

HttpWebRequest q = (HttpWebRequest)WebRequest.Create(Host + ":" + Port); 
       ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications);     

       q.Method = "POST"; 
       q.Headers.Add("JSON-Signature:" + GetSignature(data)); 
       q.ContentType = "application/json"; 

       q.UseDefaultCredentials = false; 
       q.Credentials = new NetworkCredential(user,pwd, Host); 

       byte[] buffer = UTF8Encoding.UTF8.GetBytes(data); 

       q.ContentLength = data.Length;     

       Stream oStream = q.GetRequestStream(); 
       StreamWriter oWriter = new StreamWriter(oStream); 
       oWriter.Write(buffer); 
       oWriter.Close(); 


       HttpWebResponse reps = q.GetResponse() as HttpWebResponse; 

我讀過所有的SO問題,我可以找到關於這一點,但我沒有得到任何改善。提前致謝!

回答

2

嗯,有一件事你做錯了,是假設在字節長度是相同字符長度。您應該使用buffer.Length作爲內容長度。你還打電話StreamWriter.Write字節數組。你不應該這樣做 - 你應該使用流,因爲你已經做了編碼:

byte[] buffer = Encoding.UTF8.GetBytes(data); 

q.ContentLength = buffer.Length; 
using (Stream stream = q.GetRequestStream()) 
{ 
    stream.Write(buffer, 0, buffer.Length); 
} 

現在,這不會解決認證問題。你可能會發現,只設置PreAuthenticate解決了,但:

q.PreAuthenticate = true; 

如果不工作,我建議你運行WireShark,並期待在經過捲曲的請求和.NET的要求之間的差異。

+0

謝謝,錯誤現改爲: 「連接終止Unexpeted接收錯誤。」但是,由於它們是自定義錯誤,我現在要求支持:D非常感謝! – 2009-09-17 15:56:19

1

我想你不應該提供在身份驗證的主機...

q.Credentials = new NetworkCredential(user,pwd); 

這將是這樣的:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Host + ":" + Port); 
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(new interhanse().AcceptAllCertifications); 

request.Method = "POST"; 
request.Headers.Add("JSON-Signature:" + GetSignature(data)); 
request.ContentType = "application/json"; 

request.UseDefaultCredentials = false; 
request.Credentials = new NetworkCredential(user, pwd); 

byte[] buffer = UTF8Encoding.UTF8.GetBytes(data); 

request.ContentLength = buffer.Length; 
using (Stream oStream = request.GetRequestStream()) { 
    oStream.Write(buffer, 0, buffer.Length); 
} 
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { 
    // load data from response here 
} 

而且你應該避免分配在每個服務點確認委託請求,這可能會越來越慢地降低請求速度,因爲驗證會執行多次,而且這也是一種內存泄漏。

+0

沒有改變錯誤,但由於它不在這個例子中,我不會再通過它了。 – 2009-09-17 15:58:38

0
curl_setopt($ch, CURLOPT_USERPWD, "$user:$password"); 

這裏是你如何添加CURLOPT_USERPWD在Asp.Net:

private async Task<string> Execute(string url, string query, string user, string pasword) 
    { 
     HttpClient httpClient = new HttpClient(); 
     var baseUri = new Uri(url, UriKind.Absolute); // e.g. http://somedomain.com/endpoint 
     Uri request = new Uri(baseUri, query); // with query e.g. http://somedomain.com/endpoint?arg1=xyz&arg2=abc 

     // Add a new Request Message 
     HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, request); 

     // add headers -> CURLOPT_USERPWD equivalent 
     var encodedStr = Convert.ToBase64String(Encoding.Default.GetBytes(string.Format("{0}:{1}", user, password))); 
     var authorizationKey = "Basic" + " " + encodedStr; // Note: Basic case sensitive 
     requestMessage.Headers.Add("Authorization", authorizationKey); 

     // if POST - do this instead 
     // content 
     //HttpContent content = new StringContent(jsonContent);  // string jsonContent i.e. JsonConvert.SerializeObject(YourObject); 
     //requestMessage.Content = content; 
     //requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 

     // execute 
     HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); 
     var responseString = await responseMessage.Content.ReadAsStringAsync(); // reads it as string; 

     // if json and you need to convert to an object do this 
     // var myresponse = JsonConvert.DeserializeObject<YourMappedObject>(responseString); 

     return responseString; 
    }