Web Hosting Forum | Lunarpages

Author Topic: Downloadable files  (Read 7913 times)

Offline MrPhil

  • Senior Moderator
  • Berserker Poster
  • *****
  • Posts: 6231
Downloadable files
« on: December 02, 2016, 10:29:40 AM »
On my site, I have some files that I want to make available to visitors to read and/or download (for free). These include .c, .config, and .exe files. Others will come in the future. Initially, I just put ordinary links to the files on the HTML page:
Code: [Select]
<a href="files/file1.c">file1.c</a>etc. and it worked. Recently I noticed that something had changed on the server, and the text files were now being served up as HTML pages (no download).

So, I added an .htaccess file with
Code: [Select]
<FileMatch "\.(c|config)$">
  ForceType  text/plain
  Header set Content-Disposition  attachment
</FileMatch>
<FileMatch "\.(exe)$">
  ForceType  application/octet-stream
  Header set Content-Disposition  attachment
</FileMatch>

Now, the visitor is asked if they want to open the files (.c and .config) or download them (all). That's fine. The problem is that these flat files (.c and .config) are uploaded to the Linux server as text files, and have their line-ends changed to newlines (\n) rather than CRLF. When downloaded to a Windows machine, the lines are all run together, as the CRLFs are not restored. So, is there any MIME-type or other method to tell the server (or visitor's browser) to convert line-ends to the appropriate local type? I suppose I could either specially (manually) upload these files in BINARY mode (CRLF on the server), but then they won't quite be right on a Linux or Mac, or offer multiple versions (each manually uploaded for each target OS). That seems like a nuisance to have to do. Is there an easier way to tell the system how to download a file correctly?

I also tried application/octet-stream for the text files, but not surprisingly, that didn't help.

Add: One other thing: the .c and .config files get .txt appended to their names when downloaded. I'd like to avoid that.
« Last Edit: December 02, 2016, 04:29:34 PM by MrPhil »
Visit My Site

E-mail Me
  
-= From the ashes shall rise a sooty tern =-

Offline MrPhil

  • Senior Moderator
  • Berserker Poster
  • *****
  • Posts: 6231
Re: Downloadable files
« Reply #1 on: January 24, 2017, 02:19:46 PM »
I have decided to change tack here, and call a download.php module to handle sending out HTTP headers (Content-Type, etc.) and using readfile(file-path) to read and output the file to the browser. It will also track the download count.

This brings up an opportunity to better handle text (human-readable) files, such as C source, configuration files, etc. These files are uploaded to the Linux server in ASCII mode, and so have newline (\n) end-of-lines. When downloaded as application/octet-stream, it runs lines together on Windows. I haven't been able to find any HTTP header that promises to determine the receiver's operating system and appropriately translate the end-of-lines. Does anyone know of one? All files are force-download, and I have manually marked a file as text in the download call -- I'm not trying to automate detection of it. Everything else is binary (application/octet-stream).

I suppose I can read the file into PHP (either a line at a time, or one chunk using readfile... human readable files shouldn't be too large). Then do a str_replace \n to \r\n or \r depending on $_SERVER['HTTP_USER_AGENT']. Something like

Code: [Select]
$agent = $_SERVER['HTTP_USER_AGENT'];
if     (preg_match('/Windows/', $agent)) { translate to \r\n }
elseif (preg_match('/Mac OS X/', $agent)) { leave \n alone }
elseif (preg_match('/Macintosh/', $agent)) { translate to \r for OS 9 and earlier }
else { leave \n alone for all Linux, AIX, Unix, etc. }

After end-of-line translation, print to the browser as application/octet-stream. Is there an easier/cleaner way to do this? More importantly, are there other combinations to check, such as Windows Phone, or a later Mac than OS X? Has anyone come across a good online list?

Update: other than using file_get_contents to read the file, the above seems to work, at least for Windows. I'll have to wait until the new function goes live and anyone reports that text files aren't downloading correctly, to fix it for non-Windows downloads. It still would be good to know if all "Windows" agents imply CRLF line ends, etc. I also have no idea of the different Mac flavors I still need to deal with.
« Last Edit: January 25, 2017, 07:44:21 PM by MrPhil »
Visit My Site

E-mail Me
  
-= From the ashes shall rise a sooty tern =-

 

Share |