stash this

This commit is contained in:
Jarred Sumner
2024-10-09 02:33:53 -07:00
parent 8212e3afc6
commit 00e017c274
10 changed files with 169 additions and 5 deletions

View File

@@ -127,8 +127,9 @@ private:
/* Signal broken HTTP request only if we have a pending request */
if (httpResponseData->onAborted) {
httpResponseData->onAborted((HttpResponse<SSL> *)s, httpResponseData->userData);
} else if (httpResponseData->socketData && httpContextData->onSocketClosed) {
httpContextData->onSocketClosed(httpResponseData->socketData, SSL, s);
}
/* Destruct socket ext */
httpResponseData->~HttpResponseData<SSL>();

View File

@@ -27,6 +27,7 @@ namespace uWS {
template<bool> struct HttpResponse;
struct HttpRequest;
template <bool SSL>
struct alignas(16) HttpContextData {
template <bool> friend struct HttpContext;
@@ -34,6 +35,7 @@ struct alignas(16) HttpContextData {
template <bool> friend struct TemplatedApp;
private:
std::vector<MoveOnlyFunction<void(HttpResponse<SSL> *, int)>> filterHandlers;
using OnSocketClosedCallback = void (*)(void* userData, int is_ssl, struct us_socket_t *rawSocket);
MoveOnlyFunction<void(const char *hostname)> missingServerNameHandler;
@@ -51,6 +53,9 @@ private:
bool isParsingHttp = false;
bool rejectUnauthorized = false;
/* Used to simulate Node.js socket events. */
OnSocketClosedCallback onSocketClosed = nullptr;
// TODO: SNI
void clearRoutes() {
this->router = HttpRouter<RouterData>{};

View File

@@ -647,6 +647,17 @@ public:
data->received_bytes_per_timeout = 0;
}
void* getSocketData() {
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
return httpResponseData->socketData;
}
void setSocketData(void* socketData) {
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
httpResponseData->socketData = socketData;
}
void setWriteOffset(uint64_t offset) {
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();

View File

@@ -85,6 +85,7 @@ struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
/* Shared context pointer */
void* userData = nullptr;
void* socketData = nullptr;
/* Per socket event handlers */
OnWritableCallback onWritable = nullptr;
@@ -109,3 +110,5 @@ struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
}
#endif // UWS_HTTPRESPONSEDATA_H
static_assert(sizeof(uWS::HttpResponseData<true>) == 128, "HttpResponseData size is incorrect");

View File

@@ -21,6 +21,141 @@ namespace Bun {
using namespace JSC;
using namespace WebCore;
// Create a static hash table of values containing an onclose DOMAttributeGetterSetter and a close function
static const struct HashTableValue JSNodeHTTPServerSocketPrototypeTableValues[] = {
{ "onclose"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterOnClose, setterOnClose } },
{ "close"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, functionNodeHTTPServerSocket_close, 0 } },
};
class JSNodeHTTPServerSocketPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSNodeHTTPServerSocketPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
{
JSNodeHTTPServerSocketPrototype* prototype = new (NotNull, allocateCell<JSNodeHTTPServerSocketPrototype>(vm)) JSNodeHTTPServerSocketPrototype(vm, structure);
prototype->finishCreation(vm, globalObject);
return prototype;
}
DECLARE_INFO;
static constexpr bool needsDestruction = false;
static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSNodeHTTPServerSocketPrototype, Base);
return &vm.plainObjectSpace();
}
private:
JSNodeHTTPServerSocketPrototype(VM& vm, Structure* structure)
: Base(vm, structure)
{
}
void finishCreation(VM& vm, JSGlobalObject* globalObject)
{
Base::finishCreation(vm);
ASSERT(inherits(info()));
}
};
class JSNodeHTTPServerSocket : public JSC::JSDestructibleObject {
using Base = JSC::JSDestructibleObject;
public:
static JSNodeHTTPServerSocket* create(JSC::VM& vm, JSC::Structure* structure, us_socket_t* socket, bool is_ssl)
{
return new (JSC::allocateCell<JSNodeHTTPServerSocket>(vm)) JSNodeHTTPServerSocket(vm, structure, socket, is_ssl);
}
static JSNodeHTTPServerSocket* create(JSC::VM& vm, Zig::GlobalObject* globalObject, us_socket_t* socket, bool is_ssl)
{
auto* structure = globalObject->m_JSNodeHTTPServerSocketStructure.getInitializedOnMainThread(globalObject);
return create(vm, structure, socket, is_ssl);
}
static void destroy(JSC::JSCell* cell)
{
static_cast<JSNodeHTTPServerSocket*>(cell)->JSNodeHTTPServerSocket::~JSNodeHTTPServerSocket();
}
template<bool SSL>
static void clearSocketData(us_socket_t* socket)
{
auto* httpResponseData = (uWS::HttpResponseData<SSL>*)us_socket_ext(SSL, socket);
if (httpResponseData->socketData) {
httpResponseData->socketData = nullptr;
}
}
~JSNodeHTTPServerSocket()
{
if (socket) {
if (is_ssl) {
clearSocketData<true>(socket);
} else {
clearSocketData<false>(socket);
}
}
}
JSNodeHTTPServerSocket(JSC::VM& vm, JSC::Structure* structure, us_socket_t* socket, bool is_ssl)
: JSC::JSDestructibleObject(vm, structure)
, socket(socket)
, is_ssl(is_ssl)
{
}
mutable WriteBarrier<JSObject> functionToCallOnClose;
mutable WriteBarrier<WebCore::JSNodeHTTPResponse> currentResponseObject;
unsigned is_ssl : 1;
us_socket_t* socket;
DECLARE_INFO;
DECLARE_VISIT_CHILDREN;
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return WebCore::subspaceForImpl<JSNodeHTTPServerSocket, UseCustomHeapCellType::No>(
vm,
[](auto& spaces) { return spaces.m_clientSubspaceForJSNodeHTTPServerSocket.get(); },
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSNodeHTTPServerSocket = std::forward<decltype(space)>(space); },
[](auto& spaces) { return spaces.m_subspaceForJSNodeHTTPServerSocket.get(); },
[](auto& spaces, auto&& space) { spaces.m_subspaceForJSNodeHTTPServerSocket = std::forward<decltype(space)>(space); });
}
void onClose()
{
this->socket = nullptr;
}
static JSC_HOST_CALL_ATTRIBUTES JSC::EncodedJSValue onClose(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
{
auto* thisObject = jsDynamicCast<JSNodeHTTPServerSocket*>(callFrame->thisValue());
if (!thisObject) {
return JSValue::encode(JSC::jsUndefined());
}
thisObject->onClose();
return JSValue::encode(JSC::jsUndefined());
}
static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
JSC::JSObject* prototype = JSC::constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure());
prototype->structure()->setMayBePrototype(true);
return JSC::Structure::create(vm, globalObject, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
};
BUN_DECLARE_HOST_FUNCTION(jsFunctionRequestOrResponseHasBodyValue);
BUN_DECLARE_HOST_FUNCTION(jsFunctionGetCompleteRequestOrResponseBodyValueAsArrayBuffer);
extern "C" uWS::HttpRequest* Request__getUWSRequest(void*);

