代码之家  ›  专栏  ›  技术社区  ›  MaLKaV_eS

从php到c的https发布#

  •  0
  • MaLKaV_eS  · 技术社区  · 15 年前

    我必须发布到第三方的https url,才能处理和发送数据。我举个例子,就是:

    $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时,我必须移植它,但我总是会得到一个不真实的错误。

    以下是我要做的:

    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;
    

    我已经阅读了所有我能找到的关于这个的问题,但是我没有得到任何改进。事先谢谢!

    3 回复  |  直到 10 年前
        1
  •  2
  •   Jon Skeet    15 年前

    你做错了一件事就是假设 字节 与中的长度相同 文字 . 您应该使用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 并查看curl请求和.net请求之间的差异。

        2
  •  1
  •   Lucero    15 年前

    我认为您不应该在身份验证中提供主机…

    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
    }
    

    另外,您应该避免为每个请求分配服务点验证委托,这可能会越来越减慢请求的速度,因为验证是多次执行的,而且它也是一种内存泄漏。

        3
  •  1
  •   ShaTin    10 年前
    curl_setopt($ch, CURLOPT_USERPWD, "$user:$password");
    

    下面是如何在ASP.NET中添加curlopt_userpwd的方法:

        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;
        }
    
    推荐文章