Next gate
Gates are operated by District IT. Current role can review the package but not advance it.
src/Transport.php
sha256 92af5a5c352c5e8c7fde…1<?php 2declare(strict_types=1); 3 4namespace Msad17\Connectors\MilestoneApigw\B2610051208502; 5 6interface Transport 7{ 8 /** @return array{status:int, body?:mixed, events?:list<mixed>} */ 9 public function request(string $method, string $path, ?array $body = null): array; 10} 11 12/** 13 * Production transport. TLS verification is ON and cannot be disabled by config; 14 * supply a CA bundle path for self-signed device certificates instead. 15 * Secrets are resolved from the platform secret store at runtime — never from this package. 16 */ 17final class HttpTransport implements Transport 18{ 19 /** @param array<string,string> $headers already-resolved auth headers */ 20 public function __construct( 21 private readonly string $baseUrl, 22 private readonly array $headers = [], 23 private readonly int $timeoutSeconds = 8, 24 private readonly ?string $caFile = null, 25 ) { 26 } 27 28 public function request(string $method, string $path, ?array $body = null): array 29 { 30 $allowed = array_map(fn(array $e) => $e[0] . ' ' . $e[1], Connector::ENDPOINTS); 31 if (!in_array($method . ' ' . $path, $allowed, true)) { 32 throw new \RuntimeException("Endpoint not declared in manifest: {$method} {$path}"); 33 } 34 $ch = curl_init(rtrim($this->baseUrl, '/') . $path); 35 $hdr = []; 36 foreach ($this->headers as $k => $v) { 37 $hdr[] = $k . ': ' . $v; 38 } 39 $opts = [ 40 CURLOPT_CUSTOMREQUEST => $method, 41 CURLOPT_RETURNTRANSFER => true, 42 CURLOPT_TIMEOUT => $this->timeoutSeconds, 43 CURLOPT_SSL_VERIFYPEER => true, 44 CURLOPT_SSL_VERIFYHOST => 2, 45 CURLOPT_HTTPHEADER => $hdr, 46 ]; 47 if ($this->caFile) { 48 $opts[CURLOPT_CAINFO] = $this->caFile; 49 } 50 if ($body !== null) { 51 $opts[CURLOPT_POSTFIELDS] = json_encode($body); 52 } 53 curl_setopt_array($ch, $opts); 54 $raw = curl_exec($ch); 55 $status = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE); 56 curl_close($ch); 57 $decoded = is_string($raw) ? json_decode($raw, true) : null; 58 return ['status' => $status, 'body' => $decoded ?? $raw, 'events' => is_array($decoded) ? ($decoded['events'] ?? []) : []]; 59 } 60} 61 62/** Sandbox transport: no network. Serves fixtures and records every call for policy checks. */ 63final class FixtureTransport implements Transport 64{ 65 /** @var list<string> */ 66 public array $calls = []; 67 68 /** @param list<array<string,mixed>> $events */ 69 public function __construct(private readonly array $events) 70 { 71 } 72 73 public function request(string $method, string $path, ?array $body = null): array 74 { 75 $this->calls[] = $method . ' ' . $path; 76 return ['status' => 200, 'body' => ['fixture' => true], 'events' => $this->events]; 77 } 78}