/artipie-http

HTTP Artipie Layer

Primary LanguageJavaMIT LicenseMIT

Join our Telegramm group

EO principles respected here DevOps By Rultor.com We recommend IntelliJ IDEA

Javadoc License codecov Hits-of-Code Maven Central PDD status

HTTP

Artipie HTTP base interfaces.

If you have any question or suggestions, do not hesitate to create an issue or contact us in Telegram.
Artipie roadmap.

To install add this dependency to pom.xml file:

<dependency>
  <groupId>com.artipie</groupId>
  <artifactId>http</artifactId>
  <version><!-- use latest version --></version>
</dependency>

This module tends to be reactive and provides these interfaces:

  • Slice - Arti-pie slice, should be implemented by adapter interface or Artipie application, it can receive request data and return reactive response;
  • Response - returned by Slice from adapters, can be sent to Connection;
  • Connection - response asks connection to accept response data, Connection should be implemented by HTTP web server implementation to accept HTTP responses.

Each artipie adapter has to implement Slice interface with single method response. This method should process the request and return reactive response object:

class Maven implements Slice {
  @Override
  public Response response(String line, Iterable<Map.Entry<String, String>> headers,
      Flow.Publisher<Byte> body) {
      this.upload(body);
      return new RsWithStatus(200);
  }
}

Response is reactive object with single method send. This method is called by server implementation, server provides connection implementation as send parameter which can accept response data: the server asks response to send itself to connection.

class MavenResponse implements Response {

    @Override
    void send(final Connection con) {
        con.accept(200, headers, empty);
    }
}

HTTP server implements Connection interface which can accept response data: server asks response to send itself to connection, response asks connection to accept the data. Artipie adapters are not supposed to implement this interface, it should be done by HTTP server implementation, e.g. vertex-server module.

Some useful examples for different objects

Routing

You can do routing in the following style:

class Repo extends Slice.Wrap {
  Repo(Storage storage) {
    super(
      new SliceRoute(
        new SliceRoute.Path(new RtRule.ByMethod(RqMethod.PUT), new SliceUpload(storage)),
        new SliceRoute.Path(new RtRule.ByMethod(RqMethod.GET), new SliceDownload(storage)),
        new SliceRoute.Path(RtRule.FALLBACK, new SliceSimple(new RsWithStatus(RsStatus.METHOD_NOT_ALLOWED)))
      )
    );
}

Authentication

Authentication protocol is specified by AuthScheme interface which parses user identity from request head (line and headers).

Possible implementations are:

  • Basic - from HTTP Basic authentication
  • Bearer - from Bearer token
  • Token - from token

Authorization

Authorization is specified by Permissions interface which checks user permissions for Action. It can be encapsulated by AuthSlice wrapper to perform authorization checks:

final Slice slice = new AuthSlice(
  new SliceUpload(storage),
  new BasicAuthScheme(authentication),
  new Permission.ByName(permissions, Action.Standard.READ)
);

This slice reads user authentication by authentication decoder (AuthScheme implementation), if the identity was not found, then 401 error will be returned. Then the identity will be passed to authorization check (Permissions class) with specified permission (Action.Standard.READ in the example). If user is not authorized to perform this action 403 error will be returned. If all checks passed successfully, then request will be redirected to underlying Slice implementation (SliceUpload in the example).

Main components of request

final RequestLineFrom request = new RequestLineFrom(line);
final Uri uri = request.uri();
final RqMethod method = request.method();
final String httpVersion = request.version();

Specific header

new RqHeaders.Single(headers, "x-header-name");

Returning of async responses

return new AsyncResponse(
    CompletableFuture.supplyAsync(
        /**
         * Business logic here
        **/
    ).thenApply(
        rsp -> new RsWithBody(
            new RsWithStatus(RsStatus.OK), body
        )
    )
)

How to contribute

Please read contributing rules.

Fork repository, make changes, send us a pull request. We will review your changes and apply them to the master branch shortly, provided they don't violate our quality standards. To avoid frustration, before sending us your pull request please run full Maven build:

$ mvn clean install -Pqulice

To avoid build errors use Maven 3.3+.