1. Introduction
This section is non-normative.
The Signed Exchanges specification [draft-yasskin-http-origin-signed-responses] describes a way to provide one or more signatures for an HTTP exchange and to check whether any of those signatures is trusted as authoritative for a particular origin. This specification describes how web browsers load those exchanges. It is expressed as several monkeypatches to the [FETCH] specification which call algorithms defined here.
1.1. Overview
When fetching a resource (https://distributor.example.org/foo.sxg
) with the application/signed-exchange
MIME type, the UA parses it, checks its
signatures, and then if all is well, redirects to its request URL
(https://publisher.example.org/foo
) with a "stashed" exchange attached to the
request. The redirect applies all the usual processing, and then when it would
normally check for an HTTP cache hit, it also checks whether the stashed request
matches the redirected request and which of the stashed exchange or HTTP cache
contents is newer. If the stashed exchange matches and is newer, the UA returns
the stashed response.
A Service Worker for https://distributor.example.org/
gets to handle the
original request. A Service Worker for https://publisher.example.org/
can then
handle the redirect. If it needs to know that signed exchange content is
available for the request it’s handling, it has two options:
-
If
navigationPreload
is enabled, the signed response will be available in theFetchEvent
'spreloadResponse
. Note that this will also cause a network request for requests that aren’t served from a signed exchange. -
clone()
therequest
and set itscache
to"only-if-cached"
, to retrieve the matching response from either the signed exchange or the HTTP cache. Note thatfetch()
ing a newRequest
with the sameurl
will not retrieve the response from the signed exchange.
1.2. Other interesting details
-
Like with
<link rel="prefetch">
and<link rel="preload">
, the UA will use the stashed response even if its HTTP cache headers have expired. This makes it easier to specify that the contents of the signed exchange don’t wind up in the HTTP cache before our security reviewers have gotten comfortable with that idea. The publisher can still control resource expiration by setting the Signature header’s expiration time to the cache expiration time if that’s sooner than they’d otherwise have the signature expire.
2. Fetch monkeypatches
When fetching a signed exchange, the UA needs to look for a trusted and valid signature and then redirect to the contained resource. We don’t put the contained resource in the HTTP cache, so redirects get a new field to store it.
2.1. A request’s stashed exchange
A request has an associated stashed exchange, which is null or an exchange.
2.2. Request clone
Rewrite clone a request to run these steps:
- Let newRequest be a copy of request, except for its body and stashed exchange .
- If request’s body is non-null, set newRequest’s body to the result of cloning request’s body.
- If request’s stashed exchange is non-null, set newRequest’s stashed exchange to an exchange whose request URL is a copy of request’s stashed exchange's request URL and whose response is the clone of request’s stashed exchange's response.
- Return newRequest.
2.3. New response fields
A response has an associated came from a signed exchange boolean. Unless stated otherwise, it is false.
A response has an associated signed exchange outer header list (a header list). Unless stated otherwise it is empty.
A response has an associated header integrity value, either null or, for responses that came from a signed exchange, a byte sequence holding the SHA-256 hash that verified the response's header list. Unless stated otherwise, it is null.
Note: The header integrity value doesn’t change even if the
publisher signs the content again or changes the signing key, but it does change
if any of the headers or body change. (It catches changes to the body because a
valid signed exchange’s headers have to include a Digest
value that covers the
body.)
2.4. Response date
A response response’s date is the result of:
-
Let date be the result of extracting header list values given
`Date`
and response’s header list. -
If date is a failure, return the point in time of the beginning of the universe.
-
Return the point in time represented by date, as interpreted for the Date header field.
2.5. Monkeypatch HTTP fetch
In HTTP fetch, before
If actualResponse’s status is a redirect status, then: ...
add the following steps:
-
If the signed exchange version of actualResponse is:
- undefined
-
Do nothing.
"b2"
or"b3"
-
-
Let report be the result of create a new signed exchange report with request and actualResponse.
-
Let parsedExchange be the result of parsing a signed exchange of version
b2
orb3
, respectively, from actualResponse in the context of request’s client, reporting to report. -
If parsedExchange is not an exchange, run queue a signed exchange report report with parsedExchange as the result, and return a network error.
-
In parallel, wait and queue a report for parsedExchange and report.
-
Set actualResponse’s status to
303
. -
Set actualResponse’s
`Location`
header to the ASCII encoding of the serialization of parsedExchange’s request URL. -
Set request’s stashed exchange to parsedExchange.
-
- Anything else
-
-
Let fallbackUrlBytes be the result of extracting the fallback URL from actualResponse.
-
If fallbackUrlBytes is a failure, return a network error.
-
Set actualResponse’s status to
303
. -
Set actualResponse’s
`Location`
header to fallbackUrlBytes.
-
Note: The final [draft-yasskin-http-origin-signed-responses] will use a version of
`1`
, but this specification tracks what’s actually implemented in browsers, which still uses draft versions.
2.6. Monkeypatch HTTP-network-or-cache fetch
In HTTP-network-or-cache fetch, after
5.19. If httpRequest’s cache mode is neither "
no-store
" nor "reload
", then: ...
add the following steps:
-
If httpRequest’s stashed exchange isn’t null:
-
Let stashedExchange be httpRequest’s stashed exchange.
-
If
-
httpRequest matches the stored exchange stashedExchange and
-
response is null or response’s date is earlier than httpRequest’s stashed exchange's response's date
then set response to httpRequest’s stashed exchange's response.
-
-
If response is null and httpRequest’s initiator is "
prefetch
" or "preload
", return a network error.Note: This ensures that prefetching a signed exchange from one origin won’t accidentally do a network request from another origin, which could compromise the user’s privacy.
-
Note: Applying the signed exchange’s response here has the effect of letting a newer HTTP cache entry override a signed exchange’s content, and of not storing the signed exchange’s response in the HTTP cache.
3. Subresource substitution
When prenavigating to a page held in a signed exchange, it can be useful to also prefetch subresources of that page as signed exchanges from the same server. To identify those transitive prefetchable resources, this section introduces an extension to the HTTP Link header.
The following is an example HTTP response for https://feed.example/sxg.publisher.example/page.html.wbn
showing the right
Link headers to let a browser prefetch subresources.
Content-Type: application/signed-exchange;v=b3 Link: <https://feed.example/sxg.publisher.example/lib.js.sxg>; rel="alternate"; type="application/signed-exchange"; anchor="https://cdn.publisher.example/lib.js" A signed exchange, whose request URL is https://sxg.publisher.example/page.html: Content-Type: text/html Link: <https://cdn.publisher.example/lib.js>; rel="preload"; as="script" Link: <https://cdn.publisher.example/lib.js>; rel="allowed-alt-sxg"; header-integrity="sha256-XXXXXX" <html> <head> <script src="https://cdn.publisher.example/lib.js"></script> </head> ... </html>
If another page includes a <link rel="prefetch"
href="https://feed.example/sxg.publisher.example/page.html.wbn">
, the above
response allows it to transitively prefetch a signed exchange that it can use to
satisfy the https://cdn.publisher.example/lib.js
<script>
element.
-
Link type "
allowed-alt-sxg
"The
allowed-alt-sxg
keyword may be used in the HTTP Link header of the inner HTTP response of the main resource signed exchange to indicate that the content of the Link Target is also available as a particular signed exchange identified by theheader-integrity
parameter. Theheader-integrity
parameter holds the value of the header integrity value of the alternate signed exchange, encoded as a [CSP] hash-source. -
An alternate signed exchange link is a Link header sent with a signed exchange S, with the
alternate
link type, thetype
parameter set toapplication/signed-exchange
, and a Link Context (ananchor
parameter). The Link Context MUST be the Link Target of apreload
Link header inside the signed content of S, and the alternate signed exchange link means that this resource can also be found inside the alternate signed exchange at the Link Target of the alternate signed exchange link. -
New serialisation-defined Target Attributes on the Link header.
-
The
variants
target attribute has the same values as the Variants Header Field. There MUST NOT be more than onevariants
attribute in a link-value; occurrences after the first MUST be ignored by parsers. It is serialized to an HTTP link-param by first encoding as if it were a Variants Header Field value, and then if there are characters that don’t match the token production, encoding as a quoted-string.This parameter is used in
allowed-alt-sxg
links and alternate signed exchange links to indicate what representations are available for the resource at the time that the response is produced. -
The
variant-key
target attribute has the same values as the Variant-Key Header Field. There MUST NOT be more than onevariant-key
attribute in a link-value; occurrences after the first MUST be ignored by parsers. It is serialized to an HTTP link-param by first encoding as if it were a Variant-Key Header Field value, and then if there are characters that don’t match the token production, encoding as a quoted-string.This parameter is used in
allowed-alt-sxg
links and alternate signed exchange links to indicate one or more sets of available-values that identify the representation of the resource.
-
3.1. New Document fields
At the end of the Document object section, add the following lines:
The
Document
has a map of prefetched signed exchanges for navigation, which is a map of URLs to exchanges, initially empty. This might merge with the set of prefetched resources whenprefetch
is specified more completely.The
Document
has a set of prefetched subresource signed exchanges, which is a set of exchanges, initially empty.
3.2. New navigation params struct field
In the navigation params struct, add the following items:
- prefetched subresource signed exchanges
-
A set of exchanges, empty unless specified otherwise.
3.3. Monkeypatch Link type "prefetch"
Note: To prefetch the alternate signed exchanges when the UA receives a
prefetched main resource signed exchange, this section monkeypatches Link type
"prefetch
". This algorithm gets all the alternate signed exchange
links from the outer response, checks if they are allowed by the inner
response’s allowed-alt-sxg
links, and if they are, associates them
with the inner response’s preload
links.
Currently the behavior of recursive prefetch is
not specified. This section monkeypatches Link type "prefetch
" to
add support only for the alternate signed exchanges subresources. When we
change the HTML spec to support general recursive prefetching, this section
needs to align with that change. <https://github.com/w3c/resource-hints/issues/77>
To process this type of linked resource ("prefetch
"), given a link element el, boolean success, and response response:
-
If success is true, fire an event named
load
at el. -
Otherwise, fire an event named
error
at el. -
If success is false, then return.
-
If the response did not come from a signed exchange, then return.
-
Let requestUrl be the first item of response’s URL list.
-
Let clonedExchange be the result of creating a new exchange with requestUrl and the result of cloning response.
-
Let prefetchedSignedExchanges be el’s node document's prefetched signed exchanges for navigation.
-
Set prefetchedSignedExchanges[requestUrl] to clonedExchange.
-
Let outerLinkHeader be the result of getting
`Link`
from response’s signed exchange outer header list. -
If outerLinkHeader is null, then return.
-
Let outerLinks be the result of Parsing a Link Field Value from outerLinkHeader.
-
If outerLinks is empty, then return.
-
Let innerLinkHeader be the result of getting
`Link`
from response’s header list. -
If innerLinkHeader is null, then return.
-
Let innerLinks be the result of Parsing a Link Field Value from innerLinkHeader.
-
If innerLinks is empty, then return.
-
Let alternateLinks be the result of getting alternate signed exchange link info from outerLinks.
-
Let allowedSxgLinks be the result of getting allowed signed exchange link info from innerLink.
-
For each innerLink of innerLinks:
-
If innerLink’s Relation Type is not 'preload', then continue.
-
Let linkTarget be innerLink’s Link Target.
-
Let asAttribute be innerLink’s Target Attribute named
"as"
. -
If asAttribute is not a potential destination, continue.
-
If asAttribute is
"image"
, then:-
Let imagesrcset be innerLink’s Target Attribute named
"imagesrcset"
. -
Let imagesizes be innerLink’s Target Attribute named
"imagesizes"
. -
Create a
link
element linkElement whosehref
attribute is linkTarget, andimagesrcset
attribute is imagesrcset, andimagesizes
attribute is imagesizes. -
Let selected source and selected pixel density be the URL and pixel density that results from selecting an image source given linkElement, respectively.
-
If selected source is not null, then set linkTarget to the result of parsing selected source, with a base URL of response’s URL.
-
-
For each allowedSxgLink of allowedSxgLinks:
-
If allowedSxgLink’s target isn’t the same as linkTarget, then continue.
-
Let storedExchange be the result of creating an exchange with linkTarget and a new response.
-
If allowedSxgLink’s variants is not null, set
`Variants`
/allowedSxgLink’s variants in storedExchange’s response's header list. -
If allowedSxgLink’s variant key is not null, set
`Variant-Key`
/allowedSxgLink’s variant key in storedExchange’s response's header list. -
Let requestForMatch be the result of creating a potential-CORS request given a url of linkTarget, a destination of the result of translating asAttribute, and a corsAttributeState of No CORS.
-
If requestForMatch doesn’t match the stored exchange storedExchange, then continue.
-
Let alternateSxgUrl be the target of the first alternate signed exchange link info of alternateLinks whose
-
variants is identical to allowedSxgLink’s variants,
-
variant key is identical to allowedSxgLink’s variant key, and
or continue if no such link is present.
-
-
Let sxgRequest be the result of creating a potential-CORS request given a url of alternateSxgUrl, a destination of the result of translating asAttribute, and a corsAttributeState of No CORS.
-
Run the following steps in parallel:
-
Let sxgResponse be the result of fetching sxgRequest.
-
If sxgResponse’s came from a signed exchange is true, and sxgResponse’s URL is the same as linkTarget, then queue a task on the networking task source to:
-
Let sxgExchange be a new exchange with a request URL of linkTarget and a response of sxgResponse.
-
Append sxgExchange to el’s node document's prefetched subresource signed exchanges.
-
-
-
-
3.4. Monkeypatch process a navigate fetch
In process a navigate fetch before
Let reservedEnvironment be null.
add the following steps:
-
If sourceBrowsingContext’s active document's prefetched signed exchanges for navigation contains an entry for a key of request’s url, then:
-
Let prefetchedExchange be sourceBrowsingContext’s active document's prefetched signed exchanges for navigation[request’s url].
-
Set request’s stashed exchange to the result of creating a new exchange with prefetchedExchange’s request URL and the result of cloning prefetchedExchange’s response.
-
And in
Let navigationParams be a new navigation params whose ...
add:
-
... prefetched subresource signed exchanges is sourceBrowsingContext’s active document's prefetched subresource signed exchanges, ...
Note: As browsers move toward partitioned HTTP caches, the source document’s cache will likely be separate from the target’s cache, so we can’t just pass prefetched content through the cache.
3.5. Monkeypatch Page load processing model for HTML files
Note: To use the prefetched subresource signed exchanges after the navigation, this section monkeypatches Page load processing model
for HTML files. This gets all the allowed-alt-sxg
links from the
inner response that are also preloaded and uses the prefetched subresource signed exchanges if all of those links were
prefetched.
Currently the processing model of the HTTP Link header is not defined in the HTML spec. This section monkeypatches only for Link rel=preload HTTP headers. When we will change the HTML spec to generally support Link HTTP headers, this section must be made to align with the change. <https://github.com/whatwg/html/issues/4224>
In Page load processing model for HTML files before
Create an HTML parser and ...
add the following steps:
-
Run the following steps in parallel:
-
Wait until document’s viewport is known.
Note: When the document’s viewport is known is not normatively defined in the HTML spec. Need to define the behavior of the preload scanner to define this.
-
Let linkHeader be the result of getting
`Link`
from navigationParams’s response's header list. -
If linkHeader is null, then return.
-
Let links be the result of Parsing a Link Field Value from linkHeader.
-
Let allowedSxgLinks be the result of getting allowed signed exchange link info from links.
-
Let preloadLinkItems be an empty list.
-
Let canLoadAlternateSxg be true.
-
For each link of links:
-
If link’s Relation Type is not 'preload', then continue.
-
Let linkTarget be link’s Link Target.
-
Let asAttribute be link’s Target Attribute named
"as"
. -
If asAttribute is not a potential destination, continue.
-
If asAttribute is
"image"
, then:-
Let imagesrcset be link’s Target Attribute named
"imagesrcset"
. -
Let imagesizes be link’s Target Attribute named
"imagesizes"
. -
Create a
link
element linkElement whosehref
attribute is linkTarget, andimagesrcset
attribute is imagesrcset, andimagesizes
attribute is imagesizes. -
Let selected source and selected pixel density be the URL and pixel density that results from selecting an image source given linkElement, respectively.
-
If selected source is not null, then set linkTarget to the result of parsing selected source, with a base URL of navigationParams’s response's URL.
-
-
Let headerIntegrity be null.
-
For each allowedSxgLink of allowedSxgLinks:
-
Let storedExchange be the result of creating an exchange with the URL of allowedSxgLink’s target and a new response.
-
If allowedSxgLink’s variants is null, set
`Variants`
/allowedSxgLink’s variants in storedExchange’s response's header list. -
If allowedSxgLink’s variant key is not null, set
`Variant-Key`
/allowedSxgLink’s variant key in storedExchange’s response's header list. -
Let requestForMatch be the result of creating a potential-CORS request given a url of allowedSxgLink’s target, a destination of the result of translating asAttribute, and a corsAttributeState of No CORS.
-
If requestForMatch matches the stored exchange storedExchange, then:
-
Set headerIntegrity to allowedSxgLink’s header integrity.
-
Break out of the allowedSxgLinks loop.
-
-
-
Let prefetched alternate exchange be null.
-
For each sxg of navigationParams’s prefetched subresource signed exchanges:
-
If headerIntegrity is the same as the value of sxg’s response's header integrity value encoded as a [CSP] hash-source, then set prefetched alternate exchange to sxg.
-
-
If headerIntegrity is not null and prefetched alternate exchange is null, then set canLoadAlternateSxg to false.
Note: This means that there is a matching
allowed-alt-sxg
link for thepreload
link, but the matching signed exchange has not been prefetched. In this case the UA can’t use the prefetched subresource signed exchanges for otherpreload
links. This is intended to prevent the referrer page from encoding a tracking ID into the set of subresources it prefetches. -
Append the alternate signed exchange preload info (link, linkTarget, prefetched alternate exchange) to preloadLinkItems.
-
-
For each preloadLinkItem of preloadLinkItems:
-
Let asAttribute be preloadLinkItem’s link's Target Attribute named
"as"
. -
Assert: asAttribute is a potential destination.
-
Let corsAttributeState be the state of a synthetic CORS settings attribute with a value of preloadLinkItem’s link's Target Attribute named
"crossorigin"
. -
Let request be the result of creating a potential-CORS request given a url of preloadLinkItem’s target, a destination of the result of translating asAttribute, and a corsAttributeState of corsAttributeState.
-
Set request’s client to document.
-
Set request’s cryptographic nonce metadata to preloadLinkItem’s link's Target Attribute named
"nonce"
. -
Set request’s integrity metadata to preloadLinkItem’s link's Target Attribute named
"integrity"
. -
Set request’s referrer policy to be the referrer policy attribute of preloadLinkItem’s link's Target Attribute named
"referrerpolicy"
. -
If canLoadAlternateSxg is true, then set request’s stashed exchange to preloadLinkItem’s prefetched alternate exchange.
Note: When canLoadAlternateSxg if false or there is no matching prefetched alternate exchange, the original resource declared in the
preload
Link header link will be fetched. -
Fetch request in parallel.
-
-
4. Structures
4.1. Exchange
An exchange is a struct with the following items:
4.2. Read buffer
A read buffer is a struct with the following items:
-
stream: A
ReadableStream
. -
reader: A
ReadableStreamDefaultReader
whose stream is stream. -
bytes: A byte sequence holding the bytes that have been read from stream but not returned to a calling algorithm yet.
4.3. Augmented Certificate
An augmented certificate is a tuple with the following items:
-
certificate, a byte sequence that’s expected to hold a DER-encoded X.509v3 certificate ([RFC5280]).
-
OCSP response, a byte sequence that’s expected to hold a DER-encoded OCSPResponse for the certificate.
-
SCT, a byte sequence that’s expected to hold a SignedCertificateTimestampList for the certificate.
These fields are byte sequences instead of parsed and validated structures because we expect some UAs to pass them to other systems for validation, and some of those systems expect plain byte sequences.
A certificate contains a public key (Subject Public Key Info), which has an algorithm (AlgorithmIdentifier).
A certificate contains an extensions map (Certificate Extensions) from OIDs to byte sequences.
A certificate chain is a list of augmented certificates, of which the first item is the leaf.
4.4. Signed Exchange report
A signed exchange report is a struct with the following items:
- result
-
The result string of loading signed exchange. This must be unset or one of "
ok
", "mi_error
", "non_secure_distributor
", "parse_error
", "invalid_integrity_header
", "signature_verification_error
", "cert_verification_error
", "cert_fetch_error
", "cert_parse_error
", - outer request
-
The request which the user agent sent to the server to load the signed exchange.
- outer response
-
The response which the user agent received from the server.
- inner URL
-
The logical URL of the signed exchange, if available. Otherwise, an empty string.
- cert URL list
-
The list of URLs in "
cert-url
" parameters for the signed exchange’s signatures, if available. Otherwise, an empty list. - server IP
-
The IP address of the server from which the user agent received the signed exchange, if available. Otherwise, an empty string.
- cert server IP list
-
The list of IP addresses of the servers from which the user agent received the certificates listed in cert URL list.
4.5. Exchange Signature
An exchange signature is a struct with the following items:
- signature
-
A byte sequence holding a signature of the exchange.
- certificate chain
-
A certificate chain whose leaf's public key can verify the signature and from which the UA will try to build a path from the leaf to a trusted root.
- certSha256
-
A byte sequence holding the SHA-256 hash that verified the certificate chain's leaf.
- integrity header
-
A list of ASCII strings that describes the response header and any of its parameters that guard the integrity of the response payload.
- validityUrl
-
A URL describing where to update this signature.
- validityUrlBytes
-
The bytes that validityUrl was parsed from.
- date
-
The POSIX time at which the signature starts being valid.
- expiration time
-
The POSIX time at which the signature stops being valid.
4.6. Allowed signed exchange link info
An allowed signed exchange link info is a struct with the following items,
holding a parsed allowed-alt-sxg
link:
- target
-
A URL holding the value of the link’s Link Target.
- header integrity
-
A string holding the value of the link’s Target Attribute named
"header-integrity"
. - variants
-
A string holding the value of the link’s Target Attribute named
"variants"
, or null. - variant key
-
A string holding the value of the link’s Target Attribute named
"variant key"
, or null.
4.7. Alternate signed exchange link info
An alternate signed exchange link info is a struct with the following items,
holding a parsed alternate
link:
- target
-
A URL holding the value of the link’s Link Target.
- context
-
A URL holding the value of the link’s Link Context.
- variants
-
A string holding the value of the link’s Target Attribute named
"variants"
, or null. - variant key
-
A string holding the value of the link’s Target Attribute named
"variant key"
, or null.
4.8. Alternate signed exchange preload info
An alternate signed exchange preload info is a struct with the following items:
- link
- target
-
A URL to be preloaded. This can be different from link's Link Target, when
"imagesrcset"
is used for image preload. - prefetched alternate exchange
-
The exchange of the prefetched alternate signed exchange, or null.
5. Algorithms
5.1. Identifying signed exchanges
The signed exchange version of a response response is the result of the following steps:
-
If determine nosniff on response’s header list returns false, return undefined.
Note: This requires servers to include the
X-Content-Type-Options: nosniff
header when they serve signed exchanges, which prevents some clients that don’t understand signed exchanges from interpreting one as another content type. -
Let mimeType be the result of extracting a MIME type from response’s header list.
-
If mimeType is a failure, return undefined.
-
If mimeType’s essence is not
"application/signed-exchange"
, return undefined. -
Let params be mimeType’s parameters
-
If params["v"] exists, return it. Otherwise, return undefined.
5.2. Extracting the fallback URL
This section defines how to load a the fallback URL from its invariant location in an unrecognized signed exchange version.
Extracting the fallback URL from a response response returns the result of the following steps:
-
Assert: This algorithm is running in parallel.
-
Assert: The signed exchange version of response is not undefined.
-
If bodyStream is null, return failure.
-
Let stream be a new read buffer for bodyStream.
-
Let (magic, fallbackUrlBytes, fallbackUrl) be the result of parsing the invariant prefix from stream. If returns a failure, return that failure.
-
Return fallbackUrlBytes.
5.3. Parsing signed exchanges
This section defines how to load the formats defined in [draft-yasskin-httpbis-origin-signed-exchanges-impl-02] and [draft-yasskin-httpbis-origin-signed-exchanges-impl-03].
Parsing a signed exchange of version version from a response response in the context of an environment settings object client, reporting to a signed exchange report report, returns an exchange or a string which indicates a result as described by the following steps
-
Assert: This algorithm is running in parallel.
-
Assert: The signed exchange version of response is, if version is
b2
-
"b2"
b3
-
"b3"
-
If response’s URL's origin is not a potentially trustworthy origin, return "non_secure_distributor".
Note: This ensures that the privacy properties of retrieving an HTTPS resource via a signed exchange are no worse than retrieving it via TLS.
-
If bodyStream is null, return "parse_error".
-
Let stream be a new read buffer for bodyStream.
-
Let (magic, requestUrlBytes, requestUrl) be the result of parsing the invariant prefix from stream. If returns a failure, return "parse_error".
-
Set report’s inner URL to requestUrl.
-
If magic is not the following value, depending on version, return "parse_error":
b2
-
`sxg1-b2\0`
b3
-
`sxg1-b3\0`
-
Assert: requestUrlBytes should match the result of extracting the fallback URL from response.
-
Let encodedSigLength be the result of reading 3 bytes from stream.
-
Let encodedHeaderLength be the result of reading 3 bytes from stream.
-
If encodedSigLength or encodedHeaderLength is a failure, return "parse_error".
-
Let sigLength be the result of decoding encodedSigLength as a big-endian integer.
-
Let headerLength be the result of decoding encodedHeaderLength as a big-endian integer.
-
If sigLength > 16384 or headerLength > 524288, return "parse_error".
-
Let signature be the result of reading sigLength bytes from stream.
-
If signature is a failure, return "parse_error".
-
Let parsedSignature be the result of parsing the Signature header field signature in the context of client reporting to with report.
-
If parsedSignature is not an exchange signature, return it.
-
Let headerBytes be the result of reading headerLength bytes from stream.
-
If headerBytes is a failure, return "parse_error".
-
If parsedSignature is not valid for headerBytes and requestUrlBytes, and signed exchange version version, return "signature_verification_error".
-
Let parsedExchange be, if version is:
b2
-
the result of parsing b2 CBOR headers given headerBytes and requestUrl.
b3
-
the result of parsing b3 CBOR headers given headerBytes and requestUrl.
-
Set parsedExchange’s response's came from a signed exchange to true.
-
Set parsedExchange’s response's signed exchange outer header list to response’s header list.
-
Set parsedExchange’s response's header integrity value to the SHA-256 hash of headerBytes.
-
If parsedSignature does not establish cross-origin trust for parsedExchange, return "cert_verification_error".
-
If parsedExchange’s response's status is a redirect status or the signed exchange version of parsedExchange’s response is not undefined, return "parse_error".
Note: This might simplify the UA’s implementation, since it doesn’t have to handle nested signed exchanges.
-
Read a body from stream into parsedExchange’s response using parsedSignature to check its integrity. If this returns an error string, return it.
Note: Typically this body’s stream is still being enqueued to after returning.
-
Return parsedExchange.
5.4. Parsing the invariant prefix
All signed exchange versions start with the same initial bytes, parsed by this section.
Parsing the invariant prefix from a read buffer stream returns a failure or the triple of a byte sequence magic, byte sequence fallbackUrlBytes, and URL fallbackUrl, as described by the following steps:
-
Assert: This algorithm is running in parallel.
-
Let magic be the result of reading 8 bytes from stream.
-
If magic is a failure, return it.
-
Let encodedFallbackUrlLength be the result of reading 2 bytes from stream.
-
If encodedFallbackUrlLength is a failure, return it.
-
Let fallbackUrlLength be the result of decoding encodedFallbackUrlLength as a big-endian integer.
-
Let fallbackUrlBytes be the result of reading fallbackUrlLength bytes from stream.
-
If fallbackUrlBytes is a failure, return it.
-
Let fallbackUrlString be the result of UTF-8 decode without BOM or fail on fallbackUrlBytes.
-
If fallbackUrlString is a failure, return it.
-
Let fallbackUrl be the result of running the URL parser on fallbackUrlString.
-
If fallbackUrl is a failure, if it has a non-null fragment, or if its scheme is something other than
"https"
, return a failure. -
Return (magic, fallbackUrlBytes, fallbackUrl).
5.5. Parsing a Signature Header Field
Parsing the Signature header field signatureString in the context of an environment settings object client, reporting to a signed exchange report report, returns an exchange signature or a string which indicates a result, as described by the following steps:
-
Assert: This algorithm is running in parallel.
-
If signatureString contains any bytes that aren’t ASCII bytes, return "parse_error".
-
Let parsed be the result of Parsing HTTP1 Header Fields into Structured Headers given an input_string of the ASCII decoding of signatureString and a header_type of "param-list".
-
If parsed has more than one element, "parse_error".
Note: This limitation of current implementations will go away in the future.
-
If any of the parameters of parsed[0] listed here doesn’t have the associated type, "parse_error".
- Byte sequence
-
"sig", "cert-sha256"
- String
-
"integrity", "cert-url", "validity-url"
- Integer
-
"date", "expires"
-
Let result be a new exchange signature struct.
-
Set result’s signature to the "sig" parameter of parsed[0].
-
Set result’s integrity header to the result of strictly splitting the "integrity" parameter of parsed[0] on U+002F (
/
). -
Let certUrl be the result of running the URL parser on the "cert-url" parameter of parsed[0].
-
Append certUrl to report’s cert URL list.
-
If certUrl is a failure, if it has a non-null fragment, or if its scheme is something other than
"https"
or"data"
, return "parse_error". -
Set result’s certSha256 to the "cert-sha256" parameter of parsed[0].
-
Set result’s validityUrlBytes to the ASCII encoding of the "validity-url" parameter of parsed[0].
-
Let validityUrl be the result of running the URL parser on the "validity-url" parameter of parsed[0]..
-
If validityUrl is a failure, if it has a non-null fragment, or if its scheme is something other than
"https"
, return "parse_error". -
Set result’s validityUrl to validityUrl.
-
Set result’s date to the "date" parameter of parsed[0].
-
Set result’s expiration time to the "expires" parameter of parsed[0].
-
If result’s expiration time or result’s date is less than 0 or greater than 263-1, return "parse_error".
-
If result’s expiration time <= result’s date, return "parse_error".
-
Set result’s certificate chain to the result of handling the certificate reference certUrl with a hash of result’s certSha256 and report in the context of client. If this is not a certificate chain, return it.
-
Return result.
5.5.1. Handling the certificate reference
Handling the certificate reference certUrl with the SHA-256 hash certSha256 in the context of an environment settings object client, reporting to a signed exchange report report, returns a certificate chain or a string which indicates a result, as described by the following steps:
-
Assert: This algorithm is running in parallel.
-
Let certRequest be a new request with the following items:
- url
-
certUrl
- header list
-
«
`Accept`
:`application/cert-chain+cbor`
» - client
-
client
- service-workers mode
-
"
none
" - mode
-
"
cors
"
-
Let certResponse be the result of fetching certRequest.
-
Append the IP address of the server from which the user agent received the certResponse to report’s cert server IP list, if available.
-
If certResponse’s status is not
200
, return "cert_fetch_error". -
Let certMimeType be the result of extracting a MIME type from certResponse’s header list.
-
If certMimeType is a failure or its essence is not
"application/cert-chain+cbor"
, return "cert_fetch_error". -
If certResponse’s body is null or that body’s stream is null, return "cert_parse_error".
-
Let reader be the result of getting a reader for certResponse’s body's stream.
-
Assert: Getting a reader did not throw an exception, because the response was created in this algorithm and not passed anywhere that could create a reader for its body.
-
Let bytes be the result of reading all bytes from reader.
-
Wait for bytes to settle.
-
If bytes was rejected, return "cert_parse_error".
-
Let chain be the certificate chain produced by parsing bytes’ value using the cert-chain CDDL. If bytes’s value doesn’t match this CDDL or isn’t canonically-encoded CBOR, return "cert_parse_error".
-
Assert: chain has at least one item.
-
If the SHA-256 hash of chain’s leaf's certificate is not equal to certSha256, return "signature_verification_error".
-
Return chain.
5.6. The signed message
The signed message for a version version, an exchange signature signature and byte sequences requestUrlBytes and headerBytes is the concatenation of the following byte sequences:
-
The byte 0x20 (SP) repeated 64 times. This matches the TLS 1.3 ([RFC8446]) format to avoid cross- protocol attacks if anyone uses the same key in a TLS certificate and an exchange-signing certificate.
-
A context string consisting of, if version is:
b2
-
`HTTP Exchange 1 b2`
b3
-
`HTTP Exchange 1 b3`
Note: Each draft of [draft-yasskin-httpbis-origin-signed-exchanges-impl-02] and the final RFC for [draft-yasskin-http-origin-signed-responses] will use distinct context strings.
-
A single 0x00 byte which serves as a separator.
-
A single 0x20 (SP) byte, representing the length of the next field.
-
signature’s certSha256.
-
The 8-byte big-endian encoding of the length in bytes of signature’s validityUrlBytes.
-
signature’s validityUrlBytes.
-
The 8-byte big-endian encoding of signature’s date.
-
The 8-byte big-endian encoding of signature’s expiration time.
-
The 8-byte big-endian encoding of the length in bytes of requestUrlBytes.
-
requestUrlBytes.
-
The 8-byte big-endian encoding of the length in bytes of headerBytes.
-
headerBytes.
5.7. Validating a signature
An exchange signature signature is valid for byte sequences requestUrlBytes and headerBytes, and signed exchange version version, if the following steps
return valid
:
-
Let clockSkew be the uncertainty in the UA’s estimate of the current time caused by clock skew on the client. The UA MAY set this to 0 or use a more sophisticated estimate.
-
If the UA’s estimate of the current time is more than clockSkew before signature’s date, return "untrusted".
Note: We take estimated clock skew into account when checking the signature’s date because we want well-behaved servers to use the time they created the signature, but if they immediately start serving that signature, and skewed clients don’t try to correct for their skew, those clients will reject the signature.
Our security reviewers aren’t sure we should allow UAs to take clock skew into account. <https://github.com/WICG/webpackage/issues/141>
-
If the UA’s estimate of the current time is after signature’s expiration time, return "untrusted".
Note: We use the client’s best guess of the current time to check the expiration time so that attackers trying to get an exchange trusted for longer, are constrained to modify the client’s clock and can’t also attack its estimate of its skew.
-
Let message be the signed message for version, signature, requestUrlBytes, and headerBytes.
-
Let publicKey be the public key of parsedSignature’s certificate chain's leaf. If the certificate can’t be parsed enough to find this public key, return
invalid
. -
If publicKey’s algorithm is not id-ecPublicKey on the secp256r1 named curve, return
invalid
. -
If parsedSignature’s signature is not a valid signature of message by publicKey using the ecdsa_secp256r1_sha256 algorithm, return
invalid
. -
Return
valid
.
5.8. Cross-origin trust
A valid exchange signature signature establishes cross-origin trust in an exchange exchange if the following steps return "trusted":
-
Let requestUrl be exchange’s request URL.
-
If signature’s validityUrl's origin is not same origin with requestUrl’s origin, return "untrusted".
-
If exchange’s response's header list includes an uncached response header, return "untrusted".
-
If signature’s expiration time is more than 604800 seconds (7 days) after signature’s date, return "untrusted".
-
If signature’s certificate chain does not have a trusted leaf for requestUrl’s origin, return "untrusted".
-
Return "trusted".
5.9. Establishing trust in a certificate
The certificate chain chain has a trusted leaf for an origin origin if the following steps return trusted
:
-
Let leaf be chain’s leaf.
-
Attempt to build a trustworthy path from leaf’s certificate to a trusted root with
-
chain,
-
leaf’s OCSP response,
-
any SCTs from
-
leaf’s SCT.
-
An OCSP extension in leaf’s OCSP response.
-
An X.509 extension in leaf’s certificate.
-
as input, using [RFC5280] and any other conventions used in making TLS ([RFC8446]) connections. The UA SHOULD support Certificate Transparency ([RFC6962]) for this check. (See § 6.1 Certificate Transparency.) The UA MUST check that it has evidence the leaf’s certificate was not revoked 7 or more days ago (for example using the leaf’s OCSP response). If no such path can be built, return
untrusted
. -
-
If leaf’s certificate is not trusted for origin’s host, return
untrusted
. -
If leaf’s extensions don’t map a CanSignHttpExchanges OID to the ASN.1/DER encoding of NULL (0x05 0x00), return
untrusted
. -
Return
trusted
.
5.10. Parsing b2 CBOR headers
Parsing b2 CBOR headers from a byte sequence headerBytes and a URL requestUrl returns a failure or an exchange via the following steps:
-
Let headers be the result of parsing a CBOR item from headerBytes, matching the following CDDL rule:
headers = [ { ':method': bstr, * bstr => bstr, }, { ':status': bstr, * bstr => bstr, } ]
-
If any of the following is true, return a failure:
-
headers is an error.
-
headers[0] contains any key starting with
`:`
that isn’t`:method`
. -
headers[0] contains a
`host`
key. -
headers[0][
`:method`
] is not`GET`
. -
headers[1] contains any key starting with
`:`
that isn’t`:status`
. -
headers[1][
`:status`
] is not200
.
-
-
Let requestHeaders be the result of creating a header list from the CBOR map headers[0].
-
If requestHeaders is a failure, return it.
-
Let responseHeaders be the result of creating a header list from the CBOR map headers[1].
-
If responseHeaders is a failure, return it.
-
If responseHeaders does not contain
`Content-Type`
, return a failure. -
Set
`X-Content-Type-Options`
/`nosniff`
in responseHeaders. -
Let response be a new response with status headers[1][
`:status`
] and header list responseHeaders. -
Return an exchange of requestUrl and response.
Note: This ignores requestHeaders, which can’t be encoded in b3 and later.
5.11. Parsing b3 CBOR headers
Parsing b3 CBOR headers from a byte sequence headerBytes and a URL requestUrl returns a failure or an exchange via the following steps:
-
Let headers be the result of parsing a CBOR item from headerBytes, matching the following CDDL rule:
headers = { ':status': bstr, * bstr => bstr, }
-
If any of the following is true, return a failure:
-
headers is an error.
-
headers contains any key starting with
`:`
that isn’t`:status`
. -
headers[
`:status`
] is not200
.
-
-
Let responseHeaders be the result of creating a header list from the CBOR map headers.
-
If responseHeaders is a failure, return it.
-
Let response be a new response with status headers[
`:status`
] and header list responseHeaders. -
Return an exchange of requestUrl and response.
5.11.1. Converting a map to a header list
The result of creating a header list from the CBOR map map is returned by the following steps:
-
Let headers be a new empty header list.
-
For each key → value of map:
-
If key starts with
`:`
, continue. -
If the isomorphic decoding of key contains any ASCII upper alpha, return a failure.
-
If key doesn’t match the constraints on a name or value doesn’t match the constraints on a value, return a failure.
-
Assert: headers does not contain key.
-
Append key/value to headers.
-
-
Return headers.
5.12. Creating the response stream.
To read a body from a read buffer stream into a response response using an exchange signature signature to check its integrity, the UA MUST:
-
If signature’s integrity header is:
- «"
digest
", "mi-sha256-03
"» -
-
Let instance-digests be the result of getting, decoding, and splitting
`digest`
from response’s header list.Note: No Digest algorithm uses non-ASCII characters or 0x22 (
"
), so this is equivalent to parsing from the Digest ABNF<encoded digest output>
. -
Let mi be the element of instance-digests that starts with
"mi-sha256-03="
. If there is no such element, return an error string "invalid_integrity_header". -
Let codings be the result of getting, decoding, and splitting
`content-encoding`
in response’s header list. -
If codings doesn’t include
"mi-sha256-03"
, return an error string "invalid_integrity_header". -
Assert: Handle content codings used the value of mi as the integrity proof for the first record when decoding the
mi-sha256-03
content encoding to produce the bytes in stream.
-
- Anything else
-
Return an error string "invalid_integrity_header".
- «"
-
Let body be a new body.
-
Let cancel be the following steps, taking reason as an argument:
-
Let outputStream be the result of creating a
ReadableStream
with a cancelAlgorithm of cancel. -
Set body’s stream to outputStream.
-
Set response’s body to body.
-
-
Dump stream to outputStream.
-
5.13. Request matching
A request browserRequest matches the stored exchange storedExchange if the following steps return "match":
-
If browserRequest’s method is not
`GET`
or`HEAD`
, return "mismatch".Note: The browserRequest’s method can be something other than
`GET`
if a Service Worker intercepts the redirect and modifies the request before re-fetching it. -
If browserRequest’s url is not equal to storedExchange’s request URL, return "mismatch".
-
If storedExchange’s response's header list contains:
- Neither a
`Variants`
nor a`Variant-Key`
header -
Return "match".
Note: This states that exactly one resource lives at the request URL, and no content negotiation is intended.
- A
`Variant-Key`
header but no`Variants`
header -
Return "mismatch".
Note: This indicates a likely misconfiguration, and returning "mismatch" makes that fail fast.
- A
`Variants`
header but no`Variant-Key`
header -
Return "mismatch".
Note: This behavior is implied by the below steps, but we make it explicit here.
- Both a
`Variants`
and a`Variant-Key`
header -
Proceed to the following steps.
- Neither a
-
If getting
`Variants`
from storedExchange’s response's header list returns a value that fails to parse according to the instructions for the Variants Header Field, return "mismatch". -
Let acceptableVariantKeys be the result of running the Variants Cache Behavior on an incoming-request of browserRequest and stored-responses of a list containing storedExchange’s response.
-
Let variantKeys be the result of getting
`Variant-Key`
from storedExchange’s response's header list, and parsing it into a list of lists as described in the Variant-Key Header Field. -
If parsing variantKeys failed, return "mismatch".
-
If the intersection of acceptableVariantKeys and variantKeys is empty, return "mismatch".
This depends on the Variants Cache Behavior returning a list of lists. <https://github.com/httpwg/http-extensions/issues/744>
-
Return "match".
5.14. Create a new signed exchange report
To create a new signed exchange report with request and actualResponse, the UA MUST:-
Let report be a new signed exchange report struct.
-
Set report’s outer request to request.
-
Set report’s outer response to actualResponse.
-
Set report’s server IP to the IP address of the server from which the user agent received the actualResponse, if available.
-
Return report.
5.15. Wait and queue a report
To wait and queue a report for parsedExchange and report, the UA MUST:-
Wait until parsedExchange’s body's stream is closed or errored.
-
If parsedExchange’s body's stream is closed, run queue a signed exchange report report with "ok" as the result and abort these steps.
-
If parsedExchange’s body's stream is errored, run queue a signed exchange report report with "mi_error" as the result.
5.16. Queuing signed exchange report
To queue a signed exchange report report with result as the result, the UA MUST:
-
Set report’s result to result.
-
Let report body and policy be the result of generate a network error report with report’s outer request. If the result is null, abort these steps.
-
If report body’s
"type"
is"dns.address_changed"
, abort these steps.Note: This means that the NEL report was downgraded because the IP addresses of the server and the policy don’t match. In this case, the UA has called deliver a network report algorithm with the error report while handling the response. So we don’t need to send the same error report while processing the response as a signed exchange.
-
Add a new property
"sxg"
to report body with a new ECMAScript object with the following properties:-
outer_url
: The serialization of report’s outer request's url. -
inner_url
: The serialization of report’s inner URL. -
cert_url
: The sequence type of the result of serialization of each element of report’s cert URL list.
-
-
Set report body’s
"phase"
to"sxg"
. -
If the report’s result is "ok", set report body’s
"type"
to"ok"
. Otherwise, set report body’s"type"
to the result of concatenating a string"sxg."
and the report’s result. -
If report body’s
"sxg"
's"cert_url"
's scheme is not"data"
and report’s result is "signature_verification_error" or "cert_verification_error" or "cert_fetch_error" or "cert_parse_error":-
If report’s outer request's url's origin is different from any origin of the URLs in report’s cert URL list, or report’s server IP is different from any of the IP address in report’s cert server IP list:
-
Set report body’s
"type"
to"sxg.failed"
. -
Set report body’s
"elapsed_time"
to 0.
-
Note: This step "downgrades" a Signed Exchange report if the certificate was served from the different server from the server of
"outer_url"
. This is intended to avoid leaking the information about the certificate server. -
-
Deliver a network report with report body and policy and report’s outer request.
If a NEL policy was received from the distributor’s origin,distributor.example
, this step will send the following JSON data to describe an invalid signature:{ "type" : "network-error" , "url" : "https://publisher.example/article.html" , "age" : 234 , "user_agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) ..." , "body" : { "referrer" : "https://aggregator.example/article.html" , "sampling_fraction" : 1 , "server_ip" : "<IP_ADDRESS>" , // The IP address of distr ibut or.example."protocol" : "http/1.1" , "method" : "GET" , "status_code" : 200 , "elapsed_time" : 1234 , "phase" : "sxg" , "type" : "sxg.signature_verification_error" , "sxg" : { "outer_url" : "https://distributor.example/publisher.example/article.html.sxg" , "inner_url" : "https://publisher.example/article.html" , "cert_url" : [ "https://distributor.example/publisher.example/cert" ] }, } }
5.17. Stream algorithms
The algorithms in this section create and operate over
ECMAScript objects like ReadableStream
despite not having a Realm to attach
them to. <https://github.com/whatwg/fetch/issues/730>
5.17.1. Create a read buffer
A new read buffer for a ReadableStream
stream is a new read
buffer struct whose items are:
- stream
-
stream
- reader
-
The result of getting a reader from stream.
- bytes
-
An empty byte sequence.
5.17.2. Read up to bytes
To read up to N bytes from a read buffer buffer, the UA MUST:
-
Assert: This algorithm is running in parallel.
-
Let done be
false
. -
While done is
false
and the length of buffer’s bytes item is less than N bytes:-
Let chunk be the result of reading a chunk from buffer’s reader.
-
Wait for chunk to settle.
-
If chunk is :
- Fulfilled with an object whose
done
property isfalse
and whosevalue
property is aUint8Array
object: -
-
Let bs be the byte sequence represented by the
Uint8Array
object. -
Set buffer to the concatenation of buffer and bs.
-
- Fulfilled with an object whose
done
property istrue
: -
Set done to
true
. - Rejected with e:
-
Return a failure with reason e.
- Fulfilled with an object whose
-
-
If buffer’s bytes item is at least N bytes long:
-
Let result be a byte sequence consisting of the first N bytes of buffer’s bytes item.
-
Set buffer’s bytes item to a byte sequence consisting of the bytes after the Nth from its old value.
-
-
Otherwise:
-
Let result be buffer’s bytes item.
-
Set buffer’s bytes item to an empty byte sequence.
-
-
Return result.
5.17.3. Read bytes
To read N bytes from a read buffer buffer, the UA MUST:
-
Assert: This algorithm is running in parallel.
-
Let bytes be the result of reading up to N bytes from buffer.
-
If bytes is a failure, return it.
-
If bytes is exactly N bytes long, return it.
-
Otherwise, return a failure.
5.17.4. Dump to another stream
To Dump a read buffer input to a ReadableStream
output, the UA MUST:
-
Assert: This algorithm is running in parallel.
-
Enqueue a
Uint8Array
wrapping anArrayBuffer
containing input’s bytes into output. -
While input’s stream is readable:
-
Wait until output is closed, errored, or needs more data.
-
If output is closed or errored, cancel input’s stream and abort these steps.
-
Let chunk be the result of reading a chunk with input’s reader.
-
Wait for chunk to settle.
-
If chunk is:
- Fulfilled with an object whose
done
property isfalse
and whosevalue
property is aUint8Array
object bytes: -
Enqueue a
Uint8Array
wrapping anArrayBuffer
containing bytes into output. - Fulfilled with an object whose
done
property istrue
: -
Close output.
- Rejected with e:
-
Error output with reason e.
- Fulfilled with an object whose
-
5.18. Get value of Target Attributes
A link header value link’s Target Attribute named name is the second item of the first tuple of link’s Target Attributes whose first item matches the string name, or null if no such tuple is present.
5.19. Get allowed signed exchange link info
The result of getting allowed signed exchange link info from a list links is returned by the following steps:
-
Let allowedSxgLinks be an empty list.
-
For each link of links:
-
If link’s Relation Type is not 'allowed-alt-sxg', then continue.
-
Let linkTarget be link’s Link Target.
-
Let headerIntegrity be link’s Target Attribute named
"header-integrity"
. -
If headerIntegrity is null, then continue.
-
Let linkVariants be link’s Target Attribute named
"variants"
. -
Let linkVariantKey be link’s Target Attribute named
"variant-key"
. -
Append the allowed signed exchange link info (linkTarget, headerIntegrity, linkVariants, linkVariantKey) to allowedSxgLinks.
-
-
Return allowedSxgLinks.
5.20. Get alternate signed exchange link info
The result of getting alternate signed exchange link info from a list links is returned by the following steps:
-
Let alternateSxgLinks be an empty list.
-
For each link of links:
-
If link’s Relation Type is not 'alternate', then continue.
-
If link’s Target Attributes doesn’t contain (
"type"
,"application/signed-exchange"
), then continue. -
Let linkTarget be link’s Link Target.
-
Let linkContext be link’s Link Context.
-
Let linkVariants be link’s Target Attribute named
"variants"
. -
Let linkVariantKey be link’s Target Attribute named
"variant-key"
. -
Append the alternate signed exchange link info (linkTarget, linkContext, linkVariants, linkVariantKey) to alternateSxgLinks.
-
-
Return alternateSxgLinks.
6. Security Considerations
The Security Considerations of [draft-yasskin-http-origin-signed-responses] apply.
6.1. Certificate Transparency
To identify off-path attackers, § 5.9 Establishing trust in a certificate encourages UAs to implement Certificate Transparency, which requires that, in order for a certificate to be trusted, it must be logged publicly. This means that an off-path attacker who has managed to get a mis-issued certificate has to at least announce that certificate in a place the legitimate domain owner has a chance to notice. Once they notice, they can revoke the certificate, which will stop the UA from trusting it no more than 7 days later.


- fileStream - Variable in class it.polimi.se2018.client.view.gui.BoardController
-
- fileStream - Variable in class it.polimi.se2018.client.view.gui.ChoosePattern
-
- fileStream - Variable in class it.polimi.se2018.client.view.gui.PatternCardBox
-
- fileStream - Variable in class it.polimi.se2018.client.view.gui.RoundTrackerBox
-
- finalPoints - Variable in class it.polimi.se2018.server.model.Components.Player
-
- finish - Static variable in class it.polimi.se2018.client.view.gui.EndGameScene
-
- finish - Variable in class it.polimi.se2018.events.serverclient.modelview.PlayerPointsUpdateEvent
-
- FluxBrushEvent - Class in it.polimi.se2018.events.clientserver
-
Class FluxBrushEvent: client server event for Flux Brush tool card
- FluxBrushEvent(int) - Constructor for class it.polimi.se2018.events.clientserver.FluxBrushEvent
-
Class constructor with the index of pool of the dice at the moment of the call
- FluxBrushRequestEvent - Class in it.polimi.se2018.events.serverclient.controllerview
-
Class FluxRemoverRequestEvent: controller view event for Flux Remover tool card request
- FluxBrushRequestEvent(int, int) - Constructor for class it.polimi.se2018.events.serverclient.controllerview.FluxBrushRequestEvent
-
class constructor with the id of the player and the size of the pool
- fluxRemoverEffect(int, int, int, Dice) - Method in class it.polimi.se2018.server.controller.ToolCardEffect
-
method responsible of the exchange of a dice between the draft pool and the dice bag
- FluxRemoverEvent - Class in it.polimi.se2018.events.clientserver
-
Class FluxRemover: client server event for Flux Remover tool card
- FluxRemoverEvent(int, int) - Constructor for class it.polimi.se2018.events.clientserver.FluxRemoverEvent
-
Class constructor with the index of the pool of dice at the moment of the call and
the new value of the dice
- FluxRemoverRequestEvent - Class in it.polimi.se2018.events.serverclient.controllerview
-
Class FluxRemoverRequestEvent: controller view event for Flux Remover tool card request
- FluxRemoverRequestEvent(int, DiceColor, int) - Constructor for class it.polimi.se2018.events.serverclient.controllerview.FluxRemoverRequestEvent
-
class constructor with the id of the player, the size of the pool and the color of the dice


Well-Grounded Java Developer 2nd Edition is on @manning Deal of the Day today (Sep 15)! It's coming out _real soon now_ and you can get all the chapters in early access already _right now_. Grab it and sharpen your JVM skills today! https://www.manning.com/dotd?utm_source=twitter&utm_medium=organic&utm_campaign=dotd
9/15/2022, 12:31:38 PM
Favs: 2
Retweets: 1
link


FHOG Efficiently compute Felzenszwalb's HOG (FHOG) features. FHOG.m A fast implementation of the HOG variant used by Felzenszwalb et al. in their work on discriminatively trained deformable part models. http://www.cs.berkeley.edu/~rbg/latent/index.html Gives nearly identical results to features.cc in code release version 5 but runs 4x faster (over 125 fps on VGA color images). The computed HOG features are 3*nOrients+5 dimensional. There are 2*nOrients contrast sensitive orientation channels, nOrients contrast insensitive orientation channels, 4 texture channels and 1 all zeros channel (used as a 'truncation' feature). Using the standard value of nOrients=9 gives a 32 dimensional feature vector at each cell. This variant of HOG, refered to as FHOG, has been shown to achieve superior performance to the original HOG features. For details please refer to work by Felzenszwalb et al. (see link above). This function is essentially a wrapper for calls to gradientMag() and gradientHist(). Specifically, it is equivalent to the following: [M,O] = gradientMag( I,0,0,0,1 ); softBin = -1; useHog = 2; H = gradientHist(M,O,binSize,nOrients,softBin,useHog,clip); See gradientHist() for more general usage. This code requires SSE2 to compile and run (most modern Intel and AMD processors support SSE2). Please see: http://en.wikipedia.org/wiki/SSE2. USAGE H = fhog( I, [binSize], [nOrients], [clip], [crop] ) INPUTS I - [hxw] color or grayscale input image (must have type single) binSize - [8] spatial bin size nOrients - [9] number of orientation bins clip - [.2] value at which to clip histogram bins crop - [0] if true crop boundaries OUTPUTS H - [h/binSize w/binSize nOrients*3+5] computed hog features EXAMPLE I=imResample(single(imread('peppers.png'))/255,[480 640]); tic, for i=1:100, H=fhog(I,8,9); end; disp(100/toc) % >125 fps figure(1); im(I); V=hogDraw(H,25,1); figure(2); im(V) EXAMPLE % comparison to features.cc (requires DPM code release version 5) I=imResample(single(imread('peppers.png'))/255,[480 640]); Id=double(I); tic, for i=1:100, H1=features(Id,8); end; disp(100/toc) tic, for i=1:100, H2=fhog(I,8,9,.2,1); end; disp(100/toc) figure(1); montage2(H1); figure(2); montage2(H2); D=abs(H1-H2); mean(D(:)) See also hog, hogDraw, gradientHist Piotr's Image&Video Toolbox Version 3.23 Copyright 2013 Piotr Dollar. [pdollar-at-caltech.edu] Please email me if you find bugs, or have suggestions or questions! Licensed under the Simplified BSD License [see external/bsd.txt]
0001 function H = fhog( I, binSize, nOrients, clip, crop ) 0002 % FHOG Efficiently compute Felzenszwalb's HOG (FHOG) features. 0003 % 0004 % FHOG.m A fast implementation of the HOG variant used by Felzenszwalb et al. 0005 % in their work on discriminatively trained deformable part models. 0006 % http://www.cs.berkeley.edu/~rbg/latent/index.html 0007 % Gives nearly identical results to features.cc in code release version 5 0008 % but runs 4x faster (over 125 fps on VGA color images). 0009 % 0010 % The computed HOG features are 3*nOrients+5 dimensional. There are 0011 % 2*nOrients contrast sensitive orientation channels, nOrients contrast 0012 % insensitive orientation channels, 4 texture channels and 1 all zeros 0013 % channel (used as a 'truncation' feature). Using the standard value of 0014 % nOrients=9 gives a 32 dimensional feature vector at each cell. This 0015 % variant of HOG, refered to as FHOG, has been shown to achieve superior 0016 % performance to the original HOG features. For details please refer to 0017 % work by Felzenszwalb et al. (see link above). 0018 % 0019 % This function is essentially a wrapper for calls to gradientMag() 0020 % and gradientHist(). Specifically, it is equivalent to the following: 0021 % [M,O] = gradientMag( I,0,0,0,1 ); softBin = -1; useHog = 2; 0022 % H = gradientHist(M,O,binSize,nOrients,softBin,useHog,clip); 0023 % See gradientHist() for more general usage. 0024 % 0025 % This code requires SSE2 to compile and run (most modern Intel and AMD 0026 % processors support SSE2). Please see: http://en.wikipedia.org/wiki/SSE2. 0027 % 0028 % USAGE 0029 % H = fhog( I, [binSize], [nOrients], [clip], [crop] ) 0030 % 0031 % INPUTS 0032 % I - [hxw] color or grayscale input image (must have type single) 0033 % binSize - [8] spatial bin size 0034 % nOrients - [9] number of orientation bins 0035 % clip - [.2] value at which to clip histogram bins 0036 % crop - [0] if true crop boundaries 0037 % 0038 % OUTPUTS 0039 % H - [h/binSize w/binSize nOrients*3+5] computed hog features 0040 % 0041 % EXAMPLE 0042 % I=imResample(single(imread('peppers.png'))/255,[480 640]); 0043 % tic, for i=1:100, H=fhog(I,8,9); end; disp(100/toc) % >125 fps 0044 % figure(1); im(I); V=hogDraw(H,25,1); figure(2); im(V) 0045 % 0046 % EXAMPLE 0047 % % comparison to features.cc (requires DPM code release version 5) 0048 % I=imResample(single(imread('peppers.png'))/255,[480 640]); Id=double(I); 0049 % tic, for i=1:100, H1=features(Id,8); end; disp(100/toc) 0050 % tic, for i=1:100, H2=fhog(I,8,9,.2,1); end; disp(100/toc) 0051 % figure(1); montage2(H1); figure(2); montage2(H2); 0052 % D=abs(H1-H2); mean(D(:)) 0053 % 0054 % See also hog, hogDraw, gradientHist 0055 % 0056 % Piotr's Image&Video Toolbox Version 3.23 0057 % Copyright 2013 Piotr Dollar. [pdollar-at-caltech.edu] 0058 % Please email me if you find bugs, or have suggestions or questions! 0059 % Licensed under the Simplified BSD License [see external/bsd.txt] 0060 0061 %Note: modified to be more self-contained 0062 0063 if( nargin<2 ), binSize=8; end 0064 if( nargin<3 ), nOrients=9; end 0065 if( nargin<4 ), clip=.2; end 0066 if( nargin<5 ), crop=0; end 0067 0068 softBin = -1; useHog = 2; b = binSize; 0069 0070 [M,O]=gradientMex('gradientMag',I,0,1); 0071 0072 H = gradientMex('gradientHist',M,O,binSize,nOrients,softBin,useHog,clip); 0073 0074 if( crop ), e=mod(size(I),b)<b/2; H=H(2:end-e(1),2:end-e(2),:); end 0075 0076 end


Although many non-profits work and partner with the city and county in
which they reside, all working towards ending homelessness, the
reality is that an end to homelessness may not be possible, and if it
is, at the very least as our Lord said "The poor you will always have with you" (Matthew 26:10-12). They are our brothers and sisters in Christ.
Regardless of why our brothers and sisters are poor or what their
condition of life is, they have the inherent right to be able to have
the necessities for human life that bring dignity and hope.
Here at Mary's Mercy Center we have a constant flow of poor and
homeless people. The numbers fluctuate from time to time but slight
decreases are not long lasting. In sharp contrast the needs of the
poor and homeless have increased dramatically. Where providing food
and clothing for individuals and families seemed to be enough, now the
needs have broadened, i.e., there is need for gasoline money at the
end of the month, the poor cannot always pay all of their rent or
utilities, cannot afford school backpacks or supplies to put in them,
there is not enough money to fill prescriptions, no money for car
repairs, no money for new shoes to replace the severely worn ones.
Preventative medicine for the poor and homeless is nonexistent, simple
needs for infants are unaffordable, and the list goes on. There is a
deepening need among our brothers and sisters. Whether it is seen or
unseen, the terrible need is there and, sadly, growing.
It’s the easiest way to give and ensure that Mary's Mercy Center, Veronica's Home of Mercy, or Mary's Table, receives your ongoing support
All donations are tax deductible.
Mary's Mercy Center, Inc. Tax ID 33-0632426
Mary's Mercy Center, Inc. is a public non-profit organization which is
committed to serve all races, creeds and conditions of life, and
extending unconditional love, acceptance, and respect to all who come
for assistance. Networking with Local agencies has empowered Mary's
Mercy Center to reach out to the poor and powerless of society and
help people grow into useful, affirmed people in today's world.
Restoring dignity to the poor and marginalized, we serve the young,
the old and the mentally and physically challenged.
Our journey began in the mid 1980’s with a divinely inspired vision
shared by members of the Catholic charismatic Renewal Center, under
the direction of Fr. Michael Barry. Challenged by the example and
teachings of Jesus, we began to reach out and serve the poor in our
local communities, working first in local parks with supplies of
food and money to cover utility bills.
From these early outreach efforts, we moved to open a soup kitchen
at Our Lady of Fatima Church in San Bernardino. Soon, the Lutheran
Church of Our Savior added their hands and hearts; and then, Our
Lady of Guadalupe Church followed with a larger kitchen and dining
facility at their location. By 1990, Mary’s Table, as the soup
kitchen had come to be known, had expanded to five days a week and
was serving over 5,000 hot meals each month. It had become a haven,
a place of rest, fellowship and renewal for many. In 1996, a free
medical screening was added to Mary’s Mercy Center, which had
already expanded to include a clothes closet, an emergency food bag
program and other services.
Even before this, in 1989, fundraising had begun with the help of
the 300 Club for a major expansion that would become Mary’s Mercy
Center. In 1992, we purchased our present building and became
incorporated as a non-profit public benefit corporation, organized
exclusively for charitable, religious and education purposes. In
1993, the Sisters of Charity of the Incarnate Word provided a
substantial grant for the purchase of an old convent that would be
transformed into Veronica’s Home of Mercy. Veronica’s Home of Mercy
was opened in 1995. Before that Casa Merced (a HUD House) opened its
doors in 1994. Then in 2009 Veronica’s Home II opened its doors.
Mary’s Mercy Center currently welcomes approximately 300 volunteers
of various faiths, schools, and community organizations from
throughout Southern California. We are proud to network with city
agencies, county agencies, and other non-profits to direct our
clients to additional resources. The goal is to restore dignity and
purpose to the homeless, the poor and the marginalized. Homelessness
and poverty are complicated issues and the solutions are as varied
as the individuals we serve. Together we are making a difference in
the lives of many.
Mary's table provides a hot nutritious meal six days a week, including all holidays except Christmas Day. Meals are served to all who come regardless of their situation and no identification is required. After our guests are seated, volunteers serve them their coffee, ice tea, and/or milk. There are no limits on the number of servings for each guest. They are allowed to eat as often as they wish or need to eat.Over 8,000 meals are served each month. Our food comes from many different sources: almost all of our meat is donated; some food and all staples are purchased from food banks, stores and large corporations. We share food among our fellow non-profits when there is an over abundance.
St. Martin de Porres Emergency Food Bag Program distributes food bags every Wednesday, except the first Wednesday of the Month. Approximately 1,200 families are helped each month. For those with a facility to cook the bags contain beans, rice, tomato sauce, bread, cereal, fruit, etc. For the homeless and unable to cook the bags contain canned foods, cups of soup, energy bars, peanut butter and jelly, fruit, bread and bottled water. No identification is required to receive assistance.
Showers are available for women on Mondays and Wednesdays from 8 am to 10:30 am and for men on Tuesdays and Thursdays from 7:30 am to 10:30 am. Prior to their shower each person is given clean clothing and a hygiene packet.
is open at the Center on Wednesday mornings
each quarter
St. Joseph's Clothes Closet distributes free clothing. Clothing is distributed to women and children on Mondays from 9am to 11am. We usually have a good supply of women's clothing but there is a great need for men's, children's and infant's clothing.
Mary's Children Program is an outreach established to help mother/guardians in crisis with infant needs: formula, diapers, blankets, bottles, baby food, shampoo and lotion. This program serves approximately 60 families each month. The items are given free of charge but do require a referral from a social worker, doctor or hospital.
An Annual Christmas Party is held in December. This outreach has grown into a very large and heartwarming event. Thanks to hundreds of generous donors and organizations we are able to serve over 1,300 children and 600 adults. In addition to a warm holiday meal, Mary's Mercy Center gives each child a new wrapped gift and candy. As a special surprise each child participates in a drawing. If their ticket says "WINNER" they receive a larger gift and if the ticket says "BIKE" they receive a new bike. Adults and older teens receive a "shoebox" with toiletries and some special item, a wallet, cologne, or a scarf for example.
Veronica's Home of Mercy I and Veronica's Home of Mercy II,
long-term Catholic/Christian residential homes, are committed
to providing a home for adult pregnant women and their
children as a healthy alternative to abortion, domestic
violence, substance abuse and/or homelessness. Veronica's Home
of Mercy provides a loving and affirming atmosphere that will
restore dignity to women. The goal is to enable the individual
woman to integrate into society and live with a renewed sense
of her own worth and dignity. It is important to know that
Veronica's Home of Mercy has never refused admission to any
woman because of race, creed or lack of funds
Our Program is extensive and comprehensive. Qualified staff
provide drug and alcohol counseling, twelve-step meetings,
child care, transportation, life skills and 24-hour
supervision. In collaboration with ten other institutions and
professional programs within the community Veronica's Home of
Mercy offers the following:
Veronica's Home of Mercy has deep roots in the community. We are committed to the larger community, and the larger community is committed and involved with Veronica's Home of Mercy.
After Care
Follow through is very important. It can mean the difference between a resident's success and failure. Casa Merced I, Casa Merced II and Casa Merced III are our re-entry homes. These single-family residential homes are reserved for women who have finished the program at Veronica's Home of Mercy and are doing extremely well but are in need of some assistance until they finish school. These homes provide a more relaxed atmosphere and greater independence. The low rent and access to the support of the staff helps ease the women back into society.
We encourage our residents to keep in touch with us. Our staff, in-house classes and activities are readily available to our graduates. If they leave in good standing we invite them to come back and celebrate holidays and birthdays with us. This is especially helpful for those who have no family
With 47% of the city residents on welfare, food stamps, Medi-Cal, or a combination thereof; 38% living at or below the poverty level; and over 50% of the population is living at 200% of the federal poverty level, San Bernardino is the second poorest city in the nation just behind Detroit.
While the City of San Bernardino accounts for only 10% of the county’s population it has 40% of its homeless population and approximately 70% are males. The San Bernardino County 2013 Homeless Count and Subpopulation Survey found 2,321 homeless individuals throughout the county. Approximately 45% of the homeless population had been homeless for a year or more, 34% abused alcohol and/or drugs and 26% experienced mental illness.
Most individuals experiencing homelessness reported a job loss, unemployment or alcohol/drug use as the primary event or condition that led to their homelessness. Without structured, formal, comprehensive support, many of these individuals will remain living on the streets and resort to criminal activities resulting in increased costs to the taxpayers and a decrease in community safety.
There are comprehensive programs for homeless women and homeless women with children however there are no comprehensive housing programs for homeless men in the Central San Bernardino Region.
Mary’s Mercy Center has been serving homeless individuals and individuals at-risk of becoming homeless with dignity and respect since 1987. Over the years, thousands of individuals have received hot meals, clothing, supportive services, showers, food, medical and dental services through Mary’s Mercy Center.Since 1995, Mary’s Mercy Center has been providing women and women with children comprehensive, transitional housing services. This program has grown and now serves well over 100 individuals annually.
In 2012, with an understanding of the lack of resources for homeless men, Mary’s Mercy Center made a commitment to provide the same high quality, evidence-based programming for men that they do for women. Mary’s Village will provide comprehensive services including behavioral health, medical and other supportive services, at one location. Mary’s Mercy Center is looking forward to working with the community to improve the lives of homeless individuals, thus changing the entire community.”
“We have made at least the start in discovering the meaning in human life when we plant shade trees under which we will never sit.” -Elton Trueblood
Make a difference
Become an active participant
Mary’s Mercy Center is very proud to be home to approximately 300 volunteers of different faiths coming to us from Los Angeles, Riverside and San Bernardino Counties. Mary’s Mercy Center networks with other non-profit agencies and many of the city and county agencies. Loma Linda University’s Department of Nursing visits Mary’s Table hosting Blood Pressure and Diabetes Clinics regularly. Boy Scouts, Girl Scouts, youth groups and neighborhood youth volunteer at Mary’s Mercy Center for their community service requirements. Individual church communities who sponsor fund-raisers and volunteers. You are invited to become an active member of Mary's Mercy Center! It isn't always the people on site that make the total difference.
By coming on board you become members and part of the ongoing growth and development for the vision of Mary's Mercy Center. Since the opening of Veronica's Home of Mercy II in late 2009 we have set our sights on a shelter for men. The needs of the poor and homeless are tremendous, but we do what we can with God's help and your support. It is important to note that on average, grants awarded to Mary's Mercy Center only account for 40% of the corporation's total budget, and that administrative costs are only 9% of the total budget. Mary's Mercy Center exists, runs and operates mostly dependent on the mercy of God in your heart. Donations and contributions are vital and essential.
All donations are tax deductible.
Mary's Mercy Center, Inc.
Tax ID 33-0632426
Monday - Thursday
9:00am - 4:00pm PST


Dei Legionari Airport Arrivals
TRS Arrivals: Fri Jan 09, 2009 12:00PM - 12:00AM
Picking up a Passenger?Stay Informed on the Road - Sign up for Flight Alerts to be sent straight to your mobile phone. Or check the latest information using FlightStats Mobile. |
|
|
|
Real-time Flight Tracker Airport Flight Tracker On-time Performance Ratings |
Flight Alerts Flight Availability |
| Get This Widget | Personal Tools |
|
For Your Website For iGoogle or Windows Live! |
Other FlightStats Widgets Toolbar Buttons |
| Welcome Guest - Login | My Account | REGIONAL SITES: |


FAQ¶
- What is iocage?
iocage is a jail management program designed to simplify jail administration tasks.
- What is a jail?
A Jail is a FreeBSD OS virtualization technology allowing users to run multiple copies of the operating system. Some operating systems use the term Zones or Containers for OS virtualization.
- What is VNET?
VNET is an independent, per jail virtual networking stack.
- How do I configure network interfaces in a VNET or shared IPjail?
Both are configured in the same way: iocage set ip4_add="[interface]|[IP]/[netmask]" [UUID | NAME]. For more info, please refer to the Networking section of this documentation.
- Do I need to set my default gateway?
Only if VNET is enabled. You need to assign an IP address to the bridge where the jail interface is attached. This IP essentially becomes the default gateway for your jail.
- Can I run a firewall inside a jail?
Yes, a VNET jail supports IPFW. PF is not supported inside the jail. However, you can still enable PF for the host. If you plan to use IPFW inside a jail, be sure securelevel is set to 2.
- Can I enable both IPFW and PF at the same time?
Yes, make sure you allow traffic on both in/out for your jails.
- Can I create custom jail templates?
Yes, and thin provisioning is supported too!
- What is a jail clone?
Clones are ZFS clones. These are fully writable copies of the source jail.
- Can I limit the CPU and Memory use?
Yes, but only for legacy versions of iocage. Refer to the
iocage.8
manual page or Resource Limits (Legacy ONLY) section of this documentation for more details.- Is there a way to display resource consumption?
Yes - iocage df [UUID | NAME]
- Is NAT supported for jails?
Yes. NAT is built into FreeBSD. Treat your server as a core router/firewall. Check the FreeBSD Firewalls chapter for more details.
- Will iocage work on a generic system with no ZFS pools?
No. ZFS is a must. If you run a FreeBSD server, you should be using ZFS!
- Is ZFS jailing supported?
Yes, please refer to the
iocage.8
manual page.


Phone number here<EMAIL_ADDRESS>Linkedin.com/username City name ,State, Zip
EDUCATION
Degree name
Name of the institute
Date of passing
EXPERTISE
Your skill goes here
PROFESSIONAL PROFILE
Here u can write the basic information about your career like your forte, something about yourself that
you want your interviewer to know. Try to keep it brief and only provide necessary information. Do not include information which is
already written in your resume in some other section.
NEW SECTION
This is the description part of your new section. Try to stay within limit and write something which has less than 200 words. The spaces and symbols you use will also be included so use them for an indentation effect.


Check the console for a quote!
| Assignment # | Description |
|---|---|
| 1. | Creating a landing page for my class assignments |
| 2. | Animated GIFs |
| 3. | Painting Tools |
| 4. | Swarm Simulation |
| 5. | Blockchain Chatbot |
| 6. | Chasing Money or Community Simulation |
| 7. | Parameterized Mechanical Pencils |
| 9. | Blue Demon Rorschach Mask |


Mars Rover Challenge
• Rover is roving a 3x3 grid.
• Input the starting coordinates on the first form.
• Input the instructions to the rover on the second form.


|
| file | backend.c |
| | Everything related to a backend.
|
| |
| file | global.c |
| | Helpers for global plugins.
|
| |
| file | internal.c |
| | Internal methods for Elektra.
|
| |
| file | kdb.c |
| | Low level functions for access the Key Database.
|
| |
| file | kdbenum.c |
| | dummy file do document the enums which have no name in the header file.
|
| |
| file | key.c |
| | Methods for Key manipulation.
|
| |
| file | keyhelpers.c |
| | Helpers for key manipulation.
|
| |
| file | keymeta.c |
| | Methods to do various operations on Key metadata.
|
| |
| file | elektra/keyname.c |
| | Methods for Key name manipulation.
|
| |
| file | keyset.c |
| | Methods for key sets.
|
| |
| file | keytest.c |
| | Methods for making tests.
|
| |
| file | keyvalue.c |
| | Methods for Key value manipulation.
|
| |
| file | log.c |
| | Non-C99 Logger Implementation.
|
| |
| file | mount.c |
| | Internals of mount functionality.
|
| |
| file | nolog.c |
| | C99-compatible Fake Logger Implementation.
|
| |
| file | opmphm.c |
| | The Order Preserving Minimal Perfect Hash Map.
|
| |
| file | opmphmpredictor.c |
| | The Order Preserving Minimal Perfect Hash Map Predictor.
|
| |
| file | owner.c |
| | Obsolete owner methods.
|
| |
| file | elektra/plugin.c |
| | Interna of plugin functionality.
|
| |
| file | elektra/proposal.c |
| | Implementation of proposed API enhancements.
|
| |
| file | rand.c |
| | Rand for Elektra.
|
| |
| file | split.c |
| | Interna of splitting functionality.
|
| |
| file | trie.c |
| | Interna of trie functionality.
|
| |


Interactive Media Creator
+
Full Stack Web Developer
My name is Sunil Rao and I'm a software developer operating in the Chicago, IL area. My skills lie in the creation of interactive graphical applications as well as web applications.
Welcome to my portfolio! With technology seeping into our everyday lives, ranging from the rise of the "internet of things" to a large segment of the population relying on social media services to get their news, now more than ever it is imporant to build our applications and services with care and responsibility. My work ranges from games raising awareness of mental health issues to web applications that increase voter engagement with local/state elections. Below you can find my projects and work experience.
As you can see below, game development is one of my passions. You can follow along with my current game projects over here.
C#, C++, Java, JavaScript, ActionScript, HTML5
Hibernate, Spring, NodeJS
WebGL, ThreeJS
C, ASM, Python
OpenSceneGraph, Oculus SDK
Android+iOS App Development, Photoshop, SketchUp