mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Simplify AcceptPreferenceParser.
This commit is contained in:
parent
0bd73115cc
commit
4aed8c8b4c
@ -5,52 +5,37 @@ import {
|
|||||||
parseAcceptCharset,
|
parseAcceptCharset,
|
||||||
parseAcceptEncoding,
|
parseAcceptEncoding,
|
||||||
parseAcceptLanguage,
|
parseAcceptLanguage,
|
||||||
|
parseAcceptDateTime,
|
||||||
} from '../../util/HeaderUtil';
|
} from '../../util/HeaderUtil';
|
||||||
import type { RepresentationPreferences } from '../representation/RepresentationPreferences';
|
import type { RepresentationPreferences } from '../representation/RepresentationPreferences';
|
||||||
import { PreferenceParser } from './PreferenceParser';
|
import { PreferenceParser } from './PreferenceParser';
|
||||||
|
|
||||||
|
const parsers: {
|
||||||
|
name: keyof RepresentationPreferences;
|
||||||
|
header: string;
|
||||||
|
parse: (value: string) => AcceptHeader[];
|
||||||
|
}[] = [
|
||||||
|
{ name: 'type', header: 'accept', parse: parseAccept },
|
||||||
|
{ name: 'charset', header: 'accept-charset', parse: parseAcceptCharset },
|
||||||
|
{ name: 'encoding', header: 'accept-encoding', parse: parseAcceptEncoding },
|
||||||
|
{ name: 'language', header: 'accept-language', parse: parseAcceptLanguage },
|
||||||
|
{ name: 'datetime', header: 'accept-datetime', parse: parseAcceptDateTime },
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts preferences from the accept-* headers from an incoming {@link HttpRequest}.
|
* Extracts preferences from the Accept-* headers from an incoming {@link HttpRequest}.
|
||||||
* Supports Accept, Accept-Charset, Accept-Encoding, Accept-Language and Accept-DateTime.
|
* Supports Accept, Accept-Charset, Accept-Encoding, Accept-Language and Accept-DateTime.
|
||||||
*/
|
*/
|
||||||
export class AcceptPreferenceParser extends PreferenceParser {
|
export class AcceptPreferenceParser extends PreferenceParser {
|
||||||
public constructor() {
|
public async handle({ headers }: HttpRequest): Promise<RepresentationPreferences> {
|
||||||
super();
|
const preferences: RepresentationPreferences = {};
|
||||||
}
|
for (const { name, header, parse } of parsers) {
|
||||||
|
const value = headers[header];
|
||||||
public async handle(input: HttpRequest): Promise<RepresentationPreferences> {
|
if (typeof value === 'string') {
|
||||||
const result: RepresentationPreferences = {};
|
preferences[name] = Object.fromEntries(parse(value)
|
||||||
const headers:
|
.map(({ range, weight }): [string, number] => [ range, weight ]));
|
||||||
{ [T in keyof RepresentationPreferences]: { val?: string; func: (inp: string) => AcceptHeader[] }} = {
|
|
||||||
type: { val: input.headers.accept, func: parseAccept },
|
|
||||||
charset: { val: input.headers['accept-charset'] as string, func: parseAcceptCharset },
|
|
||||||
encoding: { val: input.headers['accept-encoding'] as string, func: parseAcceptEncoding },
|
|
||||||
language: { val: input.headers['accept-language'], func: parseAcceptLanguage },
|
|
||||||
};
|
|
||||||
(Object.keys(headers) as (keyof RepresentationPreferences)[]).forEach((key): void => {
|
|
||||||
const preferences = this.parseHeader(headers[key]!.func, headers[key]!.val);
|
|
||||||
if (preferences.length > 0) {
|
|
||||||
result[key] = Object.fromEntries(preferences);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Accept-DateTime is currently specified to simply have a datetime as value
|
|
||||||
if (input.headers['accept-datetime']) {
|
|
||||||
result.datetime = { [input.headers['accept-datetime'] as string]: 1 };
|
|
||||||
}
|
}
|
||||||
|
return preferences;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a header string using the given parse function to {@link RepresentationPreference}[].
|
|
||||||
* @param input - Input header string.
|
|
||||||
* @param parseFunction - Function that converts header string to {@link AcceptHeader}.
|
|
||||||
*
|
|
||||||
* @returns A list of preferences. Returns an empty list if input was not defined.
|
|
||||||
*/
|
|
||||||
private parseHeader(parseFunction: (input: string) => AcceptHeader[], input?: string): [string, number][] {
|
|
||||||
return (input ? parseFunction(input) : [])
|
|
||||||
.map(({ range, weight }): [string, number] => [ range, weight ]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,11 @@ export interface AcceptEncoding extends AcceptHeader { }
|
|||||||
*/
|
*/
|
||||||
export interface AcceptLanguage extends AcceptHeader { }
|
export interface AcceptLanguage extends AcceptHeader { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contents of an HTTP Accept-Datetime header.
|
||||||
|
*/
|
||||||
|
export interface AcceptDatetime extends AcceptHeader { }
|
||||||
|
|
||||||
// REUSED REGEXES
|
// REUSED REGEXES
|
||||||
const token = /^[a-zA-Z0-9!#$%&'*+-.^_`|~]+$/u;
|
const token = /^[a-zA-Z0-9!#$%&'*+-.^_`|~]+$/u;
|
||||||
|
|
||||||
@ -248,10 +253,10 @@ const parseAcceptPart = (part: string, replacements: Record<string, string>): Ac
|
|||||||
*
|
*
|
||||||
* @returns An array of ranges and weights.
|
* @returns An array of ranges and weights.
|
||||||
*/
|
*/
|
||||||
const parseNoParameters = (input: string): { range: string; weight: number }[] => {
|
const parseNoParameters = (input: string): AcceptHeader[] => {
|
||||||
const parts = splitAndClean(input);
|
const parts = splitAndClean(input);
|
||||||
|
|
||||||
return parts.map((part): { range: string; weight: number } => {
|
return parts.map((part): AcceptHeader => {
|
||||||
const [ range, qvalue ] = part.split(';').map((param): string => param.trim());
|
const [ range, qvalue ] = part.split(';').map((param): string => param.trim());
|
||||||
const result = { range, weight: 1 };
|
const result = { range, weight: 1 };
|
||||||
if (qvalue) {
|
if (qvalue) {
|
||||||
@ -357,6 +362,16 @@ export const parseAcceptLanguage = (input: string): AcceptLanguage[] => {
|
|||||||
return results;
|
return results;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an Accept-DateTime header string.
|
||||||
|
*
|
||||||
|
* @param input - The Accept-DateTime header string.
|
||||||
|
*
|
||||||
|
* @returns An array with a single {@link AcceptDatetime} object.
|
||||||
|
*/
|
||||||
|
export const parseAcceptDateTime = (input: string): AcceptDatetime[] =>
|
||||||
|
[{ range: input, weight: 1 }];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a header value without overriding previous values.
|
* Adds a header value without overriding previous values.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user