2011-10-22 3 views
0

웹 호스트 (Hostgator)의 cPanel에 로그인하기 위해 C# 클래스를 개발하는 데 어려움을 겪고 있습니다. 현재 이곳에C# WebRequest로 cPanel에 로그인 할 수 없습니다.

$url = "http://mysite.com:2082/"; 

$c = curl_init($url); 

curl_setopt($c, CURLOPT_USERPWD, 'user:password'); 
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); 
$result = curl_exec($c); 
if ($result === false) 
    $result = curl_error($c); 
curl_close($c); 

file_put_contents('log.txt', $result); 
//print_r($result); 

을이 주석 작업을 만들기 위해 다양한 시도 내 C# 클래스입니다 :

class HTTPHandler 
{ 
    public static string Connect (string url, string userName, string password) 
    { 
     string result; 

     try 
     { 
      // An initial @ symbol in the password must be escaped 
      if (password.Length > 0) 
       if (password[0] == '@') 
        password = "\\" + password; 

      // Create a request for the URL.   
      WebRequest request = WebRequest.Create(url); 
      request.PreAuthenticate = true; 
      request.Credentials = new NetworkCredential(userName, password); 

      /* 
      var credCache = new CredentialCache(); 
      credCache.Add(new Uri(url), "Basic", 
           new NetworkCredential(userName, password)); 
      request.Credentials = credCache; 
      */ 

      //request.Method = "POST"; 
      //request.ContentType = "application/x-www-form-urlencoded"; 

      /* 
      // Create POST data and convert it to a byte array. 
      string postData = string.Format("user={0}&pass={1}", userName, password); 
      byte[] byteArray = Encoding.UTF8.GetBytes(postData); 
      request.ContentLength = byteArray.Length; 
      request.ContentType = "application/x-www-form-urlencoded"; 
      Stream dataStream = request.GetRequestStream(); 
      dataStream.Write(byteArray, 0, byteArray.Length); 
      dataStream.Close(); 
      */ 

      // Get the response. 
      HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

      // Get the stream containing content returned by the server. 
      Stream dataStream = response.GetResponseStream(); 
      // Open the stream using a StreamReader for easy access. 
      StreamReader reader = new StreamReader(dataStream); 
      // Display the content. 
      result = string.Format("Server response:\n{0}\n{1}", response.StatusDescription, reader.ReadToEnd()); 
      // Cleanup the streams and the response. 
      reader.Close(); 
      dataStream.Close(); 
      response.Close(); 
     } 
     catch (Exception e) 
     { 
      result = string.Format("There was an error:\n{0}", e.Message); 
     } 

     return result; 
    } 
} 

}

는 PHP에서는 다음과 같이 컬 확장을 사용하여 매우 쉽습니다

하지만 GetResponse 단계에서 401 (Unauthorized) 오류가 계속 발생합니다.

내 로컬 호스트 테스트 페이지에서 PHP와 C# 제출 사이의 $ _SERVER 변수를 비교할 때 발신자 포트와 약간 다른 데이터를 얻을 수 있습니다. 결정적인 PHP_AUTH_USER와 PHP_AUTH_PW는 같습니다.

내 OS 내가 솔루션은 정말 간단하다 생각하지만, 지금까지 내가 당황하고 윈도우 7 64 비트와 나는 비주얼 C# 2010

을 사용하고 있습니다. 그러나 C#에 대한 상대적으로 초보자. 누군가가 도울 수 있기를 바랍니다.

답변

1

PreAuthenticate을 설정할 필요가 없습니다. 요청을 이해하도록하십시오. 또한 WebRequest 대신 HttpWebRequest을 사용하는 것이 좋습니다. 가장 큰 차이점은 CookieContainer 속성을 설정하여 쿠키를 활성화 할 수 있다는 것입니다. 기본적으로 쿠키는 사용 중지되며 사용자의 요청에 대해 쿠키를 사용하려면 new CookieContainer();으로 설정하면됩니다. 인증 과정에서 발생하는 리디렉션과 성공적으로 인증 된 사실을 기록하는 인증 쿠키 때문에이 문제가 발생합니다.

코딩 스타일 참고 : 문에 IDisposable (예 : 응답, 스트림 및 리더)을 모두 포함해야합니다.

또한 암호가 @ 인 이유를 분명히 알지 못합니다. 요청은 모든 인코딩 요구 사항을 자동으로 처리해야합니다.

전체 샘플 코드 :

var request = WebRequest.CreateHttp(url); 
request.Credentials = new NetworkCredential(username, password); 
request.CookieContainer = new CookieContainer(); // needed to enable cookies 

