Skip to content

Commit

Permalink
feat: add gzip compression for responses
Browse files Browse the repository at this point in the history
  • Loading branch information
fvsch committed Oct 9, 2024
1 parent d6fccf0 commit d65e676
Show file tree
Hide file tree
Showing 12 changed files with 458 additions and 345 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ servitsy --ext '.html' # default
servitsy --ext '.xhtml' --ext '.html'
```

### `gzip`

Enables gzip compression for text files. Defaults to `true`.

```sh
# Enable (default)
servitsy --gzip
servitsy --gzip true

# Disable
servitsy --gzip false
```

### `header`

Add custom HTTP headers to responses, for all files or specific file patterns. Headers can be provided using a `header:value` syntax, or as a JSON string:
Expand Down
3 changes: 2 additions & 1 deletion lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export async function run() {
return;
}

const { errors, options } = serverOptions({}, args);
const { errors, options } = serverOptions({ args });

if (errors.length) {
logger.writeErrors(errors);
Expand Down Expand Up @@ -203,6 +203,7 @@ export function helpPage() {
'port',
'header',
'cors',
'gzip',
'ext',
'dirFile',
'dirList',
Expand Down
11 changes: 9 additions & 2 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ export const HOSTS_WILDCARD = Object.freeze({
v6: '::',
});

export const MAX_COMPRESS_SIZE = 50_000_000;

/** @type {PortsConfig} */
export const PORTS_CONFIG = Object.freeze({
initial: 8080,
count: 10,
countLimit: 100,
});

/** @type {string[]} */
export const SUPPORTED_METHODS = ['GET', 'HEAD', 'OPTIONS', 'POST'];
/** @type {readonly string[]} */
export const SUPPORTED_METHODS = Object.freeze(['GET', 'HEAD', 'OPTIONS', 'POST']);

/** @type {Record<OptionName, OptionSpec>} */
export const CLI_OPTIONS = Object.freeze({
Expand Down Expand Up @@ -59,6 +61,11 @@ export const CLI_OPTIONS = Object.freeze({
argDefault: EXTENSIONS_DEFAULT.join(', '),
help: 'Extensions which can be omitted in URLs',
},
gzip: {
args: ['--gzip'],
argDefault: 'true',
help: 'Use gzip compression for text files',
},
header: {
args: ['--header'],
help: 'Add custom HTTP header(s) to responses',
Expand Down
22 changes: 9 additions & 13 deletions lib/content-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const BIN_TYPES = {
suffix: [],
};

class TypeResult {
export class TypeResult {
/** @type {'text' | 'bin' | 'unknown'} */
group = 'unknown';

Expand Down Expand Up @@ -237,25 +237,21 @@ export async function typeForFile(fileHandle, charset) {
}

/**
* @param {{ filePath?: string; fileHandle?: import('node:fs/promises').FileHandle; charset?: string | null }} data
* @returns {Promise<string>}
* @param {{ filePath?: string; fileHandle?: import('node:fs/promises').FileHandle }} data
* @returns {Promise<TypeResult>}
*/
export async function getContentType({ filePath, fileHandle, charset }) {
export async function getContentType({ filePath, fileHandle }) {
if (filePath) {
const result = typeForFilePath(filePath, charset);
const result = typeForFilePath(filePath);
if (result.group !== 'unknown') {
return result.toString();
return result;
}
}

if (fileHandle) {
const result = await typeForFile(fileHandle, charset);
if (result.group !== 'unknown') {
return result.toString();
}
const result = await typeForFile(fileHandle);
return result;
}

return BIN_TYPES.default;
return new TypeResult().unknown();
}

/**
Expand Down
Loading

0 comments on commit d65e676

Please sign in to comment.