Crafter.Review/interfaces/Crafter.Review-Http.cppm

49 lines
2 KiB
Text
Raw Normal View History

// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
export module Crafter.Review:Http;
import std;
import :Json;
// The HTTP the driver needs: app_ready's preflight, the OpenRouter catalogue
// and key probe. On Crafter.Network's ClientHTTP1::Fetch, which follows redirects; on
// top of it a status outside 2xx thrown as HttpError, and every other failure
// as Error with a fixed text, because those texts reach the run log and
// app_ready's detail. Proxies are not consulted (AGENTS.md).
export namespace Crafter::Review::Http {
struct Response {
std::int32_t status = 0;
std::string body;
};
// A status outside 2xx. what(): "HTTP Error 404: Not Found", with the
// standard reason phrase rather than the server's.
class HttpError : public std::runtime_error {
public:
HttpError(std::int32_t code, const std::string& message);
explicit HttpError(std::int32_t code);
std::int32_t Code() const;
private:
std::int32_t code;
};
// Every other failure. What fails while the request goes out reads
// "<urlopen error [Errno 111] Connection refused>" or "<urlopen error
// timed out>"; what fails while the response comes in reads as it is:
// "timed out".
class Error : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
};
// A GET of `url`, read whole. Header names in any case; Accept-Encoding:
// identity and Connection: close always go out, and a User-Agent unless
// one is given.
Response UrlOpen(std::string_view url, const std::map<std::string, std::string>& headers, double timeout);
// The body as JSON: Dyn::Error JSONDecodeError (or UnicodeDecodeError)
// with the scanner's message for a body that is not.
Json JsonBody(const Response& response);
// http.HTTPStatus(code).phrase, "" for a code it does not know.
std::string_view Reason(std::int32_t code);
}