Skip to content

v1.1.1

Latest

Choose a tag to compare

@thewizardplusplus thewizardplusplus released this 17 May 21:08

Unification of client and middleware logic through a shared HTTP response status constant.

Change Log

The format is based on Keep a Changelog.

Changed

  • Moved the ExpectedResponseStatusToHEADRequest constant to a shared location (the dosProtectorAdapterModels package) and renamed it to ResponseStatusToHEADRequest to clarify its purpose.
  • Updated the DoSProtectorMiddleware.ApplyTo() method to use the shared constant, ensuring consistency with client-side logic in HTTPClientWrapper.
  • Replaced hardcoded HTTP status codes in tests of both DoSProtectorMiddleware and HTTPClientWrapper with the shared constant to improve maintainability.

Features

  • use of patterns:
    • implementation based on Clean Architecture principles:
      • separate use case layers for server and client;
      • adapter layer for integrating with HTTP servers and clients;
    • input parsing and validation handled internally in the use cases (inputs are passed as raw DTOs);
    • relies on the library github.com/thewizardplusplus/go-pow for PoW algorithm implementation;
  • use cases:
    • server-side:
      • SignChallenge(): generate a message authentication code (MAC) signature for a challenge:
        • MAC signature generation uses a secret key and configurable hashing algorithm;
      • GenerateChallenge(): generate a challenge with specified parameters:
        • number of leading zero bits (hash difficulty);
        • current timestamp rounded to a configurable precision;
        • time to live (TTL);
        • target resource URI;
        • payload consisting of static and random parts;
        • hashing algorithm;
      • GenerateSignedChallenge(): generate a challenge and sign it;
      • VerifySolution(): verify the correctness of a PoW solution;
      • VerifySolutionAndChallengeSignature(): verify both PoW solution and challenge MAC signature;
    • client-side:
      • SolveChallenge(): solve a challenge using the PoW algorithm;
    • providers:
      • extensible provider interfaces for:
        • hash difficulty;
        • target resource URI;
        • static payload part;
      • built-in provider implementations:
        • constant value providers;
        • dynamic providers:
          • hash difficulty based on current server load (active request count);
          • target resource URI and static payload extracted from a context;
  • adapter layer:
    • middlewares:
      • LoadLevelMiddleware: tracks the current server load by counting in-flight requests:
        • intended to be used in conjunction with the dynamic hash difficulty provider (see above);
        • interacts with the latter via an interface;
      • ResourceMiddleware: sets the request URL as the protected resource in the request context:
        • optionally enriches the URL with a host:
          • host can be taken from the request itself;
          • host can be taken from proxy-provided headers;
      • DoSProtectorMiddleware: implements the core logic of DoS attack protection using the PoW algorithm:
        • if a request lacks the solution header X-Dos-Protector-Solution, it generates a new challenge, signs it, and returns it via the response headers X-Dos-Protector-Challenge and X-Dos-Protector-Signature;
        • if a request includes the solution header X-Dos-Protector-Solution, it parses and validates the solution:
          • if validation fails, the 403 Forbidden error response is returned;
          • if validation succeeds, the request proceeds to the protected handler;
        • all operations are delegated to the corresponding use case via an interface;
    • models:
      • introduced adapter-layer models:
        • Challenge: corresponds to the domain-level challenge entity;
        • Solution: corresponds to the domain-level solution entity;
      • functions:
        • NewChallengeFromEntity() and NewSolutionFromEntity(): convert domain entities into adapter-layer models;
        • ParseChallengeFromQuery() and ParseSolutionFromQuery(): parse adapter-layer models from URL-encoded query strings;
      • methods:
        • Challenge.ToQuery() and Solution.ToQuery(): serialize adapter-layer models into URL-encoded query strings;
    • errors:
      • TransformErrorToStatusCode() maps internal errors to appropriate HTTP status codes:
        • internal error dosProtectorUsecaseErrors.ErrInvalidParameters corresponds to the HTTP status code 400 Bad Request;
        • internal error powErrors.ErrValidationFailure corresponds to the HTTP status code 403 Forbidden;
        • other errors correspond to the HTTP status code 500 Internal Server Error;
    • clients:
      • HTTPClientWrapper: a wrapper around the standard HTTP client (via an interface) that automates interaction with DoSProtectorMiddleware (see above):
        • sends an initial HEAD request to the target URL to retrieve the challenge and signature from the X-Dos-Protector-Challenge and X-Dos-Protector-Signature headers, respectively;
        • parses and solves the challenge by invoking the corresponding use case via an interface;
        • clones the original request and enriches it with the computed solution and signature in the headers X-Dos-Protector-Solution and X-Dos-Protector-Signature;
        • sends the enriched request to the server as usual.