using (var response = (HttpWebResponse)request.GetResponse()) 
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet))) 
    return string.Format("Server response:\n{0}\n{1}", response.StatusDescription, reader.ReadToEnd()); 

편집 : 모든 편집 죄송합니다. 메모리로 코드를 작성하면서 인코딩 부분을 올바르게 처리하는 데 어려움을 겪고있었습니다.

+0

감사 : 여기

내가 해낸 HTTP 도우미 클래스에 대한 코드입니다.로컬 서버의 테스트 페이지에서 PreAuthenticate를 사용하지 않고 PHP 페이지에 사용자 이름과 암호 세부 정보를받지 못했습니다. Curl을 사용하면 쿠키를 사용할 필요가 없습니다. PHP와 Curl을 사용하여 cPanel에 연결할 때 초기 @ 문자를 이스케이프 처리해야한다는 것을 알았습니다. – Andy

+0

@Andy 좋습니다.하지만이 방법을 사용해 보셨습니까? –

+0

cPanel을 사용하여 Linux를 호스팅하고있는 누군가가 성공적으로 로그인 한 C# 코드를 테스트 할 수 있기를 바랍니다. 쿠키없이 GetResponse 단계를 지나쳐야하므로 오류가 발생하지 않습니다. PHP 예제를 에뮬레이션하면됩니다. – Andy

1

이것은 전체 .NET Framework 4를 사용하여 HttpUtility에 대한이 어셈블리에 액세스하고 References의 System.Web에 대한 참조를 추가하기 위해 프로젝트 속성을 설정해야하는 System.Web을 사용하고 있습니다.

오버로드 된 모든 메소드를 테스트하지는 않았지만 가장 중요한 것은 userName이있을 때 인증 정보가 http 헤더에 추가되는 cPanel 연결입니다.

또한 cPanel의 경우 request.AllowAutoRedirect = false를 설정해야했습니다. 쿠키를 관리하지 못했기 때문에 페이지 단위로 페이지를 제어했습니다. 답변에 대한

class HTTPHandler 
{ 
    // Some default settings 
    const string UserAgent = "Bot"; // Change this to something more meaningful 
    const int TimeOut = 1000; // Time out in ms 

    // Basic connection 
    public static string Connect(string url) 
    { 
     return Connect(url, "", "", UserAgent, "", TimeOut); 
    } 

    // Connect with post data passed as a key : value pair dictionary 
    public static string Connect(string url, Dictionary<string, string> args) 
    { 
     return Connect(url, "", "", UserAgent, ToQueryString(args), TimeOut); 
    } 

    // Connect with a custom user agent specified 
    public static string Connect(string url, string userAgent) 
    { 
     return Connect(url, "", "", userAgent, "", TimeOut); 
    } 

    public static string Connect(string url, string userName, string password, string userAgent, string postData, int timeOut) 
    { 
     string result; 

     try 
     { 
      // Create a request for the URL.   
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 

      if (userAgent == null) 
       userAgent = UserAgent; 

      request.UserAgent = userAgent; 
      request.Timeout = timeOut; 

      if (userName.Length > 0) 
      { 
       string authInfo = userName + ":" + password; 
       authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo)); 
       request.Headers["Authorization"] = "Basic " + authInfo; 
       request.AllowAutoRedirect = false; 
      } 

      if (postData.Length > 0) 
      { 
       request.Method = "POST"; 
       request.ContentType = "application/x-www-form-urlencoded"; 

       // Create POST data and convert it to a byte array. 
       byte[] byteArray = Encoding.UTF8.GetBytes(postData); 
       request.ContentLength = byteArray.Length; 
       using (Stream dataStream = request.GetRequestStream()) 
       { 
        dataStream.Write(byteArray, 0, byteArray.Length); 
       } 
      } 

      // Get the response. 
      using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
      { 
       // Get the stream containing content returned by the server. 
       Stream dataStream = response.GetResponseStream(); 
       // Open the stream using a StreamReader for easy access. 
       using (StreamReader reader = new StreamReader(dataStream)) 
       { 
        result = string.Format("Server response:\n{0}\n{1}", response.StatusDescription, reader.ReadToEnd()); 
       } 
      } 
     } 

     catch (Exception e) 
     { 
      result = string.Format("There was an error:\n{0}", e.Message); 
     } 

     return result; 
    } 

    public static string ToQueryString(Dictionary<string, string> args) 
    { 
     List<string> encodedData = new List<string>(); 

     foreach (KeyValuePair<string, string> pair in args) 
     { 
      encodedData.Add(HttpUtility.UrlEncode(pair.Key) + "=" + HttpUtility.UrlEncode(pair.Value)); 
     } 

     return String.Join("&", encodedData.ToArray()); 
    } 
} 
관련 문제