Skip to content
This repository has been archived by the owner on Oct 2, 2022. It is now read-only.

Releases: ContainerSSH/http

0.9.5: Added config validation

29 Dec 23:30
Compare
Choose a tag to compare
Pre-release

This release adds a Validate() method to both the client and the server configuration. This will allow for a central validation of the entire configuration structure.

0.9.4: Rolled back context handling

15 Dec 00:52
19efe54
Compare
Choose a tag to compare
Pre-release

This release removes the previously erroneously added context handling.

0.9.3: Context handling, better errors

15 Dec 00:29
34024f8
Compare
Choose a tag to compare
Pre-release

This release includes two changes:

  1. The Post() method now accepts a context variable as its first parameter for timeout handling.
  2. The Post() method now exclusively returns a http.ClientError, which includes the reason for failure.

0.9.2: URL instead or Url

12 Dec 00:05
d60119e
Compare
Choose a tag to compare
Pre-release

This release changes the Url variable for the client to URL. It also bumps the log dependency to the latest release.

0.9.1: Service Integration

23 Nov 06:52
Compare
Choose a tag to compare
Pre-release

This release changes the API of the HTTP server to integrate with the Service library. The public interface now requires using the Lifecycle object to start and stop the server. The Lifecycle also allows adding hooks for lifecycle events.

server, err := http.NewServer(
    "service name",
    http.ServerConfiguration{
        //...
    },
    handler,
    logger,
)
if err != nil {
    // Handle configuration error
}
// Lifecycle from the github.com/containerssh/service package
lifecycle := service.NewLifecycle(server)
//Add an event hook
lifecycle.OnRunning(...)
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())

0.9.0: Initial Release

23 Nov 06:49
Compare
Choose a tag to compare
Pre-release

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",
}
client, err := http.NewClient(clientConfig, logger)
if err != nil {
    // Handle validation error
}

request := yourRequestStruct{}
response := yourResponseStruct{}
responseStatus := uint16(0)

if err := client.Post(
    "/relative/path/from/base/url",
    &request,
    &responseStatus,
    &response,
); err != nil {
    // Handle connection error
}

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,
)
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.

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.