There are actually several PHP files that work in conjunction with WaterMarkScript. They should be together in the same subdirectory of public_html.
Either in the same directory or a parent directory, there must be a .htaccess
file with contents combining the requirements of HtaccessForPHP and RequireUseridsForSecureWebAccess.
This just defines some functions and variables common to both index.php
and requestAssgnSolnGet.php
.
The file list array has to be populated with all files available to WaterMarkScript currently; see the commented example for what to pattern. A relatively straightforward enhancement should be just to read all subdirectories of the watermark script directory, since that script is hardcoded to look there anyway; this would save a step whenever updating available solutions.
Note that to allow feeding of special file types (such as PDF), there cannot be any whitespace in this file. Otherwise, PHP will immediately and automatically feed appropriate headers for an HTML page, messing up the delivery of PDF data.
<?php require('permissions.php'); function control_access($user) { ensure_permissions($user, array('student', 'ta', 'ia', 'tutor', 'isc', 'instructor')); } function cond_include($path_minus_ext) { if (file_exists($path_minus_ext.'.php')) { include($path_minus_ext.'.php'); } else if (file_exists($path_minus_ext.'.shtml')) { include($path_minus_ext.'.shtml'); } } $stuserid=$_SERVER['REMOTE_USER']; // The userid of whoever is logged on # Get userid of the account too. $me=posix_getpwuid(posix_getuid()); $me=$me['name']; $filesdir="/u/$me/protectPDF"; $file_list=array( // An associative array of filename => description #'f06final'=>'Final Exam: Fall 2006', ); ?>
It should be possible for $file_list
to be built automatically.
It could scan the same directory as WaterMarkScript (so this directory may as well be provided by this include also) and add every directory to this list.
There should be no clear disadvantage to doing this, and the advantage is that nobody has to remember to update this separate file every time there's a new PDF uploaded.
The entry point for the page. It displays to students the conditions for downloading the file, and displays a table which allows them to select any files they wish to download.
#!/usr/bin/env php-cgi <?php require("requestAssgnSolnCommon.php"); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> <style type="text/css"> <!-- th {text-align: left;} --> </style> <title><?php echo $me ?>: Assignment Solution Request</title> <?php cond_include('/u/' . $me . '/public_html/standard_style'); ?> </head> <body> <?php cond_include('/u/' . $me . '/public_html/standard_init'); ?> <?php control_access($stuserid); ?> <p>The files listed below are "protected", meaning that they are not to be shared. By clicking on one of the links below, you agree to the following statements:</p> <ul> <li>My userid is <code><?php echo "$stuserid"; ?></code>.</li> <li>I am a student in CS 135 in the Winter 2010 term.</li> <li>I will not share these files with anyone else, and I will delete all my copies of them at the end of the Winter 2010 term. It is my responsibility to ensure that no one else has access to these files.</li> <li>I agree to the collection of my userid, IP address, and the current time. </li> </ul> <br /> <?php echo "<table width=75%><tr><th>Description</th> <th>Filename</th> <th>Last updated</th></tr>"; foreach($file_list as $fname=>$desc) { echo "<tr><td>$desc</td> <td><a href='requestAssgnSolnGet.php?f=$fname'>$fname.pdf</a></td> <td>".date('g:ia F j',filemtime("$filesdir/$fname/$fname.pdf"))."</td></tr>"; } echo "</table>"; #foot(); ?> <br /> <p>Generating your PDF file takes some time; please be patient.</p> <?php cond_include('/u/' . $me . '/public_html/standard_fini'); ?> </body> </html>
This page currently serves up quite invalid XHTML 1, and this should be fixed by anybody who has the time.
This file actually feeds the PDF file, attempting to die gracefully if it cannot. This is the script that's dependent on the WaterMarkScript to generate the PDF for it. Note that the PDF generation is not done on the web server; as a general rule, heavy work should not be done on the web server to try to help ensure good response to all requests.
#!/usr/bin/env php-cgi <?php require("requestAssgnSolnCommon.php"); control_access($stuserid); function begin_msg () { echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'; echo "\n"; echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'; echo '<head><meta http-equiv="Content-type" content="text/html;charset=UTF-8" /><title>File not available</title></head>' . "\n"; echo '<body>'; cond_include('/u/' . $me . '/public_html/standard_style'); cond_include('/u/' . $me . '/standard_init'); } function end_msg () { cond_include('/u/' . $me . '/standard_fini'); echo '</body></html>'; } $fname=$_GET['f']; if (!array_key_exists($fname,$file_list)) { begin_msg(); echo "<p>Sorry, no file with the name <code>".htmlspecialchars($fname)."</code> is available.</p>"; echo "<p><a href='https://www.student.cs.uwaterloo.ca/~$me/requestAssgnSoln'>Return to the solutions request page</a>.</p>"; end_msg(); } else { $pdffile=exec("ssh linux.student.cs.uwaterloo.ca \"$filesdir/watermarkalt.sh $fname $stuserid\""); if (file_exists("$pdffile")) { header('Content-Description: File Transfer'); header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename='.$fname.'.pdf'); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Content-Length: ' . filesize("$pdffile")); readfile("$pdffile"); # Remove our temporary file system("rm -f $pdffile"); # Log what happened system("echo \"$stuserid $fname ".$_SERVER['REMOTE_ADDR'].' ' .date('r')."\" >> \"$filesdir/log.txt\""); } else { begin_msg(); echo "<p>An error has occurred in trying to fetch the file <code>" .htmlspecialchars($fname). ".pdf (" .htmlspecialchars($pdffile). ")</code>. Please try again in a few minutes. If it still doesn't work, contact the tutor at <tt>" .htmlspecialchars("$me@student.cs.uwaterloo.ca"). '</tt>.</p>'; end_msg(); } } ?>