
send v4.1.1
Fork des send-Moduls zur Behandlung von CVE-2017-20165
@fastify/send
Send ist eine Bibliothek zum Streamen von Dateien aus dem Dateisystem als HTTP-Antwort. Sie unterstützt partielle Antworten (Ranges), Conditional-GET-Aushandlung (If-Match, If-Unmodified-Since, If-None-Match, If-Modified-Since), hohe Testabdeckung und granulare Ereignisse, die genutzt werden können, um in deiner Anwendung oder deinem Framework geeignete Maßnahmen zu ergreifen.
Installation
Dies ist ein Node.js-Modul, das über die
npm-Registry verfügbar ist. Die Installation erfolgt mit dem
npm install-Befehl:
$ npm install @fastify/send
TypeScript
@types/mime@3 muss verwendet werden, wenn TypeScript genutzt werden soll;
@types/mime@4 hat die mime-Typen entfernt.
$ npm install -D @types/mime@3
API
const send = require('@fastify/send')
send(req, path, [options])
Liefert statusCode, headers und stream für den angegebenen Pfad, um sie an eine
res zu senden. req ist die Node.js-HTTP-Anfrage und path ist ein urlencodierter Pfad,
der gesendet werden soll (urlencodiert, nicht der tatsächliche Dateisystempfad).
Optionen
acceptRanges
Aktiviert oder deaktiviert die Annahme von Bereichsanfragen (Range Requests), Standardwert ist true.
Wenn dies deaktiviert ist, wird Accept-Ranges nicht gesendet und der Inhalt
des Range-Anfrageheaders ignoriert.
cacheControl
Aktiviert oder deaktiviert das Setzen des Cache-Control-Antwortheaders, Standardwert ist
true. Wenn dies deaktiviert ist, werden die Optionen immutable und maxAge ignoriert.
contentType
Standardmäßig verwendet diese Bibliothek das mime-Modul, um den Content-Type
der Antwort basierend auf der Dateierweiterung der angeforderten Datei zu setzen.
Um diese Funktionalität zu deaktivieren, setze contentType auf false.
Der Content-Type-Header muss bei Deaktivierung manuell gesetzt werden.
dotfiles
Legt fest, wie mit „Dotfiles“ umgegangen wird, wenn sie auftreten. Eine Dotfile ist eine Datei
oder ein Verzeichnis, das mit einem Punkt („.“) beginnt. Beachte, dass diese Prüfung am
Pfad selbst erfolgt, ohne zu prüfen, ob der Pfad auf der Festplatte existiert.
Wenn root angegeben ist, werden nur die Dotfiles oberhalb des Roots geprüft
(d. h. der Root selbst kann sich innerhalb einer Dotfile befinden, wenn
auf „deny“ gesetzt).
'allow'Keine besondere Behandlung für Dotfiles.'deny'Sende einen 403 für jede Anfrage nach einer Dotfile.'ignore'Tue so, als ob die Dotfile nicht existiert, und sende 404.
Der Standardwert ist ähnlich zu 'ignore', mit der Ausnahme, dass
dieser Standard die Dateien innerhalb eines Verzeichnisses, das mit einem Punkt beginnt,
nicht ignoriert, aus Gründen der Abwärtskompatibilität.
end
Byte-Offset, an dem der Stream endet, Standardwert ist die Länge der Datei
minus 1. Das Ende ist im Stream inklusiv, d. h. end: 3 schließt das
4. Byte im Stream ein.
etag
Aktiviert oder deaktiviert die ETag-Erzeugung, Standardwert ist true.
extensions
Wenn eine bestimmte Datei nicht existiert, versuche, eine der angegebenen Erweiterungen
in der angegebenen Reihenfolge anzuhängen. Standardmäßig ist dies deaktiviert (auf false gesetzt). Ein
Beispielwert, der erweiterungslose HTML-Dateien ausliefert: ['html', 'htm'].
Dies wird übersprungen, wenn die angeforderte Datei bereits eine Erweiterung hat.
immutable
Aktiviert oder deaktiviert die immutable-Direktive im Cache-Control-Antwortheader,
Standardwert ist false. Wenn auf true gesetzt, sollte auch die Option maxAge
angegeben werden, um Caching zu ermöglichen. Die immutable-Direktive verhindert,
dass unterstützte Clients während der Gültigkeitsdauer der maxAge-Option bedingte Anfragen
stellen, um zu prüfen, ob sich die Datei geändert hat.
index
Standardmäßig unterstützt send „index.html“-Dateien. Um dies zu deaktivieren,
setze false, oder um ein neues Index zu übergeben, übergib einen String oder ein Array
in bevorzugter Reihenfolge.
lastModified
Aktiviert oder deaktiviert den Last-Modified-Header, Standardwert ist true. Verwendet den
letzten Änderungszeitpunkt des Dateisystems.
maxAge
Gib ein max-age in Millisekunden für HTTP-Caching an, Standardwert ist 0. Dies kann auch ein String sein, der vom ms-Modul akzeptiert wird.
maxContentRangeChunkSize
Gib die maximale Antwortinhaltgröße an, Standardwert ist die gesamte Dateigröße.
Dies wird verwendet, wenn acceptRanges true ist.
root
Stellt Dateien relativ zu path bereit.
start
Byte-Offset, an dem der Stream beginnt, Standardwert ist 0. Der Start ist inklusiv,
d. h. start: 2 schließt das 3. Byte im Stream ein.
highWaterMark
Wenn angegeben, setzt diese Option die maximale Anzahl von Bytes, die der interne Puffer hält, bevor das Lesen von der zugrunde liegenden Ressource pausiert wird. Wenn du diese Option weglässt (oder undefined übergibst), verwendet Node.js seinen eingebauten Standardwert für lesbare Binär-Streams.
.mime
Der mime-Export ist die globale Instanz des
mime-npm-Moduls.
Dies wird verwendet, um die MIME-Typen zu konfigurieren, die mit Dateierweiterungen verknüpft sind, sowie weitere Optionen zur Auflösung des MIME-Typs einer Datei (wie den Standardtyp, der für eine unbekannte Dateierweiterung verwendet werden soll).
Caching
Es führt kein internes Caching durch. Du solltest dafür einen Reverse-Proxy-Cache wie Varnish verwenden oder diese ausgefallenen Dinger namens CDNs. Wenn deine Anwendung klein genug ist, um von Single-Node-Speicher-Caching zu profitieren, ist sie klein genug, dass sie überhaupt kein Caching benötigt ;).
Debugging
Um die debug()-Instrumentierungsausgabe zu aktivieren, exportiere NODE_DEBUG:
$ NODE_DEBUG=send node app
Tests ausführen
$ npm install
$ npm test
Beispiele
Eine bestimmte Datei bereitstellen
Dieses einfache Beispiel sendet eine bestimmte Datei an alle Anfragen.
const http = require('node:http')
const send = require('send')
const server = http.createServer(async function onRequest (req, res) {
const { statusCode, headers, stream } = await send(req, '/path/to/index.html')
res.writeHead(statusCode, headers)
stream.pipe(res)
})
server.listen(3000)
Alle Dateien aus einem Verzeichnis bereitstellen
Dieses einfache Beispiel stellt einfach alle Dateien in einem
bestimmten Verzeichnis als oberste Ebene bereit. Zum Beispiel sendet eine Anfrage
GET /foo.txt den Inhalt von /www/public/foo.txt zurück.
const http = require('node:http')
const parseUrl = require('parseurl')
const send = require('@fastify/send')
const server = http.createServer(async function onRequest (req, res) {
const { statusCode, headers, stream } = await send(req, parseUrl(req).pathname, { root: '/www/public' })
res.writeHead(statusCode, headers)
stream.pipe(res)
})
server.listen(3000)
Benutzerdefinierte Dateitypen
const http = require('node:http')
const parseUrl = require('parseurl')
const send = require('@fastify/send')
// Standardmäßig unbekannte Typen auf text/plain setzen
send.mime.default_type = 'text/plain'
// Einen benutzerdefinierten Typ hinzufügen
send.mime.define({
'application/x-my-type': ['x-mt', 'x-mtt']
})
const server = http.createServer(function onRequest (req, res) {
const { statusCode, headers, stream } = await send(req, parseUrl(req).pathname, { root: '/www/public' })
res.writeHead(statusCode, headers)
stream.pipe(res)
})
server.listen(3000)
Benutzerdefinierte Verzeichnisindexansicht
Dies ist ein Beispiel für die Bereitstellung einer Verzeichnisstruktur mit einer benutzerdefinierten Funktion zum Rendern einer Auflistung eines Verzeichnisses.
const http = require('node:http')
const fs = require('node:fs')
const parseUrl = require('parseurl')
const send = require('@fastify/send')
// Beliebige Dateien aus /www/example.com/public/* übertragen
// mit einem benutzerdefinierten Handler für die Verzeichnisauflistung
const server = http.createServer(async function onRequest (req, res) {
const { statusCode, headers, stream, type, metadata } = await send(req, parseUrl(req).pathname, { index: false, root: '/www/public' })
if(type === 'directory') {
// Verzeichnisliste abrufen
const list = await readdir(metadata.path)
// einen Index für das Verzeichnis rendern
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' })
res.end(list.join('\n') + '\n')
} else {
res.writeHead(statusCode, headers)
stream.pipe(res)
}
})
server.listen(3000)
Bereitstellung aus einem Root-Verzeichnis mit benutzerdefinierter Fehlerbehandlung
const http = require('node:http')
const parseUrl = require('parseurl')
const send = require('@fastify/send')
const server = http.createServer(async function onRequest (req, res) {
// beliebige Dateien aus
// /www/example.com/public/* übertragen
const { statusCode, headers, stream, type, metadata } = await send(req, parseUrl(req).pathname, { root: '/www/public' })
switch (type) {
case 'directory': {
// deine benutzerdefinierte Verzeichnisbehandlungslogik:
res.writeHead(301, {
'Location': metadata.requestPath + '/'
})
res.end('Redirecting to ' + metadata.requestPath + '/')
break
}
case 'error': {
// deine benutzerdefinierte Fehlerbehandlungslogik:
res.writeHead(metadata.error.status ?? 500, {})
res.end(metadata.error.message)
break
}
default: {
// deine benutzerdefinierten Header
// alle Dateien zum Herunterladen bereitstellen
res.setHeader('Content-Disposition', 'attachment')
res.writeHead(statusCode, headers)
stream.pipe(res)
}
}
})
server.listen(3000)
Lizenz
Lizenziert unter MIT.