HTTP Constants and Types in Hyperlane

3 阅读4分钟

HTTP Constants and Types in Hyperlane

Introduction

Hyperlane provides a comprehensive set of HTTP constants and types that simplify working with HTTP protocols in your Rust applications. Instead of manually specifying MIME types, header names, HTTP versions, and other protocol constants, Hyperlane offers predefined constants that reduce errors and improve code readability. This article covers the key constants and types available in the framework.

Why Use Constants?

When building HTTP servers, you frequently need to specify values like:

  • Content-Type headers (application/json, text/html)
  • HTTP versions (HTTP/1.1, HTTP/2)
  • Header names (SERVER, CONTENT_TYPE, SET_COOKIE)
  • MIME types (TEXT_EVENT_STREAM, APPLICATION_JSON)

Hardcoding these as string literals is error-prone. A typo like "applicaiton/json" can cause subtle bugs that are hard to trace. Hyperlane's constants eliminate this risk entirely.

Content Type Constants

Hyperlane defines commonly used content type constants:

  • APPLICATION_JSONapplication/json for JSON responses
  • TEXT_EVENT_STREAMtext/event-stream for SSE responses

Using these constants in your handlers:

ctx.get_mut_response().set_header(CONTENT_TYPE, APPLICATION_JSON);

For SSE responses:

let data = ctx.get_mut_response()
    .set_header(CONTENT_TYPE, TEXT_EVENT_STREAM)
    .set_body(Vec::new())
    .build();
stream.try_send(data).await;

Header Name Constants

Hyperlane provides constants for common HTTP header names:

  • CONTENT_TYPE — The Content-Type header
  • SERVER — The Server header
  • SET_COOKIE — The Set-Cookie header
  • AUTHORIZATION — The Authorization header
  • ACCESS_CONTROL_ALLOW_ORIGIN — The Access-Control-Allow-Origin header
  • ACCESS_CONTROL_ALLOW_METHODS — The Access-Control-Allow-Methods header
  • ACCESS_CONTROL_ALLOW_HEADERS — The Access-Control-Allow-Headers header

Using these in your code:

ctx.get_mut_response().set_header(CONTENT_TYPE, APPLICATION_JSON);
ctx.get_mut_response().add_header(SERVER, "hyperlane");

CORS Constants

For Cross-Origin Resource Sharing, Hyperlane provides:

  • WILDCARD_ANY* for allowing any origin
  • ALL_METHODS — All HTTP methods for CORS
ctx.get_mut_response()
    .set_header(ACCESS_CONTROL_ALLOW_ORIGIN, WILDCARD_ANY)
    .set_header(ACCESS_CONTROL_ALLOW_METHODS, ALL_METHODS)
    .set_header(ACCESS_CONTROL_ALLOW_HEADERS, WILDCARD_ANY);

HTTP Version Constants

The HttpVersion enum provides type-safe HTTP version specification:

ctx.get_mut_response().set_version(HttpVersion::Http1_1).set_status_code(200);

Using HttpVersion::Http1_1 is both clearer and safer than setting version strings manually.

Route Constants and Types

HTTP Methods

Hyperlane uses the RequestMethod enum for HTTP method matching:

ctx.get_request().get_method() == &RequestMethod::Get

Status Codes

Status codes are set via methods on the response object:

ctx.get_mut_response().set_status_code(200);

WebSocket Types

WebSocketFrame

Hyperlane provides the WebSocketFrame type for working with WebSocket data:

let body_list = WebSocketFrame::create_frame_list(&body);
stream.send_list(body_list).await;

The WebSocketFrame::create_frame_list method serializes message data into a list of frames ready for transmission.

Cookie Types

CookieBuilder

Hyperlane's CookieBuilder provides a fluent API for constructing HTTP cookies:

let cookie = CookieBuilder::new("session_id", "abc123")
    .set_path("/")
    .http_only()
    .build();
ctx.get_mut_response().set_header(SET_COOKIE, &cookie);

The builder supports chaining multiple configuration calls:

let cookie = CookieBuilder::new("session", "token123")
    .set_expires("Wed, 21 Oct 2025 07:28:00 GMT")
    .set_domain("example.com")
    .set_same_site("Strict")
    .set_max_age(3600)
    .set_path("/")
    .secure()
    .http_only()
    .build();

To clear a cookie:

let clear_cookie = CookieBuilder::new("session", "").set_max_age(0).build();