View File

@@ -1,11 +1,12 @@
#include "config.h"
namespace Bun {
JSC_DECLARE_HOST_FUNCTION(jsHTTPAssignHeaders);
JSC_DECLARE_HOST_FUNCTION(jsHTTPGetHeader);
JSC_DECLARE_HOST_FUNCTION(jsHTTPSetHeader);
JSC::Structure* createNodeHTTPServerSocketStructure(JSC::VM& vm);
JSC::JSValue createNodeHTTPInternalBinding(Zig::GlobalObject*);
}
}

View File

@@ -2687,7 +2687,10 @@ void GlobalObject::finishCreation(VM& vm)
m_commonStrings.initialize();
Bun::addNodeModuleConstructorProperties(vm, this);
m_JSNodeHTTPServerSocketStructure.initLater(
[](const Initializer<Structure>& init) {
init.set(Bun::createNodeHTTPServerSocketStructure(init.vm));
});
m_JSDOMFileConstructor.initLater(
[](const Initializer<JSObject>& init) {
JSObject* fileConstructor = Bun::createJSDOMFileConstructor(init.vm, init.owner);
@@ -3632,6 +3635,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_JSBufferClassStructure.visit(visitor);
thisObject->m_JSBufferListClassStructure.visit(visitor);
thisObject->m_JSBufferSubclassStructure.visit(visitor);
thisObject->m_JSNodeHTTPServerSocketStructure.visit(visitor);
thisObject->m_JSCryptoKey.visit(visitor);
thisObject->m_JSDOMFileConstructor.visit(visitor);
thisObject->m_JSFFIFunctionStructure.visit(visitor);

View File

@@ -587,6 +587,8 @@ public:
LazyProperty<JSGlobalObject, JSObject> m_performanceObject;
LazyProperty<JSGlobalObject, JSObject> m_processObject;
LazyProperty<JSGlobalObject, Structure> m_JSNodeHTTPServerSocketStructure;
bool hasOverridenModuleResolveFilenameFunction = false;
private:

View File

@@ -56,6 +56,7 @@ public:
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForHandleScopeBuffer;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFunctionTemplate;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForV8Function;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSNodeHTTPServerSocket;
#include "ZigGeneratedClasses+DOMClientIsoSubspaces.h"
/* --- bun --- */

View File

@@ -56,6 +56,7 @@ public:
std::unique_ptr<IsoSubspace> m_subspaceForHandleScopeBuffer;
std::unique_ptr<IsoSubspace> m_subspaceForFunctionTemplate;
std::unique_ptr<IsoSubspace> m_subspaceForV8Function;
std::unique_ptr<IsoSubspace> m_subspaceForJSNodeHTTPServerSocket;
#include "ZigGeneratedClasses+DOMIsoSubspaces.h"
/*-- BUN --*/
@@ -898,7 +899,7 @@ public:
// std::unique_ptr<IsoSubspace> m_subspaceForXPathNSResolver;
// std::unique_ptr<IsoSubspace> m_subspaceForXPathResult;
// std::unique_ptr<IsoSubspace> m_subspaceForXSLTProcessor;
std::unique_ptr<IsoSubspace> m_subspaceForBakeGlobalScope;
std::unique_ptr<IsoSubspace> m_subspaceForAbortController;