Wrap req.getQuery, req.getMethod, res.close, res.onData & add Upload example

This commit is contained in:
Alex Hultman 2019-01-17 08:22:43 +01:00
parent 3558bf30d9
commit 4ae2facba7
5 changed files with 83 additions and 3 deletions

36
examples/Upload.js Normal file
View File

@ -0,0 +1,36 @@
/* Minimal POST example a SSL/non-SSL */
/* todo: proper throttling, better example */
/* a good example would be using the router to get
* a file name and stream that file to disk */
const uWS = require('../dist/uws.js');
const port = 9001;
const app = uWS./*SSL*/App({
key_file_name: '/home/alexhultman/key.pem',
cert_file_name: '/home/alexhultman/cert.pem',
passphrase: '1234'
}).post('/*', (res, req) => {
console.log('Posted to ' + req.getUrl());
res.onData((chunk, isLast) => {
/* Buffer this anywhere you want to */
console.log('Got chunk of data with length ' + chunk.byteLength + ', isLast: ' + isLast);
/* We respond when we are done */
if (isLast) {
res.end('Thanks for the data!');
}
});
res.onAborted(() => {
/* Request was prematurely aborted, stop reading */
console.log('Eh, okay. Thanks for nothing!');
});
}).listen(port, (token) => {
if (token) {
console.log('Listening to port ' + port);
} else {
console.log('Failed to listen to port ' + port);
}
});

View File

@ -44,16 +44,31 @@ struct HttpRequestWrapper {
args.GetReturnValue().Set(String::NewFromUtf8(isolate, header.data(), v8::String::kNormalString, header.length())); args.GetReturnValue().Set(String::NewFromUtf8(isolate, header.data(), v8::String::kNormalString, header.length()));
} }
static void req_getMethod(const FunctionCallbackInfo<Value> &args) {
std::string_view method = getHttpRequest(args)->getMethod();
args.GetReturnValue().Set(String::NewFromUtf8(isolate, method.data(), v8::String::kNormalString, method.length()));
}
static void req_getQuery(const FunctionCallbackInfo<Value> &args) {
std::string_view query = getHttpRequest(args)->getQuery();
args.GetReturnValue().Set(String::NewFromUtf8(isolate, query.data(), v8::String::kNormalString, query.length()));
}
static void initReqTemplate() { static void initReqTemplate() {
/* We do clone every request object, we could share them, they are illegal to use outside the function anyways */ /* We do clone every request object, we could share them, they are illegal to use outside the function anyways */
Local<FunctionTemplate> reqTemplateLocal = FunctionTemplate::New(isolate); Local<FunctionTemplate> reqTemplateLocal = FunctionTemplate::New(isolate);
reqTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.HttpRequest")); reqTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.HttpRequest"));
reqTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1); reqTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1);
/* Register our functions */ /* Register our functions */
reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getHeader"), FunctionTemplate::New(isolate, req_getHeader)); reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getHeader"), FunctionTemplate::New(isolate, req_getHeader));
reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getParameter"), FunctionTemplate::New(isolate, req_getParameter)); reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getParameter"), FunctionTemplate::New(isolate, req_getParameter));
reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getUrl"), FunctionTemplate::New(isolate, req_getUrl)); reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getUrl"), FunctionTemplate::New(isolate, req_getUrl));
reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getMethod"), FunctionTemplate::New(isolate, req_getMethod));
reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getQuery"), FunctionTemplate::New(isolate, req_getQuery));
/* Create the template */ /* Create the template */
Local<Object> reqObjectLocal = reqTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); Local<Object> reqObjectLocal = reqTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();

View File

@ -11,7 +11,33 @@ struct HttpResponseWrapper {
return (uWS::HttpResponse<SSL> *) args.Holder()->GetAlignedPointerFromInternalField(0); return (uWS::HttpResponse<SSL> *) args.Holder()->GetAlignedPointerFromInternalField(0);
} }
// res.onData(JS function) /* Takes nothing, kills the connection */
template <bool SSL>
static void res_close(const FunctionCallbackInfo<Value> &args) {
getHttpResponse<SSL>(args)->close();
args.GetReturnValue().Set(args.Holder());
}
/* Takes function of data and isLast. Expects nothing from callback, returns this */
template <bool SSL>
static void res_onData(const FunctionCallbackInfo<Value> &args) {
/* This thing perfectly fits in with unique_function, and will Reset on destructor */
UniquePersistent<Function> p(isolate, Local<Function>::Cast(args[0]));
getHttpResponse<SSL>(args)->onData([p = std::move(p)](std::string_view data, bool last) {
HandleScope hs(isolate);
Local<ArrayBuffer> dataArrayBuffer = ArrayBuffer::New(isolate, (void *) data.data(), data.length());
Local<Value> argv[] = {dataArrayBuffer, Boolean::New(isolate, last)};
Local<Function>::New(isolate, p)->Call(isolate->GetCurrentContext()->Global(), 2, argv);
dataArrayBuffer->Neuter();
});
args.GetReturnValue().Set(args.Holder());
}
/* Takes nothing, returns nothing. Cb wants nothing returned. */ /* Takes nothing, returns nothing. Cb wants nothing returned. */
template <bool SSL> template <bool SSL>
@ -119,10 +145,11 @@ struct HttpResponseWrapper {
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "tryEnd"), FunctionTemplate::New(isolate, res_tryEnd<SSL>)); resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "tryEnd"), FunctionTemplate::New(isolate, res_tryEnd<SSL>));
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "write"), FunctionTemplate::New(isolate, res_write<SSL>)); resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "write"), FunctionTemplate::New(isolate, res_write<SSL>));
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "writeHeader"), FunctionTemplate::New(isolate, res_writeHeader<SSL>)); resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "writeHeader"), FunctionTemplate::New(isolate, res_writeHeader<SSL>));
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close"), FunctionTemplate::New(isolate, res_close<SSL>));
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getWriteOffset"), FunctionTemplate::New(isolate, res_getWriteOffset<SSL>)); resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getWriteOffset"), FunctionTemplate::New(isolate, res_getWriteOffset<SSL>));
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onWritable"), FunctionTemplate::New(isolate, res_onWritable<SSL>)); resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onWritable"), FunctionTemplate::New(isolate, res_onWritable<SSL>));
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onAborted"), FunctionTemplate::New(isolate, res_onAborted<SSL>)); resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onAborted"), FunctionTemplate::New(isolate, res_onAborted<SSL>));
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onData"), FunctionTemplate::New(isolate, res_onData<SSL>));
/* Create our template */ /* Create our template */
Local<Object> resObjectLocal = resTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); Local<Object> resObjectLocal = resTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();

View File

@ -3,6 +3,8 @@
#include "Utilities.h" #include "Utilities.h"
using namespace v8; using namespace v8;
// todo: probably isCorked, cork should be exposed?
struct WebSocketWrapper { struct WebSocketWrapper {
static Persistent<Object> wsTemplate[2]; static Persistent<Object> wsTemplate[2];

@ -1 +1 @@
Subproject commit 2a62218d2a4344255463eeb7b1cbda507f90e86f Subproject commit 04281eeea649d2d9d527644eba5866de44b64502