File Extension Types

Hyperlane provides the FileExtension type for working with file types:

let file_extension = FileExtension::get_extension_name(&file_path);
let content_type = FileExtension::parse(&file_extension).get_content_type();

This automatically maps file extensions to their corresponding MIME types, which is essential for static file serving.

SSE Constants

For Server-Sent Events, Hyperlane provides the HTTP_DOUBLE_BR constant for line endings:

for i in 0..10 {
    let body = format!("data:{i}{HTTP_DOUBLE_BR}");
    stream.try_send(&body).await;
}

The HTTP_DOUBLE_BR constant ensures correct SSE formatting with double line breaks after each event.

Request and Response Types

Server

The central server type:

let mut server: Server = Server::default();

ServerConfig

Configuration type for server-level settings:

let mut config: ServerConfig = ServerConfig::default();
config.set_address("0.0.0.0:80");
config.set_nodelay(Some(true));
config.set_ttl(Some(128));

RequestConfig

Configuration type for request-level settings:

let request_config_json = r#"{
    "buffer_size": 8192,
    "max_path_size": 8192,
    "max_header_count": 100,
    "max_header_key_size": 8192,
    "max_header_value_size": 8192,
    "max_body_size": 2097152,
    "read_timeout_ms": 6000
}"#;
let request_config = RequestConfig::from_json(request_config_json).unwrap();

ServerControlHook

Type for controlling server lifecycle:

let server_control_hook = server.run().await.unwrap_or_default();
server_control_hook.wait().await;

Status Enum

The Status enum is used in middleware to control the processing pipeline:

Status::Continue  // Continue to the next middleware
Status::Reject    // Reject the request

Context Type

The Context type carries all request/response data through the pipeline. It is created per-request and provides access to everything from request data to response configuration.

Stream Type

The Stream type manages the underlying TCP connection. It provides methods for sending data, managing connection state, and handling keep-alive:

stream.try_send(data).await;
stream.send(data).await;
stream.try_send_list(&frame_list).await;
stream.try_flush().await;
stream.set_closed(true);

Status Code Constants Pattern

While Hyperlane doesn't provide named constants for all HTTP status codes, it uses numeric codes with semantic setter methods:

ctx.get_mut_response().set_status_code(200);  // OK
ctx.get_mut_response().set_status_code(401);  // Unauthorized
ctx.get_mut_response().set_status_code(500);  // Internal Server Error
ctx.get_mut_response().set_status_code(504);  // Gateway Timeout

Putting It All Together

Here's an example that demonstrates many of these constants and types working together:

#[route("/api/data")]
struct DataHandler;

impl ServerHook for DataHandler {
    async fn new(_: &mut Stream, _: &mut Context) -> Self {
        Self
    }

    async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
        // Set response headers using constants
        ctx.get_mut_response()
            .set_version(HttpVersion::Http1_1)
            .set_status_code(200)
            .set_header(CONTENT_TYPE, APPLICATION_JSON)
            .add_header(SERVER, "hyperlane");

        // Set a cookie using CookieBuilder
        let cookie = CookieBuilder::new("session", "token123")
            .set_path("/")
            .http_only()
            .build();
        ctx.get_mut_response().set_header(SET_COOKIE, &cookie);

        // Build and send the response
        let data = ctx.get_mut_response().set_body(r#"{"status":"ok"}"#).build();
        if stream.try_send(data).await.is_err() {
            stream.set_closed(true);
            return Status::Reject;
        }

        Status::Continue
    }
}

Best Practices

  1. Always use constants for header names and content types — Never hardcode "Content-Type" when CONTENT_TYPE is available.
  2. Use HttpVersion enum instead of strings — It's type-safe and prevents version string errors.
  3. Use CookieBuilder for cookies — It handles proper cookie formatting including domain, path, and security flags.
  4. Use FileExtension for content type detection — It automatically maps file extensions to MIME types.
  5. Use WebSocketFrame for WebSocket data — It handles proper frame serialization.

Conclusion

Hyperlane's HTTP constants and types provide a robust, type-safe foundation for working with HTTP protocols in Rust. By using predefined constants for content types, header names, HTTP versions, and more, you can write cleaner, more maintainable code with fewer string-related bugs. Combined with types like CookieBuilder, FileExtension, WebSocketFrame, and the Status enum, Hyperlane gives you everything you need to build production-quality HTTP applications.