suno_core/http.rs
1//! The HTTP port: the engine's only window to the network.
2//!
3//! The engine builds [`HttpRequest`]s and reads [`HttpResponse`]s but never
4//! performs IO itself. A CLI adapter implements [`Http`] with a real client,
5//! which keeps the engine testable with a simple in-memory double.
6
7use std::future::Future;
8
9/// The HTTP method for a request. Clerk and Suno only need these two.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Method {
12 Get,
13 Post,
14}
15
16/// A request the engine wants an adapter to perform.
17#[derive(Debug, Clone)]
18pub struct HttpRequest {
19 pub method: Method,
20 pub url: String,
21 pub headers: Vec<(String, String)>,
22}
23
24impl HttpRequest {
25 /// A bare GET for a public (unauthenticated) URL: no headers, no token.
26 pub fn get(url: impl Into<String>) -> Self {
27 Self {
28 method: Method::Get,
29 url: url.into(),
30 headers: Vec::new(),
31 }
32 }
33}
34
35/// The response an adapter returns to the engine.
36#[derive(Debug, Clone)]
37pub struct HttpResponse {
38 pub status: u16,
39 pub headers: Vec<(String, String)>,
40 pub body: Vec<u8>,
41}
42
43impl HttpResponse {
44 /// Read a header value by case-insensitive name, if present.
45 ///
46 /// The download executor uses this for `Content-Length` (provider-reported
47 /// size) and `Retry-After` (rate-limit backoff), so the lookup must ignore
48 /// header-name casing the way HTTP does.
49 pub fn header(&self, name: &str) -> Option<&str> {
50 self.headers
51 .iter()
52 .find(|(key, _)| key.eq_ignore_ascii_case(name))
53 .map(|(_, value)| value.as_str())
54 }
55}
56
57/// A failure to complete a request at the transport level.
58#[derive(Debug, thiserror::Error)]
59#[error("{0}")]
60pub struct TransportError(pub String);
61
62/// The HTTP port an adapter implements for the engine.
63pub trait Http {
64 /// Perform `request` and return the response, or a [`TransportError`].
65 fn send(
66 &self,
67 request: HttpRequest,
68 ) -> impl Future<Output = Result<HttpResponse, TransportError>> + Send;
69}