http
http
is a module to provide HTTP client and server implementations.
Server
Server APIs utilizing Deno’s HTTP server APIs.
import { serve } from "https://deno.land/std@0.165.0/http/server.ts";
serve(() => new Response("Hello World\n"));
console.log("http://localhost:8000/");
File Server
A small program for serving local files over HTTP.
deno run --allow-net --allow-read https://deno.land/std/http/file_server.ts
> HTTP server listening on http://localhost:4507/
HTTP Status Code and Status Text
Helper for processing status code and status text.
import {
Status,
STATUS_TEXT,
} from "https://deno.land/std@0.165.0/http/http_status.ts";
console.log(Status.NotFound); //=> 404
console.log(STATUS_TEXT[Status.NotFound]); //=> "Not Found"
HTTP errors
Provides error classes for each HTTP error status code as well as utility functions for handling HTTP errors in a structured way.
For example throwing an error and detecting thrown errors as HTTP errors, and setting values in a response.
import {
errors,
isHttpError,
} from "https://deno.land/std@0.165.0/http/http_errors.ts";
try {
throw new errors.NotFound();
} catch (e) {
if (isHttpError(e)) {
const response = new Response(e.message, { status: e.status });
} else {
throw e;
}
}
Also the createHttpError()
function can be used to create errors:
import { createHttpError } from "https://deno.land/std@0.165.0/http/http_errors.ts";
import { Status } from "https://deno.land/std@0.165.0/http/http_status.ts";
try {
throw createHttpError(
Status.BadRequest,
"The request was bad.",
{ expose: false },
);
} catch (e) {
// handle errors
}
errors
A namespace that contains each error constructor. Each error extends HTTPError
and provides .status
and .expose
properties, where the .status
will be an
error Status
value and .expose
indicates if information, like a stack trace,
should be shared in the response.
By default, .expose
is set to false in server errors, and true for client
errors.
HttpError
The base case for all other HTTP errors, which extends Error
.
createHttpError()
A factory function which provides a way to create errors. It takes up to 3
arguments, the error Status
, an message, which defaults to the status text and
error options, which incudes the expose
property to set the .expose
value on
the error.
isHttpError()
A type guard that checks if a value is an HTTP error.
Negotiation
A set of functions which can be used to negotiate content types, encodings and languages when responding to requests.
Note: some libraries include accept charset functionality by analyzing the
Accept-Charset
header. This is a legacy header that clients omit and servers should ignore therefore is not provided.
accepts()
Used to determine what content type the requestor supports via analyzing the
Accept
header. Just passing a request to the accept function will return the
clients accepted content in order of preference:
import { accepts } from "https://deno.land/std@0.165.0/http/negotiation.ts";
const req = new Request("https://example.com/", {
headers: {
"accept":
"text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8",
},
});
console.log(accepts(req));
// [
// "text/html",
// "application/xhtml+xml",
// "image/webp",
// "application/xml",
// "*/*",
// ]
Providing supported content types will cause the function to return the “best” match:
import { accepts } from "https://deno.land/std@0.165.0/http/negotiation.ts";
const req = new Request("https://example.com/", {
headers: {
"accept":
"text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8",
},
});
accepts(req, "text/html", "image/webp"); // "text/html";
acceptsEncodings()
Used to determine what content encoding the requestor supports via analyzing the
Accept-Encoding
header. Just passing a request to the function will return the
clients accepted content encodings in order of preference:
import { acceptsEncodings } from "https://deno.land/std@0.165.0/http/negotiation.ts";
const req = new Request("https://example.com/", {
headers: { "accept-encoding": "deflate, gzip;q=1.0, *;q=0.5" },
});
acceptsEncodings(req); // ["deflate", "gzip", "*"]
Providing the supported content encodings will cause the function to return the
“best” match. Note that "indentity"
should always be included as it is the
base encoding:
import { acceptsEncodings } from "https://deno.land/std@0.165.0/http/negotiation.ts";
const req = new Request("https://example.com/", {
headers: { "accept-encoding": "deflate, gzip;q=1.0, *;q=0.5" },
});
acceptsEncodings(req, "gzip", "identity"); // "gzip"
acceptsLanguages()
Used to determine what content languages the requestor supports via analyzing
the Accept-Language
header. Just passing a request to the function will return
the clients accepted content languages in order of preference:
import { acceptsLanguages } from "https://deno.land/std@0.165.0/http/negotiation.ts";
const req = new Request("https://example.com/", {
headers: {
"accept-language": "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5",
},
});
acceptsLanguages(req); // ["fr-CH", "fr", "en", "de", "*"]
Providing the supported content languages will cause the function to return the “best” match:
import { acceptsLanguages } from "https://deno.land/std@0.165.0/http/negotiation.ts";
const req = new Request("https://example.com/", {
headers: {
"accept-language": "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5",
},
});
acceptsLanguages(req, "en-gb", "en-us", "en"); // "en"
Cookie
Helpers to manipulate the Cookie
header.
getCookies
import { getCookies } from "https://deno.land/std@0.165.0/http/cookie.ts";
const headers = new Headers();
headers.set("Cookie", "full=of; tasty=chocolate");
const cookies = getCookies(headers);
console.log(cookies); // { full: "of", tasty: "chocolate" }
setCookie
import {
Cookie,
setCookie,
} from "https://deno.land/std@0.165.0/http/cookie.ts";
const headers = new Headers();
const cookie: Cookie = { name: "Space", value: "Cat" };
setCookie(headers, cookie);
const cookieHeader = headers.get("set-cookie");
console.log(cookieHeader); // Space=Cat
deleteCookie
Note: Deleting a
Cookie
will set its expiration date before now. Forcing the browser to delete it.
import { deleteCookie } from "https://deno.land/std@0.165.0/http/cookie.ts";
const headers = new Headers();
deleteCookie(headers, "deno");
const cookieHeader = headers.get("set-cookie");
console.log(cookieHeader); // deno=; Expires=Thus, 01 Jan 1970 00:00:00 GMT
Note: It is possible to pass the exact same path and domain attributes that were used to set the cookie.
import { deleteCookie } from "https://deno.land/std@0.165.0/http/cookie.ts";
const headers = new Headers();
deleteCookie(headers, "deno", { path: "/", domain: "deno.land" });
Note: At the moment multiple
Set-Cookie
in aResponse
is not handled.
getSetCookies
import { getSetCookies } from "https://deno.land/std@0.165.0/http/cookie.ts";
const headers = new Headers([
["Set-Cookie", "lulu=meow; Secure; Max-Age=3600"],
["Set-Cookie", "booya=kasha; HttpOnly; Path=/"],
]);
const cookies = getSetCookies(headers);
console.log(cookies); // [{ name: "lulu", value: "meow", secure: true, maxAge: 3600 }, { name: "booya", value: "kahsa", httpOnly: true, path: "/ }]
Cookie maps
An alternative to cookie.ts
is cookie_map.ts
which provides CookieMap
,
SecureCookieMap
, and mergeHeaders
to manage request and response cookies
with the familiar Map
interface.
CookieMap
Provides methods that are aligned to the JavaScript Map
interface to manage
cookies:
import {
CookieMap,
mergeHeaders,
} from "https://deno.land/std@0.165.0/http/cookie_map.ts";
const request = new Request("https://localhost/", {
headers: { "cookie": "foo=bar; bar=baz;" },
});
const cookies = new CookieMap(request);
console.log(cookies.get("foo")); // logs "bar"
cookies.set("session", "1234567");
cookies.delete("bar");
const response = new Response("test", {
headers: mergeHeaders({
"content-type": "text/plain",
}, cookies),
});
If the headers or the response are available at the time of the construction of
the CookieMap
, they can be passed to the constructor and will have the cookies
set on them directly, thereby not requiring use of mergeHeaders
:
import { CookieMap } from "https://deno.land/std@0.165.0/http/cookie_map.ts";
const request = new Request("https://localhost/", {
headers: { "cookie": "foo=bar; bar=baz;" },
});
const headers = new Headers({ "content-type": "text/plain" });
const cookies = new CookieMap(request, { response: headers });
console.log(cookies.get("foo")); // logs "bar"
cookies.set("session", "1234567");
cookies.delete("bar");
const response = new Response("test", { headers });
SecureCookieMap
Provides methods that are aligned to the JavaScript Map
interface to manage
cookies. The biggest difference is that SecureCookieMap
supports the use of a
key ring adhering to the KeyRing
interface to sign and verify cookies. This
helps prevent client side tampering of cookies.
While passing keys is optional to SecureCookieMap
, if you are not using keys,
consider just using CookieMap
as all methods are synchronous and therefore
more straight forward to use.
import {
type KeyRing,
mergeHeaders,
SecureCookieMap,
} from "https://deno.land/std@0.165.0/http/cookie_map.ts";
const request = new Request("https://localhost/", {
headers: {
"cookie": "bar=foo; bar.sig=S7GhXzJF3n4j8JwTupr7H-h25qtt_vs0stdETXZb-Ro",
},
});
declare const keys: KeyRing;
const cookies = new SecureCookieMap(request, { keys });
console.log(await cookies.get("bar")); // logs "foo", with the signature being verified
await cookies.set("session", "1234567"); // this will be automatically signed
const response = new Response("test", {
headers: mergeHeaders({
"content-type": "text/plain",
}, cookies),
});
import {
type KeyRing,
SecureCookieMap,
} from "https://deno.land/std@0.165.0/http/cookie_map.ts";
const request = new Request("https://localhost/", {
headers: {
"cookie": "bar=foo; bar.sig=S7GhXzJF3n4j8JwTupr7H-h25qtt_vs0stdETXZb-Ro",
},
});
const headers = new Headers({ "content-type": "text/plain" });
declare const keys: KeyRing;
const cookies = new SecureCookieMap(request, { keys });
console.log(await cookies.get("bar")); // logs "foo", with the signature being verified
await cookies.set("session", "1234567"); // this will be automatically signed
const response = new Response("test", { headers });
mergeHeaders
A function which takes various sources of headers and returns a single Headers
instance. Intended to merge CookieMap
and SecureCookieMap
set cookie headers
into a final response.
Sources can be of type HeadersInit
, CookieMap
, SecureCookieMap
or objects
which have a headers
property with a value of Headers
(like a Response
object).