Categorygithub.com/containerssh/http
modulepackage
1.3.0
Repository: https://github.com/containerssh/http.git
Documentation: pkg.go.dev

# README

ContainerSSH - Launch Containers on Demand

ContainerSSH HTTP Library

Go Report Card LGTM Alerts

This library provides a common layer for HTTP clients and servers in use by ContainerSSH.

⚠⚠⚠ Warning: This is a developer documentation. ⚠⚠⚠
The user documentation for ContainerSSH is located at containerssh.io.

Using this library

This library provides a much simplified API for both the HTTP client and server.

Using the client

The client library takes a request object that can be marshalled into JSON format and sends it to the server. It then fills a response object with the response received from the server. In code:

// Logger is from the github.com/containerssh/log package
logger := standard.New()
clientConfig := http.ClientConfiguration{
    URL:        "http://127.0.0.1:8080/",
    Timeout:    2 * time.Second,
    // You can add TLS configuration here:
    CaCert:     "Add expected CA certificate(s) here.",
                // CaCert is is required for https:// URLs on Windows due to golang#16736
    // Optionally, for client authentication:
    ClientCert: "Client certificate in PEM format or file name",
    ClientKey:  "Client key in PEM format or file name",
    // Optional: switch to www-urlencoded request body
    RequestEncoding: http.RequestEncodingWWWURLEncoded,
}
client, err := http.NewClient(clientConfig, logger)
if err != nil {
    // Handle validation error
}

request := yourRequestStruct{}
response := yourResponseStruct{}

responseStatus, err := client.Post(
    context.TODO(),
    "/relative/path/from/base/url",
    &request,
    &response,
)
if err != nil {
    // Handle connection error
    clientError := &http.ClientError{}
    if errors.As(err, clientError) {
        // Grab additional information here
    } else {
    	// This should never happen
    }
}

if responseStatus > 399 {
    // Handle error
}

The logger parameter is a logger from the github.com/containerssh/log package.

Using the server

The server consist of two parts: the HTTP server and the handler. The HTTP server can be used as follows:

server, err := http.NewServer(
    "service name",
    http.ServerConfiguration{
        Listen:       "127.0.0.1:8080",
        // You can also add TLS configuration
        // and certificates here:
        Key:          "PEM-encoded key or file name to cert here.",
        Cert:         "PEM-encoded certificate chain or file name here",
        // Authenticate clients with certificates:
        ClientCACert: "PEM-encoded client CA certificate or file name here",
    },
    handler,
    logger,
    func (url string) {
        fmt.Printf("Server is now ready at %s", url)
    }
)
if err != nil {
    // Handle configuration error
}
// Lifecycle from the github.com/containerssh/service package
lifecycle := service.NewLifecycle(server)
go func() {
    if err := lifecycle.Run(); err != nil {
        // Handle error
    }
}()
// Do something else, then shut down the server.
// You can pass a context for the shutdown deadline.
lifecycle.Shutdown(context.Background())

Like before, the logger parameter is a logger from the github.com/containerssh/log package. The handler is a regular go HTTP handler that satisfies this interface:

type Handler interface {
    ServeHTTP(http.ResponseWriter, *http.Request)
}

The lifecycle object is one from the ContainerSSH service package.

Using a simplified handler

This package also provides a simplified handler that helps with encoding and decoding JSON messages. It can be created as follows:

handler := http.NewServerHandler(yourController, logger)

The yourController variable then only needs to implement the following interface:

type RequestHandler interface {
	OnRequest(request ServerRequest, response ServerResponse) error
}

For example:

type MyRequest struct {
    Message string `json:"message"`
}

type MyResponse struct {
    Message string `json:"message"`
}

type myController struct {
}

func (c *myController) OnRequest(request http.ServerRequest, response http.ServerResponse) error {
    req := MyRequest{}
	if err := request.Decode(&req); err != nil {
		return err
	}
	if req.Message == "Hi" {
		response.SetBody(&MyResponse{
			Message: "Hello world!",
		})
	} else {
        response.SetStatus(400)
		response.SetBody(&MyResponse{
			Message: "Be nice and greet me!",
		})
	}
	return nil
}

In other words, the ServerRequest object gives you the ability to decode the request into a struct of your choice. The ServerResponse, conversely, encodes a struct into the the response body and provides the ability to enter a status code.

Content negotiation

If you wish to perform content negotiation on the server side, this library now supports switching between text and JSON output. This can be invoked using the NewServerHandlerNegotiate method instead of NewServerHandler. This handler will attempt to switch based on the Accept header sent by the client. You can marshal objects to text by implementing the following interface:

type TextMarshallable interface {
	MarshalText() string
}

Using multiple handlers

This is a very simple handler example. You can use utility like gorilla/mux as an intermediate handler between the simplified handler and the server itself.

# Functions

NewClient creates a new HTTP client with the given configuration.
NewClientWithHeaders creates a new HTTP client with added extra headers.
NewServer creates a new HTTP server with the given configuration and calling the provided handler.
NewServerHandler creates a new simplified HTTP handler that decodes JSON requests and encodes JSON responses.
NewServerHandlerNegotiate creates a simplified HTTP handler that supports content negotiation for responses.goland:noinspection GoUnusedExportedFunction.

# Constants

Elliptic curve algorithms.
Elliptic curve algorithms.
Elliptic curve algorithms.
Elliptic curve algorithms.
Elliptic curve algorithms.
Elliptic curve algorithms.
This message indicates that ContainerSSH is not following a HTTP redirect sent by the server.
This message indicates a connection failure on the network level.
This message indicates that decoding the JSON response has failed.
This message indicates that JSON encoding the request failed.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
This message indicates that the server responded with a HTTP redirect.
This message indicates that a HTTP request is being sent from ContainerSSH.
This message indicates that ContainerSSH received a HTTP response from a server.
The HTTP server failed to encode the response object.
The HTTP server failed to write the response.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
RequestEncodingJSON is the default encoding and encodes the body to JSON.
RequestEncodingJSON encodes the body to JSON.
RequestEncodingWWURLEncoded encodes the body via www-urlencoded.
No description provided by the author
No description provided by the author

# Structs

ClientConfiguration is the configuration structure for HTTP clients We are adding the JSON and YAML tags to conform to the Operator SDK requirements to tag all fields.goland:noinspection GoVetStructTag.
ServerConfiguration is a structure to configure the simple HTTP server by.goland:noinspection GoVetStructTag.

# Interfaces

Client is a simplified HTTP interface that ensures that a struct is transported to a remote endpoint properly encoded, and the response is decoded into the response struct.
RequestHandler is an interface containing a simple controller receiving a request and providing a response.
Server is an interface that specifies the minimum requirements for the server.
ServerRequest is a data structure providing decoding from the raw request.
ServerResponse is a response structure that can be used by the RequestHandler to set the response details.
region Text.

# Type aliases

CipherSuite is the cipher suite used for TLS connections.
CipherSuiteList is a list of cipher suites.
ECDHCurve is an elliptic curve algorithm.
ECDHCurveList is a list of supported ECDHCurve.
RequestEncoding is the method by which the response is encoded.
TLSVersion is the version of the TLS protocol to use.