mirror of https://github.com/adamdruppe/arsd.git
updating
This commit is contained in:
parent
e442e61a59
commit
3b87c881bb
29
cgi.d
29
cgi.d
|
@ -525,7 +525,7 @@ class Cgi {
|
|||
setResponseStatus("401 Authorization Required");
|
||||
header ("WWW-Authenticate: Basic realm=\""~message~"\"");
|
||||
close();
|
||||
throw new Exception("Not authorized");
|
||||
throw new Exception("Not authorized; got " ~ authorization);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -825,6 +825,10 @@ class Cgi {
|
|||
} catch(Exception e) { return def; }
|
||||
}
|
||||
|
||||
bool isClosed() const {
|
||||
return closed;
|
||||
}
|
||||
|
||||
private void delegate(const(ubyte)[]) rawDataOutput = null;
|
||||
|
||||
private bool outputtedResponseData;
|
||||
|
@ -1039,14 +1043,16 @@ version(embedded_httpd)
|
|||
fun(cgi);
|
||||
cgi.close();
|
||||
} catch(Throwable t) {
|
||||
auto msg = t.toString;
|
||||
FCGX_PutStr(cast(ubyte*) msg.ptr, msg.length, error);
|
||||
msg = "Status: 500 Internal Server Error\n";
|
||||
msg ~= "Content-Type: text/plain\n\n";
|
||||
debug msg ~= t.toString;
|
||||
else msg ~= "An unexpected error has occurred.";
|
||||
if(1) { // !cgi.isClosed) {
|
||||
auto msg = t.toString;
|
||||
FCGX_PutStr(cast(ubyte*) msg.ptr, msg.length, error);
|
||||
msg = "Status: 500 Internal Server Error\n";
|
||||
msg ~= "Content-Type: text/plain\n\n";
|
||||
debug msg ~= t.toString;
|
||||
else msg ~= "An unexpected error has occurred.";
|
||||
|
||||
FCGX_PutStr(cast(ubyte*) msg.ptr, msg.length, output);
|
||||
FCGX_PutStr(cast(ubyte*) msg.ptr, msg.length, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1059,6 +1065,10 @@ version(embedded_httpd)
|
|||
fun(cgi);
|
||||
cgi.close();
|
||||
} catch (Throwable c) {
|
||||
// if the thing is closed, the app probably wrote an error message already, don't do it again.
|
||||
//if(cgi.isClosed)
|
||||
//goto doNothing;
|
||||
|
||||
// FIXME: this sucks
|
||||
string message = "An unexpected error has occurred.";
|
||||
|
||||
|
@ -1070,6 +1080,9 @@ version(embedded_httpd)
|
|||
int idx = str.indexOf("\n");
|
||||
if(idx != -1)
|
||||
str = str[0..idx];
|
||||
|
||||
doNothing:
|
||||
|
||||
stderr.writeln(str);
|
||||
}
|
||||
}
|
||||
|
|
107
dom.d
107
dom.d
|
@ -186,10 +186,24 @@ class Element {
|
|||
string[string] attributes;
|
||||
|
||||
///.
|
||||
bool selfClosed;
|
||||
private bool selfClosed;
|
||||
|
||||
///.
|
||||
Document parentDocument;
|
||||
/// Get the parent Document object that contains this element.
|
||||
/// It may return null and/or run in O(n) time with the height of the tree.
|
||||
pure Document parentDocument() {
|
||||
auto e = this;
|
||||
while(e !is null && e._parentDocument is null)
|
||||
e = e.parentNode;
|
||||
if(e is null)
|
||||
return null;
|
||||
return e._parentDocument;
|
||||
}
|
||||
|
||||
pure void parentDocument(Document pd) {
|
||||
_parentDocument = pd;
|
||||
}
|
||||
|
||||
private Document _parentDocument;
|
||||
|
||||
///.
|
||||
this(Document _parentDocument, string _tagName, string[string] _attributes = null, bool _selfClosed = false) {
|
||||
|
@ -434,12 +448,30 @@ class Element {
|
|||
assert(0);
|
||||
}
|
||||
|
||||
/// Convenience function to try to do the right thing for HTML
|
||||
static Element make(string tagName, string childInfo = null, string childInfo2 = null) {
|
||||
bool selfClosed = tagName.isInArray(selfClosedElements);
|
||||
|
||||
Element e;
|
||||
// want to create the right kind of object for the given tag...
|
||||
switch(tagName) {
|
||||
case "table":
|
||||
e = new Table(null);
|
||||
break;
|
||||
case "a":
|
||||
e = new Link(null);
|
||||
break;
|
||||
case "form":
|
||||
e = new Form(null);
|
||||
break;
|
||||
default:
|
||||
e = new Element(null, tagName, null, selfClosed); // parent document should be set elsewhere
|
||||
}
|
||||
|
||||
// make sure all the stuff is constructed properly FIXME: should probably be in all the right constructors too
|
||||
e.tagName = tagName;
|
||||
e.selfClosed = selfClosed;
|
||||
|
||||
/// convenience function to quickly add a tag with some text or
|
||||
/// other relevant info (for example, it's a src for an <img> element
|
||||
/// instead of inner text)
|
||||
Element addChild(string tagName, string childInfo = null, string childInfo2 = null) {
|
||||
auto e = parentDocument.createElement(tagName);
|
||||
if(childInfo !is null)
|
||||
switch(tagName) {
|
||||
case "img":
|
||||
|
@ -475,6 +507,16 @@ class Element {
|
|||
default:
|
||||
e.innerText = childInfo;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/// convenience function to quickly add a tag with some text or
|
||||
/// other relevant info (for example, it's a src for an <img> element
|
||||
/// instead of inner text)
|
||||
Element addChild(string tagName, string childInfo = null, string childInfo2 = null) {
|
||||
auto e = Element.make(tagName, childInfo, childInfo2);
|
||||
e.parentDocument = this.parentDocument;
|
||||
return appendChild(e);
|
||||
}
|
||||
|
||||
|
@ -957,7 +999,7 @@ class Element {
|
|||
Note that the returned string is decoded, so it no longer contains any xml entities.
|
||||
*/
|
||||
string getAttribute(string name) const {
|
||||
if(parentDocument && parentDocument.loose)
|
||||
if(_parentDocument && _parentDocument.loose)
|
||||
name = name.toLower();
|
||||
auto e = name in attributes;
|
||||
if(e)
|
||||
|
@ -970,7 +1012,7 @@ class Element {
|
|||
Sets an attribute. Returns this for easy chaining
|
||||
*/
|
||||
Element setAttribute(string name, string value) {
|
||||
if(parentDocument && parentDocument.loose)
|
||||
if(_parentDocument && _parentDocument.loose)
|
||||
name = name.toLower();
|
||||
|
||||
// I never use this shit legitimately and neither should you
|
||||
|
@ -990,7 +1032,7 @@ class Element {
|
|||
Extension
|
||||
*/
|
||||
bool hasAttribute(string name) {
|
||||
if(parentDocument && parentDocument.loose)
|
||||
if(_parentDocument && _parentDocument.loose)
|
||||
name = name.toLower();
|
||||
|
||||
if(name in attributes)
|
||||
|
@ -1003,7 +1045,7 @@ class Element {
|
|||
Extension
|
||||
*/
|
||||
void removeAttribute(string name) {
|
||||
if(parentDocument && parentDocument.loose)
|
||||
if(_parentDocument && _parentDocument.loose)
|
||||
name = name.toLower();
|
||||
if(name in attributes)
|
||||
attributes.remove(name);
|
||||
|
@ -1183,6 +1225,23 @@ class Element {
|
|||
return this;
|
||||
}
|
||||
|
||||
/// Wraps this element inside the given element.
|
||||
/// It's like this.replaceWith(what); what.appendchild(this);
|
||||
Element wrapIn(Element what)
|
||||
in {
|
||||
assert(what !is null);
|
||||
}
|
||||
out(ret) {
|
||||
assert(this.parentNode is what);
|
||||
assert(ret is what);
|
||||
}
|
||||
body {
|
||||
this.replaceWith(what);
|
||||
what.appendChild(this);
|
||||
|
||||
return what;
|
||||
}
|
||||
|
||||
Element replaceWith(Element e) {
|
||||
if(e.parentNode !is null)
|
||||
e.parentNode.removeChild(e);
|
||||
|
@ -1560,6 +1619,7 @@ class Link : Element {
|
|||
///.
|
||||
this(Document _parentDocument) {
|
||||
super(_parentDocument);
|
||||
this.tagName = "a";
|
||||
}
|
||||
|
||||
|
||||
|
@ -2610,27 +2670,8 @@ class Document {
|
|||
Element createElement(string name) {
|
||||
if(loose)
|
||||
name = name.toLower();
|
||||
|
||||
bool selfClosed = name.isInArray(selfClosedElements);
|
||||
|
||||
Element e;
|
||||
switch(name) {
|
||||
case "table":
|
||||
e = new Table(this);
|
||||
break;
|
||||
case "a":
|
||||
e = new Link(this);
|
||||
break;
|
||||
case "form":
|
||||
e = new Form(this);
|
||||
break;
|
||||
default:
|
||||
return new Element(this, name, null, selfClosed);
|
||||
}
|
||||
|
||||
// make sure all the stuff is constructed properly FIXME: should probably be in all the right constructors too
|
||||
e.tagName = name;
|
||||
e.selfClosed = selfClosed;
|
||||
|
||||
auto e = Element.make(name);
|
||||
e.parentDocument = this;
|
||||
|
||||
return e;
|
||||
|
|
20
web.d
20
web.d
|
@ -130,6 +130,8 @@ struct RequestInfo {
|
|||
string mainSitePath; /// the bottom-most ApiProvider's path in this request
|
||||
string objectBasePath; /// the top-most resolved path in the current request
|
||||
|
||||
FunctionInfo currentFunction; /// what function is being called according to the url?
|
||||
|
||||
string requestedFormat; /// the format the returned data was requested to be sent
|
||||
string requestedEnvelopeFormat; /// the format the data is to be wrapped in
|
||||
}
|
||||
|
@ -189,9 +191,10 @@ class ApiProvider {
|
|||
void _postProcess(Document document) {}
|
||||
|
||||
/// This tentatively redirects the user - depends on the envelope fomat
|
||||
void redirect(string location) {
|
||||
if(cgi.request("envelopeFormat", "document") == "document")
|
||||
cgi.setResponseLocation(location, false);
|
||||
void redirect(string location, bool important = false) {
|
||||
auto f = cgi.request("envelopeFormat", "document");
|
||||
if(f == "document" || f == "redirect")
|
||||
cgi.setResponseLocation(location, important);
|
||||
}
|
||||
|
||||
/// Returns a list of links to all functions in this class or sub-classes
|
||||
|
@ -868,9 +871,13 @@ void run(Provider)(Cgi cgi, Provider instantiation, int pathInfoStartingPoint =
|
|||
auto mfun = new FunctionInfo;
|
||||
mfun.returnType = "Form";
|
||||
mfun.dispatcher = delegate JSONValue (Cgi cgi, string, in string[][string] sargs, in string format, in string secondaryFormat = null) {
|
||||
auto rfun = cgi.request("method") in reflection.functions;
|
||||
auto lik = cgi.request("positional-arg-0");
|
||||
if(lik.length == 0)
|
||||
//lik = cgi.get["method"];
|
||||
lik = cgi.post["method"]; // FIXME
|
||||
auto rfun = lik in reflection.functions;
|
||||
if(rfun is null)
|
||||
throw new NoSuchPageException("no such function " ~ cgi.request("method"));
|
||||
throw new NoSuchPageException("no such function " ~ lik);
|
||||
|
||||
Form form;
|
||||
if((*rfun).createForm !is null) {
|
||||
|
@ -2389,7 +2396,8 @@ enum string javascriptBaseImpl = q{
|
|||
"_serverCall": function (name, passedArgs, returnType) {
|
||||
var me = this; // this is the Api object
|
||||
var args;
|
||||
if(typeof args == "object")
|
||||
// FIXME: is there some way to tell arguments apart from other objects? dynamic languages suck.
|
||||
if(!passedArgs.length)
|
||||
args = passedArgs;
|
||||
else {
|
||||
args = new Object();
|
||||
|
|
Loading…
Reference in New Issue