smaller buffer tbh no need for something so huge

This commit is contained in:
Adam D. Ruppe 2019-02-11 21:43:54 -05:00
parent 07e19d8ff1
commit 3f15f41ddc
2 changed files with 177 additions and 21 deletions

190
cgi.d
View File

@ -6147,7 +6147,7 @@ auto formatReturnValueAsHtml(T)(T t) {
/++
The base class for the [dispatcher] object support.
+/
class WebObject() {
class WebObject(Helper = void) {
Cgi cgi;
void initialize(Cgi cgi) {
this.cgi = cgi;
@ -6234,6 +6234,8 @@ class WebObject() {
FIXME: explain this better
+/
auto serveApi(T)(string urlPrefix) {
assert(urlPrefix[$ - 1] == '/');
import arsd.dom;
import arsd.jsvar;
@ -6294,6 +6296,124 @@ auto serveApi(T)(string urlPrefix) {
return DispatcherDefinition!handler(urlPrefix, false);
}
/++
The base of all REST objects.
+/
class RestObject(Helper = void) {
import arsd.dom;
import arsd.jsvar;
/// Show
void show() {}
/// ditto
void show(string urlId) {
load(urlId);
show();
}
enum AccessCheck {
allowed,
denied,
nonExistant,
}
enum Operation {
show,
create,
replace,
remove,
update
}
enum UpdateResult {
accessDenied,
noSuchResource,
success,
failure,
unnecessary
}
enum ValidationResult {
valid,
invalid
}
ValidationResult delegate(typeof(this)) validateFromReflection;
Element delegate(typeof(this)) toHtmlFromReflection;
var delegate(typeof(this)) toJsonFromReflection;
/// Override this to provide access control to this object.
AccessCheck accessCheck(string urlId, Operation operation) {
return AccessCheck.allowed;
}
ValidationResult validate() {
if(validateFromReflection !is null)
return validateFromReflection(this);
return ValidationResult.valid;
}
// The functions with more arguments are the low-level ones,
// they forward to the ones with fewer arguments by default.
void create() {} // POST on a parent collection - this is called from a collection class after the members are updated
void replace() {}
void replace(string urlId, scope void delegate() applyChanges) {
load(urlId);
applyChanges();
replace();
}
void update(string[] fieldList) {}
void update(string urlId, scope void delegate() applyChanges, string[] fieldList) {
load(urlId);
applyChanges();
update(fieldList);
}
void remove() {}
void remove(string urlId) {
load(urlId);
remove();
}
abstract void load(string urlId) {}
abstract void save() {}
Element toHtml() {
if(toHtmlFromReflection)
return toHtmlFromReflection(this);
else
assert(0);
}
var toJson() {
if(toJsonFromReflection)
return toJsonFromReflection(this);
else
assert(0);
}
}
/++
Base class for REST collections.
+/
class CollectionOf(Obj, Helper = void) : RestObject!(Helper) {
void index() {}
override void create() {}
override void load(string urlId) { assert(0); }
override void save() { assert(0); }
override void show() {
index();
}
override void show(string urlId) {
show();
}
}
/++
Serves a REST object, similar to a Ruby on Rails resource.
@ -6375,11 +6495,17 @@ auto serveApi(T)(string urlPrefix) {
int id;
string name;
void show() {} // automated! GET of this specific thing
// the default implementations of the urlId ones is to call load(that_id) then call the arg-less one.
// but you can override them to do it differently.
// any member which is of type RestObject can be linked automatically via href btw.
void show() {}
void show(string urlId) {} // automated! GET of this specific thing
void create() {} // POST on a parent collection - this is called from a collection class after the members are updated
void replace() {} // this is the PUT; really, it just updates all fields.
void update() {} // PATCH, it updates some fields.
void remove() {} // DELETE
void replace(string urlId) {} // this is the PUT; really, it just updates all fields.
void update(string urlId, string[] fieldList) {} // PATCH, it updates some fields.
void remove(string urlId) {} // DELETE
void load(string urlId) {} // the default implementation of show() populates the id, then
@ -6405,22 +6531,52 @@ auto serveApi(T)(string urlPrefix) {
User create() {} // You MAY implement this, but the default is to create a new object, populate it from args, and then call create() on the child
}
// so CollectionOf will mixin the stuff to forward it
OK, the underlying functions are actually really low level
GET(string url)
POST(string url)
PUT(string url)
The url starts with the initial thing passed.
It is the mixins that actually do the work.
+/
auto serveRestObject(T)(string urlPrefix) {
assert(urlPrefix[$ - 1] != '/', "Do NOT use a trailing slash on REST objects.");
static bool handler(string urlPrefix, Cgi cgi) {
string url = cgi.pathInfo[urlPrefix.length .. $];
if(url.length && url[$ - 1] == '/') {
// remove the final slash...
cgi.setResponseLocation("..");
return true;
}
string urlId = null;
if(url.length && url[0] == '/') {
// asking for a subobject
urlId = url[1 .. $];
foreach(idx, ch; urlId) {
if(ch == '/') {
urlId = urlId[0 .. idx];
break;
}
}
}
// FIXME: support precondition failed, if-modified-since, expectation failed, etc.
auto obj = new T();
obj.toHtmlFromReflection = delegate(t) {
import arsd.dom;
return Element.make("div", T.stringof ~ "/" ~ urlId);
};
// FIXME: populate reflection info delegates
switch(cgi.requestMethod) {
case Cgi.RequestMethod.GET:
obj.show(urlId);
cgi.write(obj.toHtml().toString, true);
break;
case Cgi.RequestMethod.POST:
case Cgi.RequestMethod.PUT:
case Cgi.RequestMethod.PATCH:
case Cgi.RequestMethod.DELETE:
default:
// FIXME: OPTIONS, HEAD
}
return true;
}
return DispatcherDefinition!handler(urlPrefix, false);
@ -6445,7 +6601,7 @@ auto serveStaticFile(string urlPrefix, string filename = null, string contentTyp
}
auto serveRedirect(string urlPrefix, string redirectTo) {
// FIXME
}
/+

8
jpeg.d
View File

@ -3148,8 +3148,8 @@ public ubyte[] decompress_jpeg_image_from_file(bool useMalloc=false) (const(char
bool m_eof_flag, m_error_flag;
if (filename.length == 0) throw new Exception("cannot open unnamed file");
if (filename.length < 2048) {
char[2049] buffer;
if (filename.length < 512) {
char[513] buffer;
//import core.stdc.stdlib : alloca;
auto tfn = buffer[0 .. filename.length + 1]; // (cast(char*)alloca(filename.length+1))[0..filename.length+1];
tfn[0..filename.length] = filename[];
@ -3340,8 +3340,8 @@ public MemoryImage readJpeg (const(char)[] filename) {
bool m_eof_flag, m_error_flag;
if (filename.length == 0) throw new Exception("cannot open unnamed file");
if (filename.length < 2048) {
char[2049] buffer;
if (filename.length < 512) {
char[513] buffer;
//import core.stdc.stdlib : alloca;
auto tfn = buffer[0 .. filename.length + 1]; // (cast(char*)alloca(filename.length+1))[0..filename.length+1];
tfn[0..filename.length] = filename[];