header-middleware-next
Version:
A lightweight and flexible middleware utility for managing HTTP headers in Next.js applications. Supports header extraction, transformation, masking, and safe injection for Edge and API routes.
76 lines (70 loc) • 2.53 kB
JavaScript
/**
* Function to validate the Accept-Language header in an HTTP request.
* It checks for presence, character validity, and a basic pattern compliance
* to ensure the header follows expected language tag syntax.
*
* @param {Object} req - The HTTP request object with headers.
* @returns {Object} - An object describing the validation status with type, name, message, and meta.
*/
export default async function checkAcceptLanguage(req) {
// Retrieve and trim the Accept-Language header, default to empty string if missing.
const lang = req.headers?.['accept-language']?.trim() || '';
// Warn if the Accept-Language header is missing.
if (!lang) {
return {
type: 'warning',
name: 'Accept-Language',
message: 'Missing Accept-Language header',
meta: {
'accept-language': '',
category: 'missing'
}
};
}
/**
* Regex to detect any invalid characters that should not appear in
* Accept-Language header values. Valid characters include letters, digits,
* hyphens, commas, semicolons, dots, equals signs, and spaces.
*/
const invalidPattern = /[^\w\-\,;\.= ]/;
if (invalidPattern.test(lang)) {
return {
type: 'error',
name: 'Accept-Language',
message: `Invalid characters in Accept-Language header: ${lang}`,
meta: {
'accept-language': lang,
category: 'malformed'
}
};
}
/**
* Basic pattern to validate common Accept-Language header format.
* It allows language tags with optional regional subtags and quality values (q=).
* This pattern does not fully comply with RFC 2616 but covers typical usage.
*/
const languagePattern = /^([a-zA-Z]{2,3}(-[a-zA-Z]{2})?(;q=\d(\.\d{1,3})?)?)(,\s*[a-zA-Z]{2,3}(-[a-zA-Z]{2})?(;q=\d(\.\d{1,3})?)?)*$/;
const isLikelyValid = languagePattern.test(lang);
// Warn if the header does not match expected language pattern but isn't malformed.
if (!isLikelyValid) {
return {
type: 'warning',
name: 'Accept-Language',
message: `Unusual Accept-Language format: ${lang}`,
meta: {
'accept-language': lang,
category: 'unusual'
}
};
}
// Return success if the Accept-Language header is present and matches expected pattern.
return {
type: 'success',
name: 'Accept-Language',
message: 'Valid Accept-Language header',
meta: {
'accept-language': lang,
category: 'valid'
}
};
}