Download Header Builder
Builds safe headers for attachment or inline file downloads.
Function signature
ogBuildDownloadHeaders(filename, content_type = 'application/octet-stream', size_bytes = 0, disposition = 'attachment')
Categories
- Security
Parameters
filenameCaller-supplied value used for filename processing.content_typeString value for content type processing.size_bytesInteger value controlling size bytes.dispositionString value for disposition processing.Return value
Public-safe status string returned by the function.
- success
- message
- data
Compatibility
Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.
Minimum PHP version: 7.4
Security notes
Use caller-owned allowlists and procedural mysqli prepared execution where SQL plans are returned; validate file paths, MIME policies, and permissions before file or download workflows.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Builds safe headers for attachment or inline file downloads.
*
* Primary use case: Digital products and exports.
* Typical inputs: filename, content type, size, disposition.
* Typical output: header list.
*
* Implementation note: Sanitize filenames and avoid header injection.
*
* @return array Structured result data with success, message, and data keys.
*/
function ogBuildDownloadHeaders($filename, $content_type = 'application/octet-stream', $size_bytes = 0, $disposition = 'attachment') {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
$filename = basename((string)$filename);
$content_type = trim((string)$content_type);
$size_bytes = (int)$size_bytes;
$disposition = strtolower(trim((string)$disposition));
if (empty($filename)) {
$result['message'] = 'Filename is required.';
return $result;
}
$filename = preg_replace('/[^a-zA-Z0-9._-]+/', '-', $filename);
$filename = trim($filename, '.-');
if (empty($filename)) {
$result['message'] = 'Filename is not safe after cleaning.';
return $result;
}
if (!preg_match('/^[a-z0-9.+-]+\/[a-z0-9.+-]+$/i', $content_type)) {
$content_type = 'application/octet-stream';
}
if ($disposition != 'attachment' && $disposition != 'inline') {
$disposition = 'attachment';
}
$headers = array();
$headers[] = 'Content-Type: ' . $content_type;
$headers[] = 'Content-Disposition: ' . $disposition . '; filename="' . $filename . '"';
$headers[] = 'X-Content-Type-Options: nosniff';
if ($size_bytes > 0) {
$headers[] = 'Content-Length: ' . $size_bytes;
}
$result['success'] = true;
$result['message'] = 'Download headers built.';
$result['data'] = array(
'filename' => $filename,
'content_type' => $content_type,
'disposition' => $disposition,
'headers' => $headers
);
return $result;
}