skip to Main Content

I have an ASP.NET application that runs on:

Windows Server 2019 Standard

IIS Version 10.0.17763.1

Application is set up to use HTTPS

Application is using the library System.Web.UI.WebControls.FileUpload for file upload

Application is using QuickPDFDLL0811.dll to read PDF files and count the number of pages

Users have been reporting that SOME PDF files are failing to upload. The chrome browser tab shows a spinner as if the application is doing something and then the users get presented with a "The site can’t be reached" page (attached). However, the same users have indicated they have taken the same PDF files that are erroring out through the steps I found on google here, and then they are able to upload the files successfully.

In addition, I took the same file that failed to upload in production and:

  1. Uploaded in the server where the PROD app is running through HTTP and chrome and it succeeded.
  2. Uploaded in our test environments using chrome and it via HTTP and HTTPS and it succeeded.

I am unable to share the files, as they contain sensitive data.

Has anyone run into a similar issue? or could anyone offer any guidance? The fact that I found a URL from the company docusign.com indicates to me that it is a common issue.

EDIT:
I am adding the code that gets executed when the issue is triggered (BtnUploadClick). I forgot to mention that I also reviewed the IIS log files, but nothing is being logged with an unsuccessful response.

(My apologies for the weird formatting, Stackoverflow messes it up when I copy/paste from VSCode)

protected void BtnUploadClick(object sender, EventArgs e)
{
try
{
    if (FileUpload.HasFiles)
    {
        
        foreach (var FileUpload in FileUpload.PostedFiles)
        {
            var uploadResult = Uploadfile(lstPrn, FileUpload);
            if (uploadResult.ReturnResponse == 
                             Enumerators.ResponseEnum.Success)
            {
                var objPrintFile = uploadResult.ReturnObject;
                lstPrn.Add(objPrintFile.FileName.ToUpper(), 
                           objPrintFile);
            }
        } 
    }
    else
    {
        lblFileCheck.Text = "You have not specified a file.";
        lblFileCheck.ForeColor = Color.Red;
    }
}
catch (Exception exception)
{
    //Log exception
}
}

private Response<PrintFile> Uploadfile(Hashtable lstPrn, 
HttpPostedFile FileUpload)
{
var result = new Response<PrintFile>();
var msg = "";
try
{
    if (Path.GetExtension(fileToWork).ToLower() == ".pdf")
    {
        PdfUtil myPdfUtil = new PdfUtil();

        objPrintFile.FileName = fileToWork;
        objPrintFile.ExpectedDocs = 
                myPdfUtil.GetNumberOfPdfPages(path + fileToWork);
        if (objPrintFile.ExpectedDocs > 0)
        {
            //Map object here
            try
            {
                Session.Add("NewRequestPrintFiles", lstPrn);

                result.ReturnResponse = 
                 Enumerators.ResponseEnum.Success;
                result.ReturnObject = objPrintFile;

                btnNextUpload.Enabled = true;
            }
            catch
            {
                //log message here
            }
        }
    }
}
catch (Exception ex)
{
    //Log error
}

return result;
}

public int GetNumberOfPdfPages(string fileName)
{
int totPages = 0;

if (!string.IsNullOrEmpty(fileName))
{
    using (StreamReader sr = new 
    StreamReader(File.OpenRead(fileName)))
    {
        Regex regex = new Regex(@"/Types*/Page[^s]");

        int bufSize = 10 * 1024;
        int lastPorSize = 20;
        char[] myBuffer = new char[bufSize + 1];
        char[] lastPortion = new char[lastPorSize];

        for (int c = 0; c < lastPorSize; c++)
            lastPortion[c] = '*';

        try
        {
            //read it by chunks!!
            while (!sr.EndOfStream)
            {
                int nBytes = sr.ReadBlock(myBuffer, 0, bufSize);
                string strToSerach = new string(lastPortion, 0, 
                lastPorSize) + new string(myBuffer, 0, nBytes);

                MatchCollection matches = 
                regex.Matches(strToSerach);
                foreach (Match match in matches)
                {
                    if (match.Index >= nBytes)
                    {
                        // I have to clean up if there is a match
                        // at the end of strToSerach because I 
                        //don't want that to be copied over
                        // lastPortion and count again on the 
                        //next iteration.
                        for (int c = 0; c < match.Length; c++)
                        {
                            if (match.Index + c > lastPorSize)
                                myBuffer[match.Index + c - 
                                lastPorSize] = '*';
                        }
                    }
                }

                for (int c = 0; c < lastPorSize; c++)
                {
                    if ((nBytes - lastPorSize + c) >= 0)
                    {
                        lastPortion[c] = myBuffer[nBytes - 
                                         lastPorSize + c];    
                    }
                }

                totPages += matches.Count;
            }
        }
        catch (Exception ex)
        {
            totPages = 0;
        }
    }
}
else
    totPages = 0;

return totPages;
}

EDIT:

I am attaching a screenshot of the files. File1 is the same as File2, but notice there is a size difference when File1 is taken through the process of "Print to PDF" and then is saved locally. File1 fails to upload while File2 uploads successfully.

enter image description here

enter image description here

3

Answers


  1. Chosen as BEST ANSWER

    I had to get the networking team involved since the request wasn't even being logged by IIS. They mentioned that they had applied some security rules and our application was impacted. After making an exception to the rules they applied, we were able to successfully upload the files that were failing before. I cannot tell exactly what type of rules were applied, since I don't work with that team, but they manage our traffic routing and load balancing using a tool called "F5". Thank you guys for your time and guidance.


  2. Your issue is about experience, you want someone who has ran into the same error to answer you. But your problem needs some specifics. Though I will try and answer you.

    The scenario you described could be from three things…

    1. When deploying some apps using Editors or IDEs like Visual Studio, you would notice that not all folders/directories are published. Some are not there when you deploy either to production or on your machine. So the implication of this is that when you finally deploy the app, it would not contain the folder to which you are trying to upload data and if your code does not contain the block that checks whether the directory exists or not and create it when it does not find it, the code fails. (This process is by publishing with Visual Studio IDE).

    so ensure your code checks if the directory exists otherwise create it.

    1. When the Directory’s security settings does not allow write. Could be readonly and not read/write.

    You would be required to grant write access to that directory you are trying to upload data into.

    1. Absolute Path for a resource. Sometimes in code the path to the folder you are writing to or uploading to might be different on the production.

    Ensure the production machine has the same path for deployment resources as would your development environment.

    NB: The three scenarios above can both make the code work on a test machine but not in production because if you test on the local machine, its probably going to contain the directory you are writing to or uploading to. And Read/Write access needs not be granted on developer machine most times but in production, you surely do. It happened to me when I failed to check if the directory exists or not and I published directly from my Visual Studio IDE into Microsoft Azure. When I tried to upload pictures, it failed because the directory could not be found. Though no Error Message appeared.

    Login or Signup to reply.
  3. I’m going to venture a guess that the PDF files that fail to upload are larger than 4MB. If so, what you are encountering is the default request limit of classic asp.NET applications.

    See the answers to this question for how to fix this:
    How to increase the max upload file size in ASP.NET?

    The behavior you see, of the "connection was reset" is because the server closes the connection when the limit is reached. It has to do this, because it cannot send a response until the request is fully received, and so it has no other option than to terminate the connection which results in the error you see in the browser. The reason this limit exists is for security reasons: A malicious client could overwhelm your server resources by sending extremely large requests, extremely slowly. For a similar reason, web servers also typically require that clients transmit data at a reasonable rate.

    Apparently, in ASP.NET core, the request limit default was bumped up to 30MB, probably because the 4MB limit is too restrictive on the modern web.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search