The HTTP Gateway Protocol Specification
Introduction
The HTTP Gateway Protocol is an extension of the Internet Computer Protocol that allows conventional HTTP clients to interact with the Internet Computer network. This is important for software such as web browsers to be able to fetch and render client-side canister code, including HTML, CSS, and JavaScript as well as other static assets such as images or videos. The HTTP Gateway does this by translating between standard HTTP requests and API canister calls that the Internet Computer Protocol will understand.
Such an HTTP Gateway could be a stand-alone proxy, it could be implemented in web browsers (natively, via a plugin or a service worker) or in other ways. This document describes the interface and semantics of this protocol independent of a concrete HTTP Gateway so that all HTTP Gateway Protocol implementations can be compatible.
Overview
An HTTP request by an HTTP client is handled by these steps:
- An HTTP client makes a request.
- The HTTP Gateway intercepts the request.
- The HTTP Gateway resolves the canister ID that the request is intended for.
- The HTTP Gateway Candid encodes the HTTP request.
- The HTTP Gateway invokes the canister via a query call to the
http_request
canister method. - The canister handles the request and returns an HTTP response, encoded in Candid.
- The HTTP Gateway Candid decodes the response for inspection and further processing.
- If requested by the canister, the HTTP Gateway sends the request again via an update call to
http_request_update
. - If applicable, the HTTP Gateway fetches further response body data via streaming query calls.
- If applicable, the HTTP Gateway validates the certificate of the response.
- The HTTP Gateway returns the decoded response to the HTTP client.
Canister ID Resolution
The HTTP Gateway needs to know the canister ID of the canister to talk to, and obtains that information from the hostname as follows:
-
If the hostname is in the following table, use the given canister ids:
Hostname Canister id identity.ic0.app
rdmx6-jaaaa-aaaaa-aaadq-cai
nns.ic0.app
qoctq-giaaa-aaaaa-aaaea-cai
dscvr.one
h5aet-waaaa-aaaab-qaamq-cai
dscvr.ic0.app
h5aet-waaaa-aaaab-qaamq-cai
personhood.ic0.app
g3wsl-eqaaa-aaaan-aaaaa-cai
-
Check whether the hostname is raw (e.g.,
<name>.raw.ic0.app
). If it is the case, fail and handle the request as a Web2 request, otherwise, continue. -
Check whether the canister ID is embedded in the hostname by splitting the hostname and finding the first occurrence of a valid canister ID from the right. If there is a canister ID embedded in the hostname, use it.
-
Check whether the canister is hosted on the IC using a custom domain. There are two options:
-
Check whether there is a TXT record containing a canister ID at the
_canister-id
-subdomain (e.g., to see whetherfoo.com
is hosted on the IC, make a DNS lookup for the TXT record of_canister-id.foo.com
) and use the specified canister ID; -
Make a
HEAD
request to the hostname. If the response contains anx-ic-canister-id
header, use the value of this header as the canister ID.
-
-
Else fail and handle the request as a Web2 request.
If the hostname was of the form <name>.ic0.app
, it is a safe hostname; if it was of the form <name>.raw.ic0.app
, it is a raw hostname. Note that other domains may also be used to access canisters, such as icp0.io
. The same logic concerning raw domains can also be applied to these alternative domains.