mirror of
https://github.com/oven-sh/bun
synced 2026-02-15 21:32:05 +00:00
262 lines
7.7 KiB
C++
262 lines
7.7 KiB
C++
#include "InspectorHTTPServerAgent.h"
|
|
|
|
#include <JavaScriptCore/InspectorFrontendRouter.h>
|
|
#include <JavaScriptCore/InspectorBackendDispatcher.h>
|
|
#include <JavaScriptCore/JSGlobalObject.h>
|
|
#include <wtf/text/WTFString.h>
|
|
#include <JavaScriptCore/JSGlobalObjectDebuggable.h>
|
|
#include <JavaScriptCore/JSGlobalObjectInspectorController.h>
|
|
#include <wtf/TZoneMallocInlines.h>
|
|
#include "ZigGlobalObject.h"
|
|
|
|
namespace Inspector {
|
|
|
|
WTF_MAKE_TZONE_ALLOCATED_IMPL(InspectorHTTPServerAgent);
|
|
|
|
// Zig bindings implementation
|
|
extern "C" {
|
|
void Bun__HTTPServerAgent__setEnabled(Inspector::InspectorHTTPServerAgent* agent);
|
|
|
|
// void Bun__HTTPServerAgentStartListening(Inspector::InspectorHTTPServerAgent* agent, int serverId);
|
|
// void Bun__HTTPServerAgentStopListening(Inspector::InspectorHTTPServerAgent* agent, int serverId);
|
|
// void Bun__HTTPServerAgentGetRequestBody(Inspector::InspectorHTTPServerAgent* agent, int requestId, int serverId);
|
|
// void Bun__HTTPServerAgentGetResponseBody(Inspector::InspectorHTTPServerAgent* agent, int requestId, int serverId);
|
|
}
|
|
|
|
InspectorHTTPServerAgent::InspectorHTTPServerAgent(JSC::JSGlobalObject& globalObject)
|
|
: InspectorAgentBase("HTTPServer"_s)
|
|
, m_backendDispatcher(HTTPServerBackendDispatcher::create(globalObject.inspectorController().backendDispatcher(), this))
|
|
, m_frontendDispatcher(makeUnique<HTTPServerFrontendDispatcher>(const_cast<FrontendRouter&>(globalObject.inspectorController().frontendRouter())))
|
|
, m_enabled(false)
|
|
{
|
|
}
|
|
|
|
InspectorHTTPServerAgent::~InspectorHTTPServerAgent()
|
|
{
|
|
if (m_enabled) {
|
|
Bun__HTTPServerAgent__setEnabled(nullptr);
|
|
}
|
|
}
|
|
|
|
void InspectorHTTPServerAgent::didCreateFrontendAndBackend(FrontendRouter*, BackendDispatcher*)
|
|
{
|
|
}
|
|
|
|
void InspectorHTTPServerAgent::willDestroyFrontendAndBackend(DisconnectReason)
|
|
{
|
|
m_frontendDispatcher = nullptr;
|
|
m_enabled = false;
|
|
}
|
|
|
|
Protocol::ErrorStringOr<void> InspectorHTTPServerAgent::enable()
|
|
{
|
|
if (m_enabled)
|
|
return {};
|
|
|
|
m_enabled = true;
|
|
Bun__HTTPServerAgent__setEnabled(this);
|
|
return {};
|
|
}
|
|
|
|
Protocol::ErrorStringOr<void> InspectorHTTPServerAgent::disable()
|
|
{
|
|
if (!m_enabled)
|
|
return {};
|
|
|
|
m_enabled = false;
|
|
Bun__HTTPServerAgent__setEnabled(nullptr);
|
|
return {};
|
|
}
|
|
|
|
Protocol::ErrorStringOr<void> InspectorHTTPServerAgent::startListening(int serverId)
|
|
{
|
|
if (!m_enabled)
|
|
return {};
|
|
|
|
return {};
|
|
}
|
|
|
|
Protocol::ErrorStringOr<void> InspectorHTTPServerAgent::stopListening(int serverId)
|
|
{
|
|
if (!m_enabled)
|
|
return {};
|
|
|
|
// TODO:
|
|
// Bun__HTTPServerAgentStopListening(this, serverId);
|
|
return {};
|
|
}
|
|
|
|
Protocol::ErrorStringOr<void> InspectorHTTPServerAgent::getRequestBody(int requestId, int serverId)
|
|
{
|
|
if (!m_enabled)
|
|
return {};
|
|
|
|
// TODO:
|
|
// Bun__HTTPServerAgentGetRequestBody(this, requestId, serverId);
|
|
return {};
|
|
}
|
|
|
|
Protocol::ErrorStringOr<void> InspectorHTTPServerAgent::getResponseBody(int requestId, int serverId)
|
|
{
|
|
if (!m_enabled)
|
|
return {};
|
|
// TODO:
|
|
// Bun__HTTPServerAgentGetResponseBody(this, requestId, serverId);
|
|
return {};
|
|
}
|
|
|
|
// Event dispatchers
|
|
|
|
void InspectorHTTPServerAgent::serverStarted(int serverId, const String& url, double startTime, AnyServerPtr serverInstance)
|
|
{
|
|
this->m_serverIdToServerInstance.set(serverId, serverInstance);
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->listen(serverId, url, startTime);
|
|
}
|
|
void InspectorHTTPServerAgent::serverStopped(int serverId, double timestamp)
|
|
{
|
|
this->m_serverIdToServerInstance.remove(serverId);
|
|
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->close(serverId, timestamp);
|
|
}
|
|
void InspectorHTTPServerAgent::serverRoutesUpdated(int serverId, int hotReloadId, Ref<JSON::ArrayOf<Protocol::HTTPServer::Route>>&& routes)
|
|
{
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->serverRoutesUpdated(serverId, hotReloadId, WTFMove(routes));
|
|
}
|
|
void InspectorHTTPServerAgent::requestWillBeSent(Ref<Protocol::HTTPServer::Request>&& request)
|
|
{
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->requestWillBeSent(WTFMove(request));
|
|
}
|
|
void InspectorHTTPServerAgent::responseReceived(Ref<Protocol::HTTPServer::Response>&& response)
|
|
{
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->responseReceived(WTFMove(response));
|
|
}
|
|
void InspectorHTTPServerAgent::bodyChunkReceived(Ref<Protocol::HTTPServer::BodyChunk>&& chunk)
|
|
{
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->bodyChunkReceived(WTFMove(chunk));
|
|
}
|
|
void InspectorHTTPServerAgent::requestFinished(int requestId, int serverId, double timestamp, std::optional<double>&& opt_duration)
|
|
{
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->requestFinished(requestId, serverId, timestamp, WTFMove(opt_duration));
|
|
}
|
|
void InspectorHTTPServerAgent::requestHandlerException(Ref<Protocol::HTTPServer::RequestHandlerError>&& error)
|
|
{
|
|
if (!m_enabled || !m_frontendDispatcher) {
|
|
return;
|
|
}
|
|
|
|
this->m_frontendDispatcher->requestHandlerException(WTFMove(error));
|
|
}
|
|
|
|
}
|
|
|
|
// Zig API implementation
|
|
extern "C" {
|
|
|
|
// Functions for Zig to call to notify about HTTP server events
|
|
|
|
void Bun__HTTPServerAgent__notifyServerStarted(Inspector::InspectorHTTPServerAgent* agent, int serverId, int hotReloadId, BunString* address, double startTime, void* serverInstance)
|
|
{
|
|
|
|
agent->serverStarted(serverId, address->toWTFString(), startTime, serverInstance);
|
|
}
|
|
|
|
void Bun__HTTPServerAgent__notifyServerStopped(Inspector::InspectorHTTPServerAgent* agent, int serverId, double timestamp)
|
|
{
|
|
|
|
agent->serverStopped(serverId, timestamp);
|
|
}
|
|
|
|
// This matches the Route extern struct in Zig
|
|
struct Route {
|
|
enum class Type : uint8_t {
|
|
Default = 1,
|
|
Api = 2,
|
|
Html = 3,
|
|
Static = 4
|
|
};
|
|
|
|
int route_id;
|
|
BunString path;
|
|
Type type;
|
|
int script_line;
|
|
BunString* param_names;
|
|
size_t param_names_len;
|
|
BunString file_path;
|
|
BunString script_id;
|
|
BunString script_url;
|
|
};
|
|
|
|
void Bun__HTTPServerAgent__notifyServerRoutesUpdated(Inspector::InspectorHTTPServerAgent* agent, int serverId, int hotReloadId,
|
|
Route* routes_ptr, size_t routes_len)
|
|
{
|
|
|
|
auto routes = JSON::ArrayOf<Inspector::Protocol::HTTPServer::Route>::create();
|
|
for (size_t i = 0; i < routes_len; i++) {
|
|
auto& route = routes_ptr[i];
|
|
|
|
auto route_type = Inspector::Protocol::HTTPServer::RouteType::Default;
|
|
switch (route.type) {
|
|
case Route::Type::Api:
|
|
route_type = Inspector::Protocol::HTTPServer::RouteType::API;
|
|
break;
|
|
case Route::Type::Html:
|
|
route_type = Inspector::Protocol::HTTPServer::RouteType::HTML;
|
|
break;
|
|
case Route::Type::Static:
|
|
route_type = Inspector::Protocol::HTTPServer::RouteType::Static;
|
|
break;
|
|
default:
|
|
route_type = Inspector::Protocol::HTTPServer::RouteType::Default;
|
|
break;
|
|
}
|
|
|
|
auto object = Inspector::Protocol::HTTPServer::Route::create()
|
|
.setRouteId(route.route_id)
|
|
.setPath(route.path.toWTFString())
|
|
.setType(route_type)
|
|
.setScriptLine(route.script_line)
|
|
.release();
|
|
|
|
if (!route.file_path.isEmpty()) {
|
|
object->setFilePath(route.file_path.toWTFString());
|
|
}
|
|
|
|
if (!route.script_url.isEmpty()) {
|
|
object->setScriptUrl(route.script_url.toWTFString());
|
|
}
|
|
|
|
routes->addItem(WTFMove(object));
|
|
}
|
|
|
|
agent->serverRoutesUpdated(serverId, hotReloadId, WTFMove(routes));
|
|
}
|
|
}
|