Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Hpack Laravel Package

amphp/hpack

Fast HPACK (HTTP/2 header compression) implementation for PHP by amphp. Provides efficient encoding/decoding of header blocks with dynamic tables, Huffman coding, and compliance-focused behavior, suitable for high-performance HTTP/2 clients and servers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require amphp/hpack
    
  2. Basic Usage:
    use Amp\Hpack\Encoder;
    use Amp\Hpack\Decoder;
    
    $encoder = new Encoder();
    $decoder = new Decoder();
    
    $headers = [[':method', 'GET'], [':path', '/']];
    $encoded = $encoder->encode($headers); // Binary string
    $decoded = $decoder->decode($encoded); // Original headers array
    

First Use Case

Laravel HTTP/2 Proxy Middleware (if using a custom async server like Amp):

// In a custom HTTP/2 server middleware
public function handleRequest(array $headers) {
    $encoder = new Encoder();
    $compressed = $encoder->encode($headers);
    // Send $compressed via HTTP/2 frame
}

Implementation Patterns

Core Workflows

  1. Request/Response Compression:

    // Compress outgoing headers (e.g., in a custom HTTP server)
    $encoder = new Encoder();
    $compressed = $encoder->encode($requestHeaders);
    
    // Decompress incoming headers
    $decoder = new Decoder();
    $headers = $decoder->decode($compressedHeaders);
    
  2. Dynamic Table Management:

    • Set a custom table size limit (e.g., for memory constraints):
      $decoder = new Decoder(2048); // 2KB limit
      
    • Handle SETTINGS_HEADER_TABLE_SIZE updates from peers (critical for HTTP/2 compliance).
  3. Integration with Async Frameworks:

    • Amp Example:
      use Amp\ByteStream\ReadableStream;
      use Amp\Hpack\Decoder;
      
      $decoder = new Decoder();
      $stream = new ReadableStream(...);
      $headers = $decoder->decodeStream($stream); // Decode headers incrementally
      
  4. Streaming Decoding (for large headers):

    $decoder = new Decoder();
    $decoder->setStreamMode(true);
    $headers = $decoder->decode($chunk1 . $chunk2); // Handles partial data
    

Laravel-Specific Patterns

(Note: Direct Laravel integration is limited; use cases require custom async servers.)

  • Custom HTTP Server: Extend Amp\Http\Server\Request to inject HPack encoding/decoding:
    class HpackMiddleware {
        public function __invoke(ServerRequestInterface $request, callable $next) {
            $encoder = new Encoder();
            $request = $request->withHeader(
                'custom-header',
                $encoder->encode([['x-custom', 'value']])
            );
            return $next($request);
        }
    }
    
  • Guzzle HTTP/2 Client (if using Amp HTTP client):
    $client = new Amp\Http\Client();
    $encoder = new Encoder();
    $response = $client->request('GET', 'https://example.com', [
        'headers' => $encoder->encode([['custom', 'value']])
    ]);
    

Gotchas and Tips

Pitfalls

  1. Stateful Dynamic Table:

    • Issue: Forgetting to update the decoder’s dynamic table when receiving SETTINGS_HEADER_TABLE_SIZE frames causes corruption.
    • Fix: Always forward table size updates to the decoder:
      $decoder->setTableSizeLimit($newSize);
      
  2. Binary Safety:

    • Issue: decode() throws HttpException on malformed input (e.g., truncated Huffman data).
    • Fix: Validate frames before decoding or wrap in a try-catch:
      try {
          $headers = $decoder->decode($binaryData);
      } catch (HttpException $e) {
          // Log and handle (e.g., reset connection)
      }
      
  3. Header Name Case Sensitivity:

    • Issue: HPack is case-insensitive for header names, but Laravel’s HeaderBag is case-preserving.
    • Fix: Normalize headers before encoding:
      $normalized = array_map('strtolower', $headers);
      
  4. Memory Leaks:

    • Issue: Large dynamic tables (default 4KB) can bloat memory in high-concurrency async servers.
    • Fix: Reduce table size or implement a LRU eviction policy:
      $decoder = new Decoder(1024); // 1KB limit
      

Debugging Tips

  1. Enable Debug Logging:
    $decoder = new Decoder();
    $decoder->setDebug(true); // Logs Huffman/HPack internals
    
  2. Compare with Wireshark:
    • Capture HTTP/2 traffic and compare raw HPack binary with decoded headers.
  3. Test Edge Cases:
    • Use the package’s RfcTest to validate compliance with RFC 7541 test vectors.

Extension Points

  1. Custom Header Processing:
    • Subclass Encoder/Decoder to preprocess headers (e.g., redact sensitive data):
      class CustomEncoder extends Encoder {
          protected function encodeHeader(string $name, string $value): string {
              if ($name === 'authorization') {
                  $value = '***';
              }
              return parent::encodeHeader($name, $value);
          }
      }
      
  2. FFI Optimization:
    • Enable the FFI backend for PHP 8.3+ (faster but requires libnghttp2):
      $decoder = new \Amp\Hpack\Decoder\FFI();
      
  3. Table Size Adaptation:
    • Dynamically adjust table size based on connection metrics:
      $decoder->setTableSizeLimit(
          min(4096, $connection->getMemoryUsage() * 0.1)
      );
      

Laravel-Specific Quirks

  • No Built-in HTTP/2 Support: Laravel’s Request/Response classes assume HTTP/1.1. HPack integration requires a custom async server (e.g., Amp).
  • Middleware Conflicts: Avoid mixing HPack with Laravel’s Symfony\Component\HttpFoundation headers—normalize formats first.
  • Testing: Use Amp\Http\Server\Test\DecoderTest as a reference for writing unit tests. Example:
    public function testHpackCompression() {
        $encoder = new Encoder();
        $decoder = new Decoder();
        $headers = [[':method', 'POST'], ['content-type', 'application/json']];
        $encoded = $encoder->encode($headers);
        $this->assertEquals($headers, $decoder->decode($encoded));
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata