Click here to Skip to main content
15,886,137 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a set of N different URLs as input to my program. I need to check the status code of each of them and generate a report. I am using HttpWebRequest-HttpWebResponse classes of .Net.

Also, if I get 5XX status codes I give 'X' times retry attempts to the particular URLs.

The problem I am facing is when I test my program against huge number of URLs say 30-40, for first 3-4 inputs program works properly but then I get error "The request was aborted. Operation has timed out" or "Unable to connect Remote Server" and then again say after 10-15 inputs, for the last 4-5 inputs i get proper response. But when I fire the same URLs which gives time out error in browser, it gets opened.

I tried with many googled solutions like, closed the Response object, aborted the request, disposed/closed all stream objects, set ServicePointManager's Connection Limit to 500, set timeout property of request to 3 mins, but all in Vain nothing solved it.

I really don't know what is the real issue behind it.

If anyone can help me out with this, it will be a very great help from you. Kindly suggest me some solution.

Sample Code:

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication5
{
    class Class1
    {
        private void processStart()
        {
            string line = "";
            int UrlCnt = -1;
            string InputPath = @"C:\\MyFolder\Input.txt";
            using (StreamReader oStreamReader = new StreamReader(InputPath))
            {

                while ((line = oStreamReader.ReadLine()) != null)
                {
                    UrlCnt++;
                    string URL = line;

                    GetStatusofURLs(URL, false, -1);
                }

                oStreamReader.Close();
                oStreamReader.Dispose();
            }
        }
        public void GetStatusofURLs(string URL, bool IsCalledforRetry, int RetryCount)
        {
            string startTime = "";
            string timeOut = "30";
            string endTime = "";
            bool IsAttemptSuccess = false;
            bool IsSuccessOnRetry = false;
            bool ReachedMaxTrial = false;
            startTime = DateTime.Now.ToString("hh:mm:ss.fff");
            HttpWebRequest oReq = (HttpWebRequest)WebRequest.Create(URL);
            WebRequest.DefaultWebProxy = null;
            oReq.Timeout = Convert.ToInt32(timeOut) * 1000;
            oReq.AllowAutoRedirect = false;
            ServicePointManager.DefaultConnectionLimit = 500;
            try
            {

                using ((HttpWebResponse)oReq.GetResponse())
                {
                    HttpWebResponse oRes = (HttpWebResponse)oReq.GetResponse();
                    endTime = DateTime.Now.ToString("yyyyMMddHHmmssffff");

                    IsAttemptSuccess = true;

                    if (IsCalledforRetry)
                        IsSuccessOnRetry = true;

                    if ((int)oRes.StatusCode >= 300 && (int)oRes.StatusCode < 600)
                        IsAttemptSuccess = false;
                    oRes.Close();
                    oReq.Abort();
                }
            }
            catch (Exception ex)
            {
                if (ex is WebException)
                {
                    WebException we = (WebException)ex;
                    if (we != null)
                    {
                        endTime = System.DateTime.Now.ToString("hh:mm:ss.fff");
                        if (((HttpWebResponse)we.Response) != null)
                        {
                            HttpWebResponse oRes = ((HttpWebResponse)we.Response);
                            if(!IsCalledforRetry)
                            {
                            if ((int)oRes.StatusCode >= 500)
                                RetryforSuccess(URL, ref IsSuccessOnRetry, ref  ReachedMaxTrial);
}
                        }
                    }
                    else if (!ReachedMaxTrial && !IsCalledforRetry)
                        RetryforSuccess(URL, ref  IsSuccessOnRetry, ref  ReachedMaxTrial);
                }
            }
        }
        public void RetryforSuccess(string URL, ref bool IsSuccessOnRetry, ref bool ReachedMaxTrial)
        {
            for (int i = 1; i < 5; i++)
            {
                if (IsSuccessOnRetry)
                    break;
                if (i == 5)
                {
                    ReachedMaxTrial = true;
                    GetStatusofURLs(URL, true, i);
                    break;
                }
                else
                    GetStatusofURLs(URL, true, i);
            }
        }
    }
}
Posted
Updated 24-Dec-14 20:26pm
v2
Comments
Timberbird 25-Dec-14 1:07am    
Have you tried to put only one URL in your input file - the first which gives you error? I don't think 30-40 is a huge amount of URLs, especially considering that you get an error after 3 or four requests :). BTW, it looks like you code will create an infinite loop if server returns response with code 500+ - in this case you catch WebException, call RetryforSuccess() without any checks for IsCalledforRetry, which, in turn, calls GetStatusofURLs() again, which gets WebException... you get the point. And the fact that your link is opened in browser doesn't mean that you get the same result with HttpWebRequest - browser also sends a couple of headers HttpWebRequest doesn't possibly provide (haven't tried it myself, but are you sure that at least Host an User-Agent are included?)
Member 9800875 25-Dec-14 2:18am    
First of all, thank you for bringing into my notice regarding infinite loop for 500+ codes, I modified it by keeping a check IsCalledforRetry.
Yes I have tried with only one URL, it behaves weirdly... With just the one URL - the URL which gives error, it sometimes get correct response but then some other time I get the same error "Operation has timed out".
And regarding your question about Host and User-Agent, I am sorry but I dint get what you meant to ask me.
Timberbird 25-Dec-14 3:01am    
Actually I'd try to completely avoid calling two functions from each other (for example, by moving retry connection call to processStart() method), but that doesn't seem the source of the problem by now.<br/>
I'd recommend to inspect requests your application makes. One of the simplest ways to do that is using Fiddler tool. It's a great web debugger tool - simply install and run it and it'll work as a proxy, capturing any HTTP traffic between your PC and the outer world. So you can do the following:
1) Run Fiddler (or any other traffic inspection tool).
2) Start your application having only one troublesome URL in your input file.
3) Switch to Fiddler and see how many requests does your application send and which HTTP headers do these requests contain. "Host" and "User-Agent" headers are of particular interest, since HTTP server work often depends on them. Also you should check server response.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900