2019-01-17 05:53:30 +00:00
# include "App.h"
2019-01-14 10:45:25 +00:00
# include <v8.h>
# include "Utilities.h"
using namespace v8 ;
2019-01-14 10:34:20 +00:00
2019-01-18 15:57:54 +00:00
/* uWS.App.ws('/pattern', behavior) */
2019-01-14 10:34:20 +00:00
template < typename APP >
void uWS_App_ws ( const FunctionCallbackInfo < Value > & args ) {
2019-12-05 03:07:18 +00:00
Isolate * isolate = args . GetIsolate ( ) ;
PerContextData * perContextData = ( PerContextData * ) Local < External > : : Cast ( args . Data ( ) ) - > Value ( ) ;
2019-01-14 10:34:20 +00:00
APP * app = ( APP * ) args . Holder ( ) - > GetAlignedPointerFromInternalField ( 0 ) ;
2019-10-09 13:04:45 +00:00
/* This one is default constructed with defaults */
2019-01-16 20:36:35 +00:00
typename APP : : WebSocketBehavior behavior = { } ;
2019-01-14 10:34:20 +00:00
2019-01-18 15:33:56 +00:00
NativeString pattern ( args . GetIsolate ( ) , args [ 0 ] ) ;
if ( pattern . isInvalid ( args ) ) {
return ;
}
2019-01-14 10:34:20 +00:00
2019-01-23 11:59:51 +00:00
UniquePersistent < Function > openPf ;
UniquePersistent < Function > messagePf ;
UniquePersistent < Function > drainPf ;
UniquePersistent < Function > closePf ;
2019-01-14 10:34:20 +00:00
struct PerSocketData {
2019-03-12 14:11:39 +00:00
UniquePersistent < Object > * socketPf ;
2019-01-14 10:34:20 +00:00
} ;
/* Get the behavior object */
if ( args . Length ( ) = = 2 ) {
Local < Object > behaviorObject = Local < Object > : : Cast ( args [ 1 ] ) ;
2019-10-09 13:04:45 +00:00
/* maxPayloadLength or default */
2019-11-08 12:49:40 +00:00
MaybeLocal < Value > maybeMaxPayloadLength = behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " maxPayloadLength " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) ;
2019-10-09 13:04:45 +00:00
if ( ! maybeMaxPayloadLength . IsEmpty ( ) & & ! maybeMaxPayloadLength . ToLocalChecked ( ) - > IsUndefined ( ) ) {
behavior . maxPayloadLength = maybeMaxPayloadLength . ToLocalChecked ( ) - > Int32Value ( isolate - > GetCurrentContext ( ) ) . ToChecked ( ) ;
}
/* idleTimeout or default */
2019-11-08 12:49:40 +00:00
MaybeLocal < Value > maybeIdleTimeout = behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " idleTimeout " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) ;
2019-10-09 13:04:45 +00:00
if ( ! maybeIdleTimeout . IsEmpty ( ) & & ! maybeIdleTimeout . ToLocalChecked ( ) - > IsUndefined ( ) ) {
behavior . idleTimeout = maybeIdleTimeout . ToLocalChecked ( ) - > Int32Value ( isolate - > GetCurrentContext ( ) ) . ToChecked ( ) ;
}
/* Compression or default, map from 0, 1, 2 to disabled, shared, dedicated. This is actually the enum */
2019-11-08 12:49:40 +00:00
MaybeLocal < Value > maybeCompression = behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " compression " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) ;
2019-10-09 13:04:45 +00:00
if ( ! maybeCompression . IsEmpty ( ) & & ! maybeCompression . ToLocalChecked ( ) - > IsUndefined ( ) ) {
behavior . compression = ( uWS : : CompressOptions ) maybeCompression . ToLocalChecked ( ) - > Int32Value ( isolate - > GetCurrentContext ( ) ) . ToChecked ( ) ;
}
/* maxBackpressure or default */
2019-11-08 12:49:40 +00:00
MaybeLocal < Value > maybeMaxBackpressure = behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " maxBackpressure " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) ;
2019-10-09 13:04:45 +00:00
if ( ! maybeMaxBackpressure . IsEmpty ( ) & & ! maybeMaxBackpressure . ToLocalChecked ( ) - > IsUndefined ( ) ) {
behavior . maxBackpressure = maybeMaxBackpressure . ToLocalChecked ( ) - > Int32Value ( isolate - > GetCurrentContext ( ) ) . ToChecked ( ) ;
}
2019-01-14 10:34:20 +00:00
/* Open */
2019-11-08 12:49:40 +00:00
openPf . Reset ( args . GetIsolate ( ) , Local < Function > : : Cast ( behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " open " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ) ;
2019-01-14 10:34:20 +00:00
/* Message */
2019-11-08 12:49:40 +00:00
messagePf . Reset ( args . GetIsolate ( ) , Local < Function > : : Cast ( behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " message " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ) ;
2019-01-14 10:34:20 +00:00
/* Drain */
2019-11-08 12:49:40 +00:00
drainPf . Reset ( args . GetIsolate ( ) , Local < Function > : : Cast ( behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " drain " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ) ;
2019-01-14 10:34:20 +00:00
/* Close */
2019-11-08 12:49:40 +00:00
closePf . Reset ( args . GetIsolate ( ) , Local < Function > : : Cast ( behaviorObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " close " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ) ;
2019-01-14 10:34:20 +00:00
}
2019-02-21 18:48:33 +00:00
/* Open handler is NOT optional for the wrapper */
2019-12-05 03:07:18 +00:00
behavior . open = [ openPf = std : : move ( openPf ) , perContextData ] ( auto * ws , auto * req ) {
Isolate * isolate = perContextData - > isolate ;
2019-01-16 20:31:17 +00:00
HandleScope hs ( isolate ) ;
2019-01-14 10:34:20 +00:00
2019-01-16 20:31:17 +00:00
/* Create a new websocket object */
2019-12-05 03:07:18 +00:00
Local < Object > wsObject = perContextData - > wsTemplate [ getAppTypeIndex < APP > ( ) ] . Get ( isolate ) - > Clone ( ) ;
2019-01-16 20:31:17 +00:00
wsObject - > SetAlignedPointerInInternalField ( 0 , ws ) ;
2019-01-17 06:33:31 +00:00
/* Create the HttpRequest wrapper */
2019-12-05 03:07:18 +00:00
Local < Object > reqObject = perContextData - > reqTemplate . Get ( isolate ) - > Clone ( ) ;
2019-01-17 06:33:31 +00:00
reqObject - > SetAlignedPointerInInternalField ( 0 , req ) ;
2019-01-16 20:31:17 +00:00
/* Attach a new V8 object with pointer to us, to us */
PerSocketData * perSocketData = ( PerSocketData * ) ws - > getUserData ( ) ;
2019-03-12 14:11:39 +00:00
perSocketData - > socketPf = new UniquePersistent < Object > ;
2019-01-16 20:31:17 +00:00
perSocketData - > socketPf - > Reset ( isolate , wsObject ) ;
2019-02-21 18:48:33 +00:00
Local < Function > openLf = Local < Function > : : New ( isolate , openPf ) ;
if ( ! openLf - > IsUndefined ( ) ) {
Local < Value > argv [ ] = { wsObject , reqObject } ;
2019-08-18 19:49:06 +00:00
openLf - > Call ( isolate - > GetCurrentContext ( ) , isolate - > GetCurrentContext ( ) - > Global ( ) , 2 , argv ) . IsEmpty ( ) ;
2019-02-21 18:48:33 +00:00
}
2019-01-16 20:31:17 +00:00
} ;
2019-02-21 18:48:33 +00:00
/* Message handler is always optional */
if ( messagePf ! = Undefined ( isolate ) ) {
2019-12-05 03:07:18 +00:00
behavior . message = [ messagePf = std : : move ( messagePf ) , isolate ] ( auto * ws , std : : string_view message , uWS : : OpCode opCode ) {
2019-02-21 18:48:33 +00:00
HandleScope hs ( isolate ) ;
2019-01-16 20:31:17 +00:00
2019-02-21 18:48:33 +00:00
Local < ArrayBuffer > messageArrayBuffer = ArrayBuffer : : New ( isolate , ( void * ) message . data ( ) , message . length ( ) ) ;
2019-01-16 20:31:17 +00:00
2019-02-21 18:48:33 +00:00
PerSocketData * perSocketData = ( PerSocketData * ) ws - > getUserData ( ) ;
Local < Value > argv [ 3 ] = { Local < Object > : : New ( isolate , * ( perSocketData - > socketPf ) ) ,
messageArrayBuffer ,
Boolean : : New ( isolate , opCode = = uWS : : OpCode : : BINARY ) } ;
2019-08-18 19:49:06 +00:00
Local < Function > : : New ( isolate , messagePf ) - > Call ( isolate - > GetCurrentContext ( ) , isolate - > GetCurrentContext ( ) - > Global ( ) , 3 , argv ) . IsEmpty ( ) ;
2019-01-16 20:31:17 +00:00
2019-02-21 18:48:33 +00:00
/* Important: we clear the ArrayBuffer to make sure it is not invalidly used after return */
messageArrayBuffer - > Neuter ( ) ;
} ;
}
2019-01-16 20:31:17 +00:00
2019-02-21 18:48:33 +00:00
/* Drain handler is always optional */
if ( drainPf ! = Undefined ( isolate ) ) {
2019-12-05 03:07:18 +00:00
behavior . drain = [ drainPf = std : : move ( drainPf ) , isolate ] ( auto * ws ) {
2019-02-21 18:48:33 +00:00
HandleScope hs ( isolate ) ;
2019-01-16 20:31:17 +00:00
2019-02-21 18:48:33 +00:00
PerSocketData * perSocketData = ( PerSocketData * ) ws - > getUserData ( ) ;
Local < Value > argv [ 1 ] = { Local < Object > : : New ( isolate , * ( perSocketData - > socketPf ) )
} ;
2019-08-18 19:49:06 +00:00
Local < Function > : : New ( isolate , drainPf ) - > Call ( isolate - > GetCurrentContext ( ) , isolate - > GetCurrentContext ( ) - > Global ( ) , 1 , argv ) . IsEmpty ( ) ;
2019-02-21 18:48:33 +00:00
} ;
}
2019-01-16 20:31:17 +00:00
2019-02-21 18:48:33 +00:00
/* These are not hooked in */
2019-01-16 20:31:17 +00:00
behavior . ping = [ ] ( auto * ws ) {
} ;
behavior . pong = [ ] ( auto * ws ) {
} ;
2019-02-21 18:48:33 +00:00
/* Close handler is NOT optional for the wrapper */
2019-12-05 03:07:18 +00:00
behavior . close = [ closePf = std : : move ( closePf ) , isolate ] ( auto * ws , int code , std : : string_view message ) {
2019-01-16 20:31:17 +00:00
HandleScope hs ( isolate ) ;
Local < ArrayBuffer > messageArrayBuffer = ArrayBuffer : : New ( isolate , ( void * ) message . data ( ) , message . length ( ) ) ;
PerSocketData * perSocketData = ( PerSocketData * ) ws - > getUserData ( ) ;
2019-01-18 15:57:54 +00:00
Local < Object > wsObject = Local < Object > : : New ( isolate , * ( perSocketData - > socketPf ) ) ;
/* Invalidate this wsObject */
wsObject - > SetAlignedPointerInInternalField ( 0 , nullptr ) ;
2019-02-21 18:48:33 +00:00
/* Only call close handler if we have one set */
Local < Function > closeLf = Local < Function > : : New ( isolate , closePf ) ;
if ( ! closeLf - > IsUndefined ( ) ) {
Local < Value > argv [ 3 ] = { wsObject , Integer : : New ( isolate , code ) , messageArrayBuffer } ;
2019-08-18 19:49:06 +00:00
closeLf - > Call ( isolate - > GetCurrentContext ( ) , isolate - > GetCurrentContext ( ) - > Global ( ) , 3 , argv ) . IsEmpty ( ) ;
2019-02-21 18:48:33 +00:00
}
2019-01-16 20:31:17 +00:00
2019-01-18 15:57:54 +00:00
delete perSocketData - > socketPf ;
2019-01-16 20:31:17 +00:00
/* Again, here we clear the buffer to avoid strange bugs */
messageArrayBuffer - > Neuter ( ) ;
} ;
2019-01-18 15:33:56 +00:00
app - > template ws < PerSocketData > ( std : : string ( pattern . getString ( ) ) , std : : move ( behavior ) ) ;
2019-01-14 10:34:20 +00:00
/* Return this */
args . GetReturnValue ( ) . Set ( args . Holder ( ) ) ;
}
2019-01-16 21:59:53 +00:00
/* This method wraps get, post and all http methods */
template < typename APP , typename F >
void uWS_App_get ( F f , const FunctionCallbackInfo < Value > & args ) {
2019-01-14 10:34:20 +00:00
APP * app = ( APP * ) args . Holder ( ) - > GetAlignedPointerFromInternalField ( 0 ) ;
2019-01-18 15:33:56 +00:00
NativeString pattern ( args . GetIsolate ( ) , args [ 0 ] ) ;
if ( pattern . isInvalid ( args ) ) {
return ;
}
2019-01-14 10:34:20 +00:00
2019-12-05 03:07:18 +00:00
/* This function requires perContextData */
PerContextData * perContextData = ( PerContextData * ) Local < External > : : Cast ( args . Data ( ) ) - > Value ( ) ;
UniquePersistent < Function > cb ( args . GetIsolate ( ) , Local < Function > : : Cast ( args [ 1 ] ) ) ;
2019-01-14 10:34:20 +00:00
2019-12-05 03:07:18 +00:00
( app - > * f ) ( std : : string ( pattern . getString ( ) ) , [ cb = std : : move ( cb ) , perContextData ] ( auto * res , auto * req ) {
Isolate * isolate = perContextData - > isolate ;
2019-01-14 10:34:20 +00:00
HandleScope hs ( isolate ) ;
2019-12-05 03:07:18 +00:00
Local < Object > resObject = perContextData - > resTemplate [ getAppTypeIndex < APP > ( ) ] . Get ( isolate ) - > Clone ( ) ;
2019-01-14 10:34:20 +00:00
resObject - > SetAlignedPointerInInternalField ( 0 , res ) ;
2019-12-05 03:07:18 +00:00
Local < Object > reqObject = perContextData - > reqTemplate . Get ( isolate ) - > Clone ( ) ;
2019-01-14 10:34:20 +00:00
reqObject - > SetAlignedPointerInInternalField ( 0 , req ) ;
Local < Value > argv [ ] = { resObject , reqObject } ;
2019-12-05 03:07:18 +00:00
cb . Get ( isolate ) - > Call ( isolate - > GetCurrentContext ( ) , isolate - > GetCurrentContext ( ) - > Global ( ) , 2 , argv ) . IsEmpty ( ) ;
2019-01-18 15:33:56 +00:00
/* Properly invalidate req */
reqObject - > SetAlignedPointerInInternalField ( 0 , nullptr ) ;
/* µWS itself will terminate if not responded and not attached
* onAborted handler , so we can assume it ' s done */
2019-01-14 10:34:20 +00:00
} ) ;
args . GetReturnValue ( ) . Set ( args . Holder ( ) ) ;
}
template < typename APP >
void uWS_App_listen ( const FunctionCallbackInfo < Value > & args ) {
APP * app = ( APP * ) args . Holder ( ) - > GetAlignedPointerFromInternalField ( 0 ) ;
2019-12-05 03:07:18 +00:00
Isolate * isolate = args . GetIsolate ( ) ;
2019-04-17 20:09:11 +00:00
/* Require at least two arguments */
if ( args . Length ( ) < 2 ) {
2019-02-10 10:28:33 +00:00
/* Throw here */
2019-11-08 12:49:40 +00:00
args . GetReturnValue ( ) . Set ( isolate - > ThrowException ( String : : NewFromUtf8 ( isolate , " App.listen requires port and callback " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) ) ;
2019-02-10 10:28:33 +00:00
return ;
}
2019-01-14 10:34:20 +00:00
2019-04-17 20:09:11 +00:00
/* Callback is last */
2019-12-05 03:07:18 +00:00
auto cb = [ & args , isolate ] ( auto * token ) {
2019-01-21 18:08:18 +00:00
/* Return a false boolean if listen failed */
Local < Value > argv [ ] = { token ? Local < Value > : : Cast ( External : : New ( isolate , token ) ) : Local < Value > : : Cast ( Boolean : : New ( isolate , false ) ) } ;
2019-08-18 19:49:06 +00:00
Local < Function > : : Cast ( args [ args . Length ( ) - 1 ] ) - > Call ( isolate - > GetCurrentContext ( ) , isolate - > GetCurrentContext ( ) - > Global ( ) , 1 , argv ) . IsEmpty ( ) ;
2019-02-10 10:28:33 +00:00
} ;
2019-04-17 20:09:11 +00:00
/* Host is first, if present */
std : : string host ;
if ( ! args [ 0 ] - > IsNumber ( ) ) {
NativeString h ( isolate , args [ 0 ] ) ;
if ( h . isInvalid ( args ) ) {
return ;
}
host = h . getString ( ) ;
2019-02-10 10:28:33 +00:00
}
2019-01-14 10:34:20 +00:00
2019-04-17 20:09:11 +00:00
/* Port, options are in the middle, if present */
std : : vector < int > numbers ;
for ( int i = std : : min < int > ( 1 , host . length ( ) ) ; i < args . Length ( ) - 1 ; i + + ) {
numbers . push_back ( args [ i ] - > Uint32Value ( args . GetIsolate ( ) - > GetCurrentContext ( ) ) . ToChecked ( ) ) ;
}
/* We only use the most complete overload */
app - > listen ( host , numbers . size ( ) ? numbers [ 0 ] : 0 ,
numbers . size ( ) > 1 ? numbers [ 1 ] : 0 , std : : move ( cb ) ) ;
2019-01-14 10:34:20 +00:00
args . GetReturnValue ( ) . Set ( args . Holder ( ) ) ;
}
2019-10-17 00:19:46 +00:00
template < typename APP >
void uWS_App_publish ( const FunctionCallbackInfo < Value > & args ) {
APP * app = ( APP * ) args . Holder ( ) - > GetAlignedPointerFromInternalField ( 0 ) ;
2019-12-05 03:07:18 +00:00
Isolate * isolate = args . GetIsolate ( ) ;
2019-10-17 00:19:46 +00:00
NativeString topic ( isolate , args [ 0 ] ) ;
NativeString message ( isolate , args [ 1 ] ) ;
2019-11-08 12:49:40 +00:00
app - > publish ( topic . getString ( ) , message . getString ( ) , BooleanValue ( isolate , args [ 2 ] ) ? uWS : : OpCode : : BINARY : uWS : : OpCode : : TEXT , BooleanValue ( isolate , args [ 3 ] ) ) ;
2019-10-17 00:19:46 +00:00
}
2019-01-14 10:34:20 +00:00
template < typename APP >
void uWS_App ( const FunctionCallbackInfo < Value > & args ) {
2019-12-05 03:07:18 +00:00
Isolate * isolate = args . GetIsolate ( ) ;
2019-01-14 10:34:20 +00:00
Local < FunctionTemplate > appTemplate = FunctionTemplate : : New ( isolate ) ;
2019-12-05 20:30:49 +00:00
appTemplate - > SetClassName ( String : : NewFromUtf8 ( isolate , std : : is_same < APP , uWS : : SSLApp > : : value ? " uWS.SSLApp " : " uWS.App " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) ;
/* Read the options object if any */
us_socket_context_options_t options = { } ;
2019-12-10 14:12:34 +00:00
std : : string keyFileName , certFileName , passphrase , dhParamsFileName , caFileName ;
2019-12-05 20:30:49 +00:00
if ( args . Length ( ) = = 1 ) {
Local < Object > optionsObject = Local < Object > : : Cast ( args [ 0 ] ) ;
/* Key file name */
NativeString keyFileNameValue ( isolate , optionsObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " key_file_name " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ;
if ( keyFileNameValue . isInvalid ( args ) ) {
return ;
}
if ( keyFileNameValue . getString ( ) . length ( ) ) {
keyFileName = keyFileNameValue . getString ( ) ;
options . key_file_name = keyFileName . c_str ( ) ;
}
2019-01-14 10:34:20 +00:00
2019-12-05 20:30:49 +00:00
/* Cert file name */
NativeString certFileNameValue ( isolate , optionsObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " cert_file_name " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ;
if ( certFileNameValue . isInvalid ( args ) ) {
return ;
}
if ( certFileNameValue . getString ( ) . length ( ) ) {
certFileName = certFileNameValue . getString ( ) ;
options . cert_file_name = certFileName . c_str ( ) ;
2019-01-14 10:34:20 +00:00
}
2019-12-05 20:30:49 +00:00
/* Passphrase */
NativeString passphraseValue ( isolate , optionsObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " passphrase " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ;
if ( passphraseValue . isInvalid ( args ) ) {
return ;
}
if ( passphraseValue . getString ( ) . length ( ) ) {
passphrase = passphraseValue . getString ( ) ;
options . passphrase = passphrase . c_str ( ) ;
}
/* DH params file name */
NativeString dhParamsFileNameValue ( isolate , optionsObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " dh_params_file_name " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ;
if ( dhParamsFileNameValue . isInvalid ( args ) ) {
return ;
}
if ( dhParamsFileNameValue . getString ( ) . length ( ) ) {
dhParamsFileName = dhParamsFileNameValue . getString ( ) ;
options . dh_params_file_name = dhParamsFileName . c_str ( ) ;
}
/* CA file name */
NativeString caFileNameValue ( isolate , optionsObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " ca_file_name " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ;
if ( caFileNameValue . isInvalid ( args ) ) {
return ;
}
if ( caFileNameValue . getString ( ) . length ( ) ) {
caFileName = caFileNameValue . getString ( ) ;
options . ca_file_name = caFileName . c_str ( ) ;
}
/* ssl_prefer_low_memory_usage */
options . ssl_prefer_low_memory_usage = BooleanValue ( isolate , optionsObject - > Get ( isolate - > GetCurrentContext ( ) , String : : NewFromUtf8 ( isolate , " ssl_prefer_low_memory_usage " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) . ToLocalChecked ( ) ) ;
2019-01-14 10:34:20 +00:00
}
2019-12-05 20:30:49 +00:00
/* uSockets copies strings here */
APP * app = new APP ( options ) ;
2019-02-10 11:39:00 +00:00
/* Throw if we failed to construct the app */
if ( app - > constructorFailed ( ) ) {
delete app ;
2019-11-08 12:49:40 +00:00
args . GetReturnValue ( ) . Set ( isolate - > ThrowException ( String : : NewFromUtf8 ( isolate , " App construction failed " , NewStringType : : kNormal ) . ToLocalChecked ( ) ) ) ;
2019-02-10 11:39:00 +00:00
return ;
}
2019-01-14 10:34:20 +00:00
appTemplate - > InstanceTemplate ( ) - > SetInternalFieldCount ( 1 ) ;
2019-01-18 14:56:08 +00:00
/* All the http methods */
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " get " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-16 21:59:53 +00:00
uWS_App_get < APP > ( & APP : : get , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-14 10:34:20 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " post " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-16 21:59:53 +00:00
uWS_App_get < APP > ( & APP : : post , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-14 10:34:20 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " options " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-18 14:56:08 +00:00
uWS_App_get < APP > ( & APP : : options , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " del " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-18 14:56:08 +00:00
uWS_App_get < APP > ( & APP : : del , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " patch " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-18 14:56:08 +00:00
uWS_App_get < APP > ( & APP : : patch , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " put " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-18 14:56:08 +00:00
uWS_App_get < APP > ( & APP : : put , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " head " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-18 14:56:08 +00:00
uWS_App_get < APP > ( & APP : : head , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " connect " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-18 14:56:08 +00:00
uWS_App_get < APP > ( & APP : : connect , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " trace " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-18 14:56:08 +00:00
uWS_App_get < APP > ( & APP : : trace , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-01-22 17:42:50 +00:00
/* Any http method */
2019-11-08 12:49:40 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " any " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , [ ] ( auto & args ) {
2019-01-22 17:42:50 +00:00
uWS_App_get < APP > ( & APP : : any , args ) ;
2019-12-05 03:07:18 +00:00
} , args . Data ( ) ) ) ;
2019-01-18 14:56:08 +00:00
2019-01-16 21:59:53 +00:00
/* ws, listen */
2019-12-05 03:07:18 +00:00
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " ws " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , uWS_App_ws < APP > , args . Data ( ) ) ) ;
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " listen " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , uWS_App_listen < APP > , args . Data ( ) ) ) ;
appTemplate - > PrototypeTemplate ( ) - > Set ( String : : NewFromUtf8 ( isolate , " publish " , NewStringType : : kNormal ) . ToLocalChecked ( ) , FunctionTemplate : : New ( isolate , uWS_App_publish < APP > , args . Data ( ) ) ) ;
2019-01-14 10:34:20 +00:00
2019-04-24 01:01:54 +00:00
Local < Object > localApp = appTemplate - > GetFunction ( isolate - > GetCurrentContext ( ) ) . ToLocalChecked ( ) - > NewInstance ( isolate - > GetCurrentContext ( ) ) . ToLocalChecked ( ) ;
2019-01-14 10:34:20 +00:00
localApp - > SetAlignedPointerInInternalField ( 0 , app ) ;
2019-12-05 03:07:18 +00:00
PerContextData * perContextData = ( PerContextData * ) Local < External > : : Cast ( args . Data ( ) ) - > Value ( ) ;
2019-03-02 03:38:01 +00:00
/* Add this to our delete list */
if constexpr ( std : : is_same < APP , uWS : : SSLApp > : : value ) {
2019-12-05 03:07:18 +00:00
perContextData - > sslApps . emplace_back ( app ) ;
2019-03-02 03:38:01 +00:00
} else {
2019-12-05 03:07:18 +00:00
perContextData - > apps . emplace_back ( app ) ;
2019-03-02 03:38:01 +00:00
}
2019-01-14 10:34:20 +00:00
args . GetReturnValue ( ) . Set ( localApp ) ;
}