Copy link to clipboard
Copied
Since moving to CF2016 I've been seeing quite a lot of the error below in the exception log file. I did some research and can't quite figure out what is going on and if this is indeed having an impact on the end user. I've tested the download link on http://www.hiddentoolbox.com and it appears to work fine
"Error","ajp-nio-8016-exec-6","03/26/18","11:55:46","myapp","The cause of this output exception was that: org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine. The specific sequence of files included or processed is: C:\ACS\hiddentoolbox\downloadfile.cfm, line: 15 "
coldfusion.tagext.OutputException: The cause of this output exception was that: org.apache.catalina.connector.ClientAbortException: java.io.IOException: An established connection was aborted by the software in your host machine.
I was wondering if this is as simple as people closing their browser before the download is completed, although I could not replicate myself by starting and closing a browser before it had completed.
Could anybody help throw some light on it?
Thanks
Mark
Fixed! I used the fix from Jamo (Thanks Jamo)
By adding the CFTRY and CFCATCH I no longer have a record in the logs, so now I'll be able to find the true errors in the log file.
Btw: I realized this was not caused by spiders because any legit request for the download was also creating a log record.
So here's what cured the problem. I'm not sure of the mechanics as I have not really done much with CFTRY and CFCATCH, but it definately works
<cftry>
<cfcontent type="application/unknown" file="#
It does indeed work without the CFABORT and plain text, giving this (Will change to this as the right answer)
<cftry>
<cfcontent type="application/unknown" file="#downloadlocation#\toolbox.exe" />
<cfcatch>
</cfcatch>
</cftry>
Copy link to clipboard
Copied
I took another look at this and it appears to be the use of CFCONTENT.
I have a simple page with:
<cfheader name="Content-Disposition" value="attachment; filename=#downloadfilename#.exe" />
<cfcontent type="application/x-msdownload" file="#downloadlocation#\toolbox.exe" />
The code does function, the EXE is triggered for download, and yet I'm getting all these errors in the log file
Does anybody have any idea why?
Copy link to clipboard
Copied
We have been seeing this, too. A lot. I, also, have not been able to reconcile what is happening. We have keyword searchable PDFs, and it is always a user clicking on a link to view a PDF that is triggering it.
V/r,
^ _ ^
Copy link to clipboard
Copied
It certainly was not there on CF8. No idea at all what's causing it and I can't find any other posts either.
Copy link to clipboard
Copied
I'm going to make some guesses. I think that either (a) CF is logging more information than it did before, because the connector is capturing more information from IIS, or (b) the way that HTTP clients handle helper applications has changed a bit. If you think about what's happening, both of these examples involve handoffs of some sort - the browser itself isn't going to handle displaying these files, and may not be responsible for fetching them either. Instead, the browser would hand off the handling of a PDF, say, to Adobe Acrobat. Acrobat has its own HTTP client functionality, and can do some neat tricks with it. For example, you can download a big PDF and start reading it before the download has completed. The concept of "handler applications" has been around since the web was created, but maybe the client-side plumbing has changed. Or maybe the switch from JRun to Tomcat changed the information available to the connector. I don't know, but as long as things are working I'm not going to worry too much about it!
Dave Watts, Fig Leaf Software
Copy link to clipboard
Copied
I’m with Dave that this can likely be ignored. From what I’ve read in the past, this is usually just a reflection of the user’s browser connection no longer being there when CF is trying to write its output. It could be that the user gave up and refreshed (which would trigger a new request from them to CF), or they went to some new page, or perhaps their network connection went down, or maybe the browser timed out.
As for anyone feeling like they are seeing more of them than in the past, well, while one reason may be a change due to any of the above (about your code, environment, or users), another explanation is that their appearance (and frequency) could vary based on configuration of the web connector (between CF and your web server), whether as configured by Adobe, by default, or as someone on your end might change that configuration.
To be clear (and as Dave also alluded to), in CF10 and above, this is a Tomcat web connector while in CF9 and before it was a JRun connector.
Here's a discussion from the folks at Atlassian (makers of Jira, Confluence, and other apps which like CF are Java apps that can run on Tomcat), and the stack trace shows this to issue be about a deployment on Tomcat in fact:
https://confluence.atlassian.com/jirakb/clientabortexception-because-of-closing-a-page-before-it-finished-loading-225122378.html
You’ll see they basically assert the same thing (same possible reasons, and that it can generally be ignored as long as there’s no sign of some bigger problem). One might wonder if perhaps that message could somehow be configured to not be logged, but I’m not aware of how to do that.
I will add, finally, that I see a discussion of the topic with regard to the BonCode connector (an alternative web server connector for Tomcat, used often by the Lucee community). See “setting idle timeouts” here:
http://boncode.net/connector/webdocs/Tomcat_Connector.htm
He (the creator, Bilal) indicates there that he feels that the problem might be tempered by tweaking the connectionTimeout and keepAliveTimeout args for the AJP connector in the server.xml file. CF has that same server.xml file and AJP connector line (because again, CF’s web connector IS the Tomcat connector, which also uses AJP).
I will warn that one will be really “getting into the weeds” if they start tweaking such stuff. Even the Tomcat docs on the topic are not always as clear sa they can be, and you never know (without LOTS of testing or experience) whether tweaking one thing (that even seems to “fix” one problem) might lead to an unexpected problem elsewhere.
/charlie
Copy link to clipboard
Copied
I do find that I am able to create that log entry myself just be visiting our download page which triggers the page that has the code to trigger the EXE download.
Everything certainly appears to be functioning so it's just an annoying false positive in the error log. In an ideal world I'd be able to switch it off because it makes finding other real errors that little more difficult, however I certainly am not not going to try messing with the server.xml, as Charlie pointed out, I could end up fixing one thing but who knows what adverse effect it could have.
It looks like I'm going to have to just live with it.
Copy link to clipboard
Copied
Wondering if anybody ever found a solution to this? I am running ColdFusion 2016 Update 13 and I'm still seeing this issue.
I understand that it's not actually a 'real' failure and our site works just fine, but the problem is that it creates a lot of noise in the CF exception log file, making it difficult to weed out other real issues.
My guess is this might be search engines spidering the site and rapidly disconnecting before downloading the whole exe, as the exe is triggered on the loading of the page. My only option will be to change the page so there's a manual link to the exe rather than an automatic trigger.
Copy link to clipboard
Copied
Well, here's a tip, if you go that route: you may find it challenging to identify ALL spiders via the user agent header (which is what most would try to use for such detection). They may be too many and varied..Worse, some spiders will lie and present a legit user agent.
Instead, if the page in question supports sessions, you could test for whether there are any incoming cookies (cgi.http_cookie is ""). Most spiders and automated agents don't bother to send one.
And while even a "real" user won't present a cookie on their very first visit, they will be given a. Cf session cookie after that first visit which they would then present on subsequent visits.
If both kinds of visitors "with no cookie" have no reason to receive that exe, this could solve things for you.
If not, let us know more about the exe. It's a curious thing to hear of a web page that downloads an exe automatically to all visitors. No need to explain, if this solves your problem.
And sure, ultimately, it would be great to solve this sort of problem more generically. And since I shared those other observations in Sept 2018 about other tomcat-based timeouts being the answer for others (not using the cf web server connector), I am still thinking that's a likely answer, but I saw your reply to me then saying you wanted to avoid fiddling with those, not knowing the pros/cons.
Copy link to clipboard
Copied
Hi Charlie,
Agreed on user agent, I would not be optomistic that would stop the issue
It does support sessions, I could easily check for the cookies, nice solution that is easy to implement.
Here's a link to the page https://www.hiddentoolbox.com/download.cfm once you click on the download link at the top, it'll go to download2.cfm which also triggers downloadfile.cfm (this page creates a unique file name.exe so that the software can read the file name and build in some affiliate tracking, also triggering the download, and at the same time giving the user instructions relevant to their browser)
It's likely a spider is triggering the page and that triggers the code to start the EXE which the spider does not hold a connection for. If the cookies are not present I could stop the code from triggering.
Copy link to clipboard
Copied
Yep. Let us know how it goes. (And thanks for the additional clarification in the exe. )
Copy link to clipboard
Copied
I'll update shortly and monitor the logs for a few days and report back the findings
Copy link to clipboard
Copied
We've performed lots of digital downloads over the years that use CFContent. We started encountering this error after migrating the apps to CF2016. Many bots test URLs to determine if it's valid, but don't care to stay around long enough to perform an actual download. To prevent having this false positive logged in the CF logs or causing an alert, we started adding our own TRY/CATCH block around it and then perform a simple CFAbort. If you wish, you can log it separately so you can track it, but we haven't found any false positives yet where this error has impacted a customer that desired to download a file.
NOTE: If your CF-based application is behind a WAF like CloudFlare or StackPath, files that take extra time to generate could have a negatively impact when the proxy stops waiting because it's taking too long. In these instances, either use a different host or port that isn't restricted by the WAF time limit (which could become a security hole) or trigger the file generation in the background (using AJAX) and then ping for the existence of the file prior to redirecting the user to downloadable file. (We use this approach this with a project that prepares personalized audio files for digitial distribution via streaming/downloads.)
Copy link to clipboard
Copied
Thanks for the input Jamo
Could you possible share the code/method behind how you use the try/catch?
I can confirm it's a standard install of CF2016 running on IIS, with no WAF
Copy link to clipboard
Copied
Sure. I've just posted a blog entry regarding "handling aborted downloads using try/catch" and included a GIST with sample CFML code.
https://dev.to/gamesover/using-try-catch-to-suppress-aborted-download-errors-3j42
I hope this helps.
Copy link to clipboard
Copied
We might be able to throw some light on the matter if shared with us the code that caused the error. Namely:
C:\ACS\hiddentoolbox\downloadfile.cfm, line: 15
Was it the cfcontent line you posted later?
Copy link to clipboard
Copied
Here's the code
<CFIF #ISDefined('url.aff')# AND #ISDefined('url.sub1')#>
<CFCOOKIE NAME="aff" VALUE="#val(URL.aff)#" expires="never">
<CFCOOKIE NAME="sub1" VALUE="#left(URL.sub1,50)#" expires="never">
</CFIF>
<cfparam name="cookie.aff" default="0">
<cfparam name="cookie.sub1" default="0">
<CFSET downloadfilename = "HiddenToolboxInstaller" & "_a" & "#cookie.aff#" & "_r" & "#left(urldecode(cookie.sub1),50)#">
<cffile action = "append" file = "c:\acs\hiddentoolbox\control\logs\downloadfile_cfm.txt" attributes = "normal" output = "AFF:#cookie.aff# - SUB1:#cookie.sub1# - #now()# - #remote_addr# - #CGI.HTTP_USER_AGENT#">
<cfheader name="Content-Disposition" value="attachment; filename=#downloadfilename#.exe" />
<cfcontent type="application/x-msdownload" file="#downloadlocation#\toolbox.exe" />
Copy link to clipboard
Copied
I'm going to make a suggestion. I'm not even sure I like this suggestion, but here goes. You might try making your download page unavailable to regular HTTP GET requests. Put it behind a form or something. Your problematic clients probably won't go through the form. And you might be able to capture some useful information along the way.
Dave Watts, Eidolon LLC
Copy link to clipboard
Copied
It might reduce the number of hits, but I'd prefer not to have a form, plus I doubt it would stop spam bots from then hitting the form. As they can also now get around captcha images, I think it might reduce one problem, but cause another
Copy link to clipboard
Copied
The alternative approach is to not give a damn what goes in your log files, and feed them into an indexer like Splunk (if you have money) or Solr (if you don't) and filter out the stuff that's not important for you to see. That's probably actually the best approach, but obviously requires a higher level of effort.
Dave Watts, Eidolon LLC
Copy link to clipboard
Copied
I recommend on using a date. Many browsers and security extensions convert "never" cookies to session-based.
<CFCOOKIE NAME="aff" VALUE="#val(URL.aff)#" expires="720">
Add FileExists() to ensure that there's a file. If not, return a legitimate 404 error (or other if prerequisite data is missing.) If a Form POST is required, add that pre-condition too.
Regarding the mime-type, use "application/unknown" as it will force a download.
<cfcontent type="application/unknown" file="#downloadlocation#\toolbox.exe" />
For content-disposition, add double quotes around the filename in case the value contains a space.
<cfheader name="Content-Disposition" value="attachment; filename=""#downloadfilename#.exe""" />
Regarding the EXE extenstion, this could be problematic. Some browsers, plugins, anti-malware/virus software and proxies may automatically block it. If you are serving up EXE files (not recommended), ensure that IIS is configured to allow it as I believe it's disabled by default. (We don't allow files with EXE extensions to be uploaded or downloaded.)
Here's where you'd add try/catch to prevent it from being added to the cf error log:
<cftry>
<cfcontent type="application/unknown" file="#downloadlocation#\toolbox.exe" />
<cfcatch><!--- log, etc --->Aborted<cfabort></cfcatch>
</cftry>
Copy link to clipboard
Copied
@dave watts - I'd rather stop them going in there in the first place (if I can). I'm going to study the code from Jamo https://dev.to/gamesover/using-try-catch-to-suppress-aborted-download-errors-3j42 to see if it's something I can apply.
@jamo The code has actually been working flawlessly for about 7 years, so I'm not coverly concerned about any problems within the code. I'll go over the solution you posted with a CFCatch and see if it's something I could implement to catch and stop these logs.
Copy link to clipboard
Copied
Here's yet another take on the subject, a cfcontent bug report: https://tracker.adobe.com/#/view/CF-4206502
If it is relevant to you, then place your vote.
Copy link to clipboard
Copied
Which one is line 15?
Copy link to clipboard
Copied
Fixed! I used the fix from Jamo (Thanks Jamo)
By adding the CFTRY and CFCATCH I no longer have a record in the logs, so now I'll be able to find the true errors in the log file.
Btw: I realized this was not caused by spiders because any legit request for the download was also creating a log record.
So here's what cured the problem. I'm not sure of the mechanics as I have not really done much with CFTRY and CFCATCH, but it definately works
<cftry>
<cfcontent type="application/unknown" file="#downloadlocation#\toolbox.exe" />
<cfcatch><!--- log, etc --->Aborted<cfabort></cfcatch>
</cftry>