Wrap req.getQuery, req.getMethod, res.close, res.onData & add Upload example
This commit is contained in:
parent
3558bf30d9
commit
4ae2facba7
36
examples/Upload.js
Normal file
36
examples/Upload.js
Normal 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);
|
||||||
|
}
|
||||||
|
});
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user