GetRequestStream() is throwing time out exception when posting data to HTTPS url

前端 未结 5 1707
悲&欢浪女
悲&欢浪女 2021-02-07 06:34

I\'m calling an API hosted on Apache server to post data. I\'m using HttpWebRequest to perform POST in C#.

API has both normal HTTP and secure layer (HTTPS) PORT on the

相关标签:
5条回答
  • 2021-02-07 07:02

    I ran into the same issue. It seems like it is solved for me. I went through all my code making sure to invoke webResponse.Close() and/or responseStream.Close() for all my HttpWebResponse objects. The documentation indicates that you can close the stream or the HttpWebResponse object. Calling both is not harmful, so I did. Not closing the responses may cause the application to run out of connections for reuse, and this seems to affect the HttpWebRequest.GetRequestStream as far as I can observe in my code.

    0 讨论(0)
  • 2021-02-07 07:13

    I don't know if this will help you with your specific problem but you should consider Disposing some of those objects when you are finished with them. I was doing something like this recently and wrapping stuff up in using statements seems to clean up a bunch of timeout exceptions for me.

                using (var reqStream = request.GetRequestStream())
                {
                    if (reqStream == null)
                    {
                        return;
                    }
    
                  //do whatever
    
                }
    

    also check these things

    • Is the server serving https in your local dev environment?
    • Have you set up your bindings *.443 (https) properly?
    • Do you need to set credentials on the request?
    • Is it your application pool account accessing the https resources or is it your account being passed through?
    • Have you thought about using WebClient instead?

      using (WebClient client = new WebClient())
          {               
              using (Stream stream = client.OpenRead("https://server-url-xxxx.com"))
              using (StreamReader reader = new StreamReader(stream))
              {
                  MessageBox.Show(reader.ReadToEnd());
              }
          }
      

    EDIT:

    make a request from console.

    internal class Program
    {
        private static void Main(string[] args)
        {
            new Program().Run();
            Console.ReadLine();
        }
    
        public void Run()
        {
    
           var request = (HttpWebRequest)System.Net.WebRequest.Create("https://server-url-xxxx.com");
            request.Method = "POST";
            request.ProtocolVersion = System.Net.HttpVersion.Version10;
            request.ContentType = "application/x-www-form-urlencoded";
    
            using (var reqStream = request.GetRequestStream())
            {
                using(var response = new StreamReader(reqStream )
                {
                  Console.WriteLine(response.ReadToEnd());
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-07 07:15

    I ran into this, too. I wanted to simulate hundreds of users with a Console app. When simulating only one user, everything was fine. But with more users came the Timeout exception all the time.

    Timeout occurs because by default the ConnectionLimit=2 to a ServicePoint (aka website). Very good article to read: https://venkateshnarayanan.wordpress.com/2013/04/17/httpwebrequest-reuse-of-tcp-connections/

    What you can do is:

    1) make more ConnectionGroups within a servicePoint, because ConnectionLimit is per ConnectionGroups.

    2) or you just simply increase the connection limit.

    See my solution:

    private HttpWebRequest CreateHttpWebRequest<U>(string userSessionID, string method, string fullUrl, U uploadData)
    {
        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(fullUrl);
        req.Method = method; // GET PUT POST DELETE
        req.ConnectionGroupName = userSessionID;  // We make separate connection-groups for each user session. Within a group connections can be reused.
        req.ServicePoint.ConnectionLimit = 10;    // The default value of 2 within a ConnectionGroup caused me always a "Timeout exception" because a user's 1-3 concurrent WebRequests within a second.
        req.ServicePoint.MaxIdleTime = 5 * 1000;  // (5 sec) default was 100000 (100 sec).  Max idle time for a connection within a ConnectionGroup for reuse before closing
        Log("Statistics: The sum of connections of all connectiongroups within the ServicePoint: " + req.ServicePoint.CurrentConnections; // just for statistics
    
        if (uploadData != null)
        {
            req.ContentType = "application/json";
            SerializeToJson(uploadData, req.GetRequestStream());
        }
        return req;
    }
    
    /// <summary>Serializes and writes obj to the requestStream and closes the stream. Uses JSON serialization from System.Runtime.Serialization.</summary>        
    public void SerializeToJson(object obj, Stream requestStream)
    {
        DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
        json.WriteObject(requestStream, obj);            
        requestStream.Close();
    }
    
    0 讨论(0)
  • 2021-02-07 07:16

    You may want to set timeout property, check it here http://www.codeproject.com/Tips/69637/Setting-timeout-property-for-System-Net-WebClient

    0 讨论(0)
  • 2021-02-07 07:25

    Try this:

        WebRequest req = WebRequest.Create("https://server-url-xxxx.com");
        req.Method = "POST";
        string json_value = jsonSerializer.Serialize(data); //Body data
        ServicePointManager.Expect100Continue = false;
        using (var streamWriter = new StreamWriter(req.GetRequestStream()))
        {
            streamWriter.Write(json_value);
            streamWriter.Flush();
            streamWriter.Close();
        }
        HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
        Stream GETResponseStream = resp.GetResponseStream();
        StreamReader sr = new StreamReader(GETResponseStream);
        var response = sr.ReadToEnd(); //Response
        resp.Close(); //Close response
        sr.Close(); //Close StreamReader
    

    And review the URI:

    • Reserved characters. Send reserved characters by the URI can bring problems ! * ' ( ) ; : @ & = + $ , / ? # [ ]

    • URI Length: You should not exceed 2000 characters

    0 讨论(0)
提交回复
热议问题