Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git

Separates range parsing into own function

AuthorDaveJarvis <email>
Date2023-11-11 14:20:48 GMT-0800
Commit32d4eef4862f184b864df8b6af2afcc32b63aae9
Parent98a9107
Delta41 lines added, 30 lines removed, 11-line increase
www/downloads/counter.php
$size = $size === false || empty( $size ) ? 0 : $size;
$content_type = mime_content_type( $filename );
- $content_length = $size;
- $seek_start = 0;
+ list( $seek_start, $content_length ) = parse_range( $size );
// Added by PHP, removed by us.
header_remove( 'x-powered-by' );
+
+ // HTTP/1.1 clients must treat invalid date formats, especially 0, as past.
+ header( 'Expires: 0' );
+
+ // Prevent local caching.
+ header( 'Cache-Control: public, must-revalidate, post-check=0, pre-check=0' );
+
+ // No response message portion may be cached (e.g., by a proxy server).
+ header( 'Cache-Control: private', false );
+
+ // Force the browser to download, rather than displaying the file inline.
+ header( "Content-Disposition: attachment; filename=\"$filename\"" );
+ header( 'Accept-Ranges: bytes' );
+ header( "Content-Length: $content_length" );
+ header( "Content-Type: $content_type" );
+
+ // Honour HTTP HEAD requests.
+ return $_SERVER['REQUEST_METHOD'] === 'HEAD'
+ ? false
+ : transmit( $filename, $seek_start, $size );
+ }
+
+ /**
+ * Parses the HTTP range request header, provided one was sent by the
+ * client. This provides download resume functionality.
+ *
+ * @param int $size The total file size (as stored on disk).
+ *
+ * @return int The starting offset for resuming the download, or 0 to
+ * download the entire file (i.e., no offset could be parsed).
+ */
+ function parse_range( $size ) {
+ // By default, start transmitting at the beginning of the file.
+ $seek_start = 0;
+ $content_length = $size;
// Check if a range is sent by browser or download manager.
header( "Content-Range: bytes */$size" );
- // Return early because the range is invalid.
- return false;
+ // Terminate because the range is invalid.
+ exit;
}
// Multiple ranges could be specified, but only serve the first range.
$seek_start = $matches[ 1 ] + 0;
-
- if( isset( $matches[ 2 ] ) ) {
- $seek_end = $matches[ 2 ] + 0;
- }
- else {
- $seek_end = $size - 1;
- }
+ $seek_end = isset( $matches[ 2 ] ) ? $matches[ 2 ] + 0 : $size - 1;
$range_bytes = $seek_start . '-' . $seek_end . '/' . $size;
$content_length = $seek_end - $seek_start + 1;
header( 'HTTP/1.1 206 Partial Content' );
header( "Content-Range: bytes $range_bytes" );
}
-
- // HTTP/1.1 clients must treat invalid date formats, especially 0, as past.
- header( 'Expires: 0' );
-
- // Prevent local caching.
- header( 'Cache-Control: public, must-revalidate, post-check=0, pre-check=0' );
-
- // No response message portion may be cached (e.g., by a proxy server).
- header( 'Cache-Control: private', false );
-
- // Force the browser to download, rather than displaying the file inline.
- header( "Content-Disposition: attachment; filename=\"$filename\"" );
- header( 'Accept-Ranges: bytes' );
- header( "Content-Length: $content_length" );
- header( "Content-Type: $content_type" );
- // Honour HTTP HEAD requests.
- return $_SERVER['REQUEST_METHOD'] === 'HEAD'
- ? false
- : transmit( $filename, $seek_start, $size );
+ return array( $seek_start, $content_length );
}
+
/**
* Transmits a file from the server to the client.