coldfusion cfcontent want to offer open file but not download - file-io

In ColdFusion I have code to open or download a file:
<cfif FileExists('#session.exploc#/#attname#')>
<cfset typeatt = FilegetMimeType('#session.exploc#/#attname#')>
<cfheader name = "Content-Disposition" value="attachment;#session.exploc#/#attname#">
<cfcontent type="#typeatt#" file="#session.exploc#/#attname#">
</cfif>
This gives a standard open/download window.
I would prefer a window which just allows the user to open the file, and does not provide a download. Is there a way to do that?
Alternatively, I am happy to open the file in the browser, but since I don't know the filetype in advance I'm not sure how to do that.

This is not a function of <cfcontent> per-se. All <cfcontent> handles is the MIME-type of the response, the content of it (it can reset it for example), and a few other bits and pieces. It's all about the nature of the content returned by the CFML server.
This is all fairly clear in the docs for <cfcontent>:
Some file types, such as PDF documents, do not use executable code and can display directly in most browsers. To request the browser to display the file directly, use a cfheader tag similar to the following:
<cfheader name="Content-Disposition" value="inline; filename=name.ext">
IE: what you want to be doing is to set the Content-Disposition header with a value of inline to tell the browser to potentially inline the document, if if has the capabilities to do so.

Related

Accessible PDF's from Coldfusion 2021

I've been looking everywhere, and can't find a suitable answer. We are generating PDF's on the fly for a job board. People click on a job, and have an option to download a PDF version of the job posting. We currently have everything running just fine with cfdocument, but our client is hoping to get the website to 100% compliant with WCAG 2.1.
Currently, i've tried using cfdocument, then using cfPDF to set things like title, as mentioned by Raymond Camden in ColdFusion 8: Working with PDFs (Part 2) but this doesn't seem to work anymore as the downloaded documents don't keep the set information.
The other issue is the PDF isn't marked as a PDF (apparently a flaw with cfdocument Adobe has no plans to fix).
We've tried cfhtmltopdf, but we require headers and footers for each page, and as many have pointed out on various forums, Adobe's implementation is a joke.
So, my question now is, what is the best route to creating a fully compliant PDF from Coldfusion (3rd party options are a route we are willing to take if needed) Ideally we would want the direct download like CFDocument, but we are not opposed to having a physical file created for each job posting if it means having a compliant PDF.
Our code, after all the body content, looks as follows (again this doesn't set the title, language or tag as PDF, and doesn't allow alt tags on our images for some reason).
<cfheader name="Content-Disposition" value="attachment;filename=filename.pdf">
<cfheader name="Content-Language" value="#session.language.code#" />
<cfdocument name="myPDF" format="pdf" orientation="portrait" pageType="custom" pageWidth="8.5" pageHeight="10.75" unit="in" localUrl="yes" marginbottom="1.5" margintop="1" marginleft="0.25" marginright="0.25">
***
***
***
***
<cfset PDFinfo=StructNew()>
<cfset PDFinfo.Title="#returnStruct.JobDetails.title#">
<cfset PDFinfo.Language = 'EN-US' />
<CFIF returnStruct.JobDetails.anonymous EQ 0>
<cfset PDFinfo.Author="#returnStruct.JobDetails.Organization#">
<CFELSE>
<cfset PDFinfo.Author="Employment Agency Name">
</CFIF>
<cfpdf action="setInfo" source="myPDF" info="#PDFinfo#">
<cfpdf action="write" source="myPDF" name='myPDF' version="1.4">
<cfcontent type="application/pdf" reset="true" variable="#toBinary(myPDF)#">

CasperJS: How to read filename from headers when downloading?

I'm using CasperJS to download a file. I need to extract the filename from the HTTP Response headers (i.e. Content-disposition: attachment;filename="pronk.txt"). There is no way to determine the filename from the URL itself (points to a database hash) or the hyperlink (just says "click here").
CasperJS has a great built-in download() function, however it requires a user-supplied filename. This parameter is not optional, and the download fails without it.
Is there another way to go about this where I can get the file data AND the HTTP headers?

Automate a button click on chrome://extensions page using selenium webdriver

I'm trying to write an automated test that will automate the process of updating a google chrome extension. I'm not aware of another method of doing this automatically so here is what I'm currently trying to do:
Open the chrome extensions page (as far as I'm aware this is just an html page unless I'm missing something).
Click on the "Update extensions" button
Here is what I have tried having opened the chrome extensions page:
IwebElement UpdateButton = driver.findelement(By.Id("update-extensions-now"));
UpdateButton.Click();
For some reason the button click is not registering. I have tried some other locators such as CSS path and Xpath but they don't work either. Also, when I debug this test, it passes fine so I know it's not an issue with any of my locators. I have (as a test) tried to automate clicks on the other elements on this page and it's the same issue. I can't get a handle on any elements on the chrome://extensions page at all.
Has anyone encountered this or have any ideas as to what's going on?
You can use the Chrome extensions API to auto-update required extension.
Find the file "manifest.json" in the default Google Chrome
C:\Users\*UserName*\AppData\Local\Google\Chrome\User Data\Default\Extensions
There find the update URL of your extension:
{
"name": "My extension",
...
"update_url": "http://myhost.com/mytestextension/updates.xml",
...
}
The returned XML by the Google server looks like:
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='yourAppID'>
<updatecheck codebase='http://myhost.com/mytestextension/mte_v2.crx' version='2.0' />
</app>
</gupdate>
appid
The extension or app ID, generated based on a hash of the public key, as described in Packaging. You can find the ID of an extension or Chrome App by going to the Extensions page (chrome://extensions).
codebase
A URL to the .crx file.
version
Used by the client to determine whether it should download the .crx file specified by codebase. It should match the value of "version" in the .crx file's manifest.json file.
The update manifest XML file may contain information about multiple extensions by including multiple elements.
Another option is to use the --extensions-update-frequency command-line flag to set a more frequent interval in seconds. For example, to make checks run every 45 seconds, run Google Chrome like this:
chrome.exe --extensions-update-frequency=45
Note that this affects checks for all installed extensions and apps, so consider the bandwidth and server load implications of this. You may want to temporarily uninstall all but the one you are testing with, and should not run with this option turned on during normal browser usage.
The request to update each individual extension would be:
http://test.com/extension_updates.php?x=id%3DyourAppID%26v%3D1.1
You can find even more detailed information on exntesions developers site: https://developer.chrome.com/extensions
If you look at the HTML of the "chrome://extensions" page you will notice that the "Update extensions now" button is contained within an iframe. You need to switch to the iframe before trying to register a button click. i.e:
(This is in c#. Note that this code is written from memory so it may not be 100% accurate. Also, you will want to write more robust method. This code just quickly demonstrates that by switching to the iframe, it will work ok)
String ChromeExtensionsPage = "chrome://extensions";
driver.Navigate().GoToUrl(ChromeExtensionsPage);
driver.Switchto().Frame("DesiredFrame");
IwebElement UpdateButton = driver.findelement(By.Id("DesiredButtonID"));
UpdateButton.Click();

Access MHT File from Solution Directory in Windows 8.1 App

I have an MHT (Microsoft web archive) file that I have added to my project folder. I need this file to display in a WebView on a help page. I have set the file's build action to "Content," like this question reccomended. I then use this code in the page's Loaded event handler.
Try
Dim strHelpNavigate = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.ToString(), "\MyAppsHelp.mht")
webHelp.Navigate(New Uri(strHelpNavigate))
Catch ex As Exception
webHelp.NavigateToString("<html><head><style>body {font-family: segoe ui; color: white; background-color: black;}</style></head><body><h2>Sorry, the help page is currently unavailable.</h2></body></html>")
End Try
This code produces an exception: {"Invalid URI: The format of the URI could not be determined."}
I have also tried passing "\MyAppsHelp.mht" to the Navigate method like this question reccomended, but this produces the same exception, and I see from the Local window that the string passed to the Navigate method is the same either way.
Does anyone have any advice on how to display this file in the WebView?
WebView does not natively support HTML archive files, but you can do the work convert these files to html + images if you're so inclined.
Open the .mht file in notepad, and you'll see that there are separate sections for each part of the HTML file - you can parse these sections to get the HTML out, then the base64 encoded images, then save them in your local app folder and use WebView.NavigateToLocalStreamUri to load them. See http://blogs.msdn.com/b/wsdevsol/archive/2014/06/20/a-primer-on-webview-navigatetolocalstreamuri.aspx for details on how to use this method.
OF course, if it's a static file that you will be using all of the time, it would be far easier to just convert it before packaging the app.

Why can't I attach my uploaded file to an email?

I have a form with a file input:
<input type="file" id="uploadFile" name="uploadFile" />
I submit the form using the ajaxForm method of the JQuery form plugin.
Then, in the code to handle the post, I read and process the file. I use cfspreadsheet to read the file directly from the file input field:
<cfspreadsheet
action="read"
src="#form.uploadFile#"
sheet="1"
query="spreadsheetData"
headerRow="1"
excludeHeaderRow="true"
>
This all works correctly.
I decided that I want to email the spreadsheet to the administrator as well. I thought I could accomplish this simply with a cfmail tag that includes the following cfmailparam tag:
<cfmail to="myEmailAddress#email.com"
from="fromEmail#email.com"
subject="Upload File" type="HTML">
<cfmailparam file="#form.uploadFile#" />
File processed successfully
</cfmail>
However, this is not working correctly - the email is not sent. What am I doing wrong?
Leigh's solution works well and you have probably already implemented in your code. I thought I'd put my 0.02 cents in about why this is a problem to begin with.
When you upload a file the file is placed in a temp folder location. If you do nothing with the file to put it in a final destination the file is deleted - probably at the end of your request.
Meanwhile the cfmailparam does not actually attach the file at runtime. It leaves it to the spooler process to do that. If you take a look in your ColdFusion installs "mail/spool" directory you will see a file with .cfmail extension. If you can't "catch" one before delivery check your undeliverable folder - there's bound to be a few hanging around in there.
The .cfmail file serves as an instruction to the spooler service which sends the mail. It has a subject, from, to, server address, body etc.
If you attach a file you will see something at the bottom of this file that looks like this:
file: D:\jrun\temp\blah.tmp
file-type: application/octet-stream; name="I am the file you uploaded.tmp"
file-disposition: attachment
remove: false
At runtime CF grabs this file and does what Leigh is suggesting - places it as binary with a mailpart (base64 encoded) into the main body of the message. So what is happening is that by the time the spooler service gets around to attempting to open and attach this file the file is long gone because the request has ended. I also think that the file exists with a ".tmp" extension in this temporary directory - which is obviously not what you want to attach (but that could be a previous version of CF).
To fix it, first use cffile with the "upload" action to put the file in a real (instead of temporary) folder on the disk. Then use cfmailparam to attach the file. NOTE: The "remove" attribute set to yes will cause CF to delete the file once it has successfully sent the mail - which is the effect I believe you are looking for.