Documentation
¶
Overview ¶
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Index ¶
- Constants
- Variables
- func Middleware(g *Gateway, next http.Handler) http.Handler
- type ErrorCode
- type ErrorHandler
- type Gateway
- type GatewayError
- type GatewayOption
- type HostnameAllowlist
- type JSONProblemErrorHandler
- type KeyConfig
- type KeyConfigs
- type KeyPair
- type MessageInfo
- type RequestValidator
- type ResponseDecapsulator
- type ResponseEncapsulator
- type ResponseStatusError
- type SecretKeyFinder
- type SecretKeyInfo
- type SymmetricAlgorithm
- type Transport
- func (c *Transport) Encapsulate(req *http.Request) (*http.Request, *ResponseDecapsulator, error)
- func (c *Transport) EncapsulateWithMessageInfo(req *http.Request) (*http.Request, *ResponseDecapsulator, MessageInfo, error)
- func (c *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error)
- type TransportOption
Constants ¶
const ( // RequestMediaType is the media type for an OHTTP Request per RFC 9458. RequestMediaType = "message/ohttp-req" // ResponseMediaType is the media type for an OHTTP Response per RFC 9458. ResponseMediaType = "message/ohttp-res" // ChunkedRequestMediaType is the media type for a Chunked OHTTP Request per // the Chunked Oblivious HTTP Messages Draft RFC. ChunkedRequestMediaType = "message/ohttp-chunked-req" // ChunkedResponseMediaType is the media type for a Chunked OHTTP Response per // the Chunked Oblivious HTTP Messages Draft RFC. ChunkedResponseMediaType = "message/ohttp-chunked-res" )
const DefaultAllowedHostname = "ohttp.invalid"
DefaultAllowedHostname is the hostname that will be added to an otherwise empty [HostnameAllowList].
This hostname is guaranteed to be non-routable due to the .invalid TLD. This way you need to pick an explicit Target Resource hostname when using the Gateway together with a proxy.
Variables ¶
var ( ErrorKeyNotYetActive = errors.New("key not yet active") ErrorKeyExpired = errors.New("key expired") )
var ErrChunkedResponseEncoderMismatch = errors.New("ohttp.Middleware used with an incompatible response encoder")
var ErrHostnameNotAllowed = errors.New("hostname not allowed")
ErrHostnameNotAllowed indicates a hostname is not allowed.
Functions ¶
func Middleware ¶
Middleware uses the gateway as a handler middleware.
The wrapped handler represents a Target Resource. It receives the decapsulated request and writes a decapsulated response. It can either deal with these directly, or proxy them elsewhere.
The Middleware follows the net/http Server logic when deciding whether a response should be chunked or not. Upon detecting a chunked response, it will encapsulate and begin streaming chunks.
Important when using custom response encoders: This middleware is only compatible with response encoders that map responses with chunked Transfer-Encoding, to chunked OHTTP messages. If there is disagreement, this handler will begin returning ErrChunkedResponseEncoderMismatch. It will also call the error handler on the gateway with this error.
The default BHTTP encoding is fully compatible with this middleware.
Types ¶
type ErrorCode ¶
type ErrorCode int
ErrorCode is the error code of a gateway error.
const ( ErrorCodeRequestIO ErrorCode = 1 ErrorCodeResponseIO ErrorCode = 2 ErrorCodeInvalidRequestHeader ErrorCode = 100 ErrorCodeKeyNotFound ErrorCode = 101 ErrorCodeInvalidKey ErrorCode = 102 ErrorCodeInactiveKey ErrorCode = 103 ErrorCodeInvalidRequestContentType ErrorCode = 200 ErrorCodeRequestDecoding ErrorCode = 201 ErrorCodeInvalidRequest ErrorCode = 202 ErrorCodeResponseEncoding ErrorCode = 300 ErrorCodeResponseEncryption ErrorCode = 301 )
Error codes returned by the Gateway.
type ErrorHandler ¶
type ErrorHandler interface {
// HandleError handles the provided error.
//
// headersWritten indicates whether the error handler can still write headers or not.
//
// Because the Gateway records the response of the inner handler, there is no guarantee
// that the inner handler writing a header will also make the Gateway immediately write a header.
HandleError(w http.ResponseWriter, headersWritten bool, err error)
}
ErrorHandler is used to write or log errors from the Gateway.
type Gateway ¶
type Gateway struct {
// contains filtered or unexported fields
}
Gateway is an OHTTP Gateway. It decapsulates incoming requests and encapsulates outgoing responses.
The Gateway is designed to be used as a http Middleware but can also be used as a standalone component by calling [DecapRequest] directly.
By default the Gateway only accepts decapsulated requests with a DefaultAllowedHostname hostname. This is to prevent the Gateway being used as a relay to arbitrary Target Resources.
This behaviour can be overwritten by providing a custom HostnameAllowlist or RequestValidator implementation.
func NewGateway ¶
func NewGateway(finder SecretKeyFinder, opts ...GatewayOption) (*Gateway, error)
NewGateway creates a new OHTTP Gateway.
func (*Gateway) Decapsulate ¶
Decapsulate decapsulates an OHTTP request. Decapsulate returns the decapsulated request as well as a response encapsulator that can be used to encapsulate the corresponding response.
type GatewayError ¶
GatewayError is an error that occurred during the handling of an encapsulated OHTTP request. Gateway error handlers can check for this error and derive more detailed information.
func (GatewayError) Error ¶
func (e GatewayError) Error() string
func (GatewayError) IsGeneralError ¶
func (e GatewayError) IsGeneralError() bool
IsGeneralError indicates whether the error is a general error.
func (GatewayError) IsKeyError ¶
func (e GatewayError) IsKeyError() bool
IsKeyError indicates whether the error has a key-related error code.
func (GatewayError) IsRequestError ¶
func (e GatewayError) IsRequestError() bool
IsRequestError indicates whether the error has a request-related error code.
func (GatewayError) IsResponseError ¶
func (e GatewayError) IsResponseError() bool
IsResponseError indicates whether the error has a response-related error code.
func (GatewayError) Unwrap ¶
func (e GatewayError) Unwrap() error
type GatewayOption ¶
type GatewayOption func(cfg *gatewayCfg) error
GatewayOption configures a gateway.
func WithErrorHandler ¶
func WithErrorHandler(errHandler ErrorHandler) GatewayOption
WithErrorHandler provides a custom error handler for a gateway.
func WithOTELTracer ¶
func WithOTELTracer(tracer trace.Tracer) GatewayOption
WithOTELTracer provides a custom request validator for a gateway. Set the validator to nil to disable request validation. Be careful as clients can send requests with any hostname.
func WithRequestDecoder ¶
func WithRequestDecoder(dec encoding.RequestDecoder) GatewayOption
WithRequestDecoder provides a custom request decoder for a gateway.
func WithRequestValidator ¶
func WithRequestValidator(validator RequestValidator) GatewayOption
WithRequestValidator provides a custom request validator for a gateway. Set the validator to nil to disable request validation. Be careful as clients can send requests with any hostname.
type HostnameAllowlist ¶
type HostnameAllowlist struct {
// contains filtered or unexported fields
}
HostnameAllowlist is a RequestValidator that checks the hostname on a decapsulated request against the hostnames in the list.
func NewHostnameAllowlist ¶
func NewHostnameAllowlist(hostnames ...string) HostnameAllowlist
NewHostnameAllowlist creates new HostnameAllowList with the given hostnames.
If no hostnames are provided, this function will automatically add DefaultAllowedHostname.
func (HostnameAllowlist) ValidRequest ¶
func (l HostnameAllowlist) ValidRequest(r *http.Request) error
ValidRequest checks if the given request has a hostname that is allowed. If the hostname is on the list, the request will be valid, if it's not on the list the request will be invalid and ErrHostnameNotAllowed will be returned.
type JSONProblemErrorHandler ¶
type JSONProblemErrorHandler struct {
LogFunc func(err error)
}
JSONProblemErrorHandler writes errors as application/json+problem responses and optionally logs error with the provided LogFunc.
func (*JSONProblemErrorHandler) HandleError ¶
func (h *JSONProblemErrorHandler) HandleError(w http.ResponseWriter, headersWritten bool, err error)
HandleError logs the error and writes a JSON problem response if no headers have been written.
type KeyConfig ¶
type KeyConfig struct {
KeyID byte
KemID hpke.KEM
PublicKey kem.PublicKey
SymmetricAlgorithms []SymmetricAlgorithm
}
KeyConfig is a key configuration as specified in RFC 9458. Key configs are serialized according to the format specified in section 3.1.
It provides the information required by a client to encapsulate requests for a specific gateway.
The RFC does not specify how the client acquires a key configuration, just its format.
func (KeyConfig) MarshalBinary ¶
MarshalBinary marshals the KeyConfig to the binary representations specified in the RFC.
func (*KeyConfig) UnmarshalBinary ¶
UnmarshalBinary unmarshals a key config from the binary representation specified in the RFC.
type KeyConfigs ¶
type KeyConfigs []KeyConfig
KeyConfigs is a list key of configurations as specified in RFC 9458.
These key configurations are serialized to the application/ohttp-keys format specified in section 3.2 of the RFC.
func (KeyConfigs) MarshalBinary ¶
func (k KeyConfigs) MarshalBinary() ([]byte, error)
MarshalBinary marshals the key configurations to binary application/ohttp-keys format.
func (*KeyConfigs) UnmarshalBinary ¶
func (k *KeyConfigs) UnmarshalBinary(p []byte) error
UnmarshalBinary unmarshals the key configurations from the application/ohttp-keys binary format.
type KeyPair ¶
type KeyPair struct {
SecretKey kem.PrivateKey
KeyConfig KeyConfig
}
Keypair combines a private key with its KeyConfig. Can be provided as a SecretKeyFinder to a Gateway. Suites are constructed as circl/hpke suites.
func (KeyPair) FindSecretKey ¶
func (k KeyPair) FindSecretKey(_ context.Context, header twoway.RequestHeader) (SecretKeyInfo, error)
FindSecretKey checks if the keypair matches the given header and returns appropriate info if it does.
type MessageInfo ¶
type MessageInfo struct {
// Len indicates the length of an unchunked OHTTP message.
Length int
// HeaderLen returns the length of the fixed header portion of this message.
HeaderLen int
// MaxCiphertextChunkLen returns the maximum length of a ciphertext chunk. Only applies
// to chunked OHTTP messages.
MaxCiphertextChunkLen int
}
MessageInfo returns additional information about an OHTTP message.
type RequestValidator ¶
RequestValidator validates decapsulated requests before the Gateway forwards them the wrapped handler.
The validator operates on the same request as the wrapped handler. Keep that in mind if the request body is read as part of validation.
When using creating a custom request validator for a Gateway that redirects decapsulated requests be sure to validate the hostname to prevent unexpected redirects.
type ResponseDecapsulator ¶
type ResponseDecapsulator struct {
// contains filtered or unexported fields
}
ResponseDecapsulator decapsulates an OHTTP response.
func (*ResponseDecapsulator) Decapsulate ¶
func (d *ResponseDecapsulator) Decapsulate(ctx context.Context, encapResp *http.Response) (*http.Response, error)
Decapsulate decapsulates the provided OHTTP response and returns the original response.
type ResponseEncapsulator ¶
type ResponseEncapsulator struct {
// contains filtered or unexported fields
}
ResponseEncapsulator encapsulates a response.
func (*ResponseEncapsulator) Encapsulate ¶
Encapsulate encapsulates the response as an OHTTP response.
func (*ResponseEncapsulator) EncapsulateWithMessageInfo ¶
func (e *ResponseEncapsulator) EncapsulateWithMessageInfo(resp *http.Response) (*http.Response, MessageInfo, error)
EncapsulateWithMessageInfo does the same [Encapsulate] but returns additional meta data about the body of the encapsulated response.
type ResponseStatusError ¶
ResponseStatusError is an error code that was discovered during the transport (decap) of an OHTTP response. This helper type is used for passing error state around should an encapsulated response return a non-200 status code.
func (ResponseStatusError) Error ¶
func (e ResponseStatusError) Error() string
func (ResponseStatusError) IsClientError ¶
func (e ResponseStatusError) IsClientError() bool
func (ResponseStatusError) Unwrap ¶
func (e ResponseStatusError) Unwrap() error
type SecretKeyFinder ¶
type SecretKeyFinder interface {
FindSecretKey(ctx context.Context, header twoway.RequestHeader) (SecretKeyInfo, error)
}
SecretKeyFinder finds secret key info for a given request header.
This allows the Gateway to find appropriate keys on-demand before a request is decapsulated.
type SecretKeyInfo ¶
type SecretKeyInfo struct {
KeyID byte
Suite twoway.HPKESuite
Key kem.PrivateKey
}
SecretKeyInfo holds the identity and suite information for a private key.
type SymmetricAlgorithm ¶
SymmetricAlgorithm is a pair of KDF and AEAD identifiers that a Gateway supports.
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport is a http.RoundTripper that transports requests and responses over OHTTP.
func NewTransport ¶
func NewTransport(keyConfig KeyConfig, relayURL string, opts ...TransportOption) (*Transport, error)
NewTransport creates a new transport for the given keyConfig and options.
func NewTransportWithSender ¶
func NewTransportWithSender(sender *twoway.RequestSender, relayURL string, opts ...TransportOption) (*Transport, error)
NewTransportWithSender creates a new transport with the provided sender. This method allows for the creation of Transports with custom HPKE suites.
func (*Transport) Encapsulate ¶
Encapsulate encapsulates the request as an OHTTP request. Encapsulate returns the encapsulated request and a response decapsulator that can be used to decapsulate the corresponding response.
func (*Transport) EncapsulateWithMessageInfo ¶
func (c *Transport) EncapsulateWithMessageInfo(req *http.Request) (*http.Request, *ResponseDecapsulator, MessageInfo, error)
EncapsulateWithMessageInfo does the same as Encapsulate, but returns additional meta data about the body of the encapsulated request.
type TransportOption ¶
type TransportOption func(cfg *transportCfg) error
TransportOption allows for the configuration of Transports.
func WithHTTPClient ¶
func WithHTTPClient(c *http.Client) TransportOption
WithHTTPClient provides a custom http client to the Transport.
func WithOTELTransportTracer ¶
func WithOTELTransportTracer(tracer trace.Tracer) TransportOption
WithOTELTransportTracer provides a custom otel tracer for the transport to use for tracing
func WithRequestEncoder ¶
func WithRequestEncoder(enc encoding.RequestEncoder) TransportOption
WithRequestEncoder provides a custom request encoder to the Transport.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
bhttp
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
examples
|
|
|
client
command
|
|
|
fakerelay
command
|
|
|
gateway
command
|