mirror of https://github.com/adamdruppe/arsd.git
Merge branch 'master' of https://github.com/eskimor/misc-stuff-including-D-programming-language-web-stuff
Conflicts: database.d
This commit is contained in:
commit
f2943b90b3
22
cgi.d
22
cgi.d
|
@ -310,7 +310,8 @@ class Cgi {
|
|||
else
|
||||
requestMethod = RequestMethod.CommandLine;
|
||||
|
||||
https = getenv("HTTPS") == "on";
|
||||
// FIXME: hack on REDIRECT_HTTPS; this is there because the work app uses mod_rewrite which loses the https flag! So I set it with [E=HTTPS=%HTTPS] or whatever but then it gets translated to here so i want it to still work. This is arguably wrong but meh.
|
||||
https = (getenv("HTTPS") == "on" || getenv("REDIRECT_HTTPS") == "on");
|
||||
|
||||
// FIXME: DOCUMENT_ROOT?
|
||||
|
||||
|
@ -480,6 +481,15 @@ class Cgi {
|
|||
bool contentInMemory = true; // the default ought to always be true
|
||||
immutable(ubyte)[] content; /// The actual content of the file, if contentInMemory == true
|
||||
string contentFilename; /// the file where we dumped the content, if contentInMemory == false. Note that if you want to keep it, you MUST move the file, since otherwise it is considered garbage when cgi is disposed.
|
||||
|
||||
|
||||
void writeToFile(string filenameToSaveTo) {
|
||||
import std.file;
|
||||
if(contentInMemory)
|
||||
std.file.write(filenameToSaveTo, content);
|
||||
else
|
||||
std.file.rename(contentFilename, filenameToSaveTo);
|
||||
}
|
||||
}
|
||||
|
||||
// given a content type and length, decide what we're going to do with the data..
|
||||
|
@ -633,8 +643,9 @@ class Cgi {
|
|||
// here, we should be lined up right at the boundary, which is followed by a \r\n
|
||||
|
||||
// want to keep the buffer under control in case we're under attack
|
||||
if(pps.buffer.length + chunk.length > 70 * 1024) // they should be < 1 kb really....
|
||||
throw new Exception("wtf is up with the huge mime part headers");
|
||||
//stderr.writeln("here once");
|
||||
//if(pps.buffer.length + chunk.length > 70 * 1024) // they should be < 1 kb really....
|
||||
// throw new Exception("wtf is up with the huge mime part headers");
|
||||
|
||||
acceptChunk();
|
||||
|
||||
|
@ -1157,6 +1168,11 @@ class Cgi {
|
|||
requestUri);
|
||||
}
|
||||
|
||||
/// You can override this if your site base url isn't the same as the script name
|
||||
string logicalScriptName() const {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
/// Sets the HTTP status of the response. For example, "404 File Not Found" or "500 Internal Server Error".
|
||||
/// It assumes "200 OK", and automatically changes to "302 Found" if you call setResponseLocation().
|
||||
/// Note setResponseStatus() must be called *before* you write() any data to the output.
|
||||
|
|
16
database.d
16
database.d
|
@ -41,7 +41,7 @@ interface Database {
|
|||
a = to!string(e);
|
||||
} else if (arg == typeid(null)) {
|
||||
a = null;
|
||||
} else assert(0, "invalid type " ~ arg.toString );
|
||||
} else assert(0, "invalid type " ~ arg.toString() );
|
||||
|
||||
args ~= Variant(a);
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ struct Row {
|
|||
}
|
||||
|
||||
int opApply(int delegate(ref string, ref string) dg) {
|
||||
foreach(a, b; toAA)
|
||||
foreach(a, b; toAA())
|
||||
mixin(yield("a, b"));
|
||||
|
||||
return 0;
|
||||
|
@ -137,10 +137,10 @@ interface ResultSet {
|
|||
string[] fieldNames();
|
||||
|
||||
// this is a range that can offer other ranges to access it
|
||||
bool empty();
|
||||
Row front();
|
||||
void popFront();
|
||||
int length();
|
||||
bool empty() @property;
|
||||
Row front() @property;
|
||||
void popFront() ;
|
||||
int length() @property;
|
||||
|
||||
/* deprecated */ final ResultSet byAssoc() { return this; }
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ class SelectBuilder : SqlBuilder {
|
|||
return s;
|
||||
}
|
||||
|
||||
string toString() {
|
||||
override string toString() {
|
||||
string sql = "SELECT ";
|
||||
|
||||
// the fields first
|
||||
|
@ -460,7 +460,7 @@ string fixupSqlForDataObjectUse(string sql, string[string] keyMapping = null) {
|
|||
auto from = sql[start..i];
|
||||
auto pieces = from.split(",");
|
||||
foreach(p; pieces) {
|
||||
p = p.strip;
|
||||
p = p.strip();
|
||||
start = 0;
|
||||
i = 0;
|
||||
while(i < p.length && p[i] != ' ' && p[i] != '\n' && p[i] != '\t' && p[i] != ',')
|
||||
|
|
13
dom.d
13
dom.d
|
@ -3414,14 +3414,23 @@ class Document : FileResource {
|
|||
pos++;
|
||||
pos++; // skip the >
|
||||
break;
|
||||
// case '%':
|
||||
case '?':
|
||||
char end = data[pos];
|
||||
// FIXME this is all kinda broken
|
||||
|
||||
more:
|
||||
pos++; // skip the start
|
||||
while(data[pos] != end)
|
||||
|
||||
while(data[pos] != end) {
|
||||
// FIXME: what if it is PHP?
|
||||
if(data[pos] == '>')
|
||||
break; // I've seen this in the wild: <?EM-dummyText>
|
||||
pos++;
|
||||
pos++; // skip the end
|
||||
}
|
||||
|
||||
if(data[pos] == end)
|
||||
pos++; // skip the end
|
||||
|
||||
// FIXME: we should actually store this somewhere
|
||||
// though I like having it stripped out as well tbh.
|
||||
|
|
17
html.d
17
html.d
|
@ -230,6 +230,21 @@ Html linkify(string text) {
|
|||
return Html(div.innerHTML);
|
||||
}
|
||||
|
||||
Html nl2br(string text) {
|
||||
auto div = Element.make("div");
|
||||
|
||||
bool first = true;
|
||||
foreach(line; splitLines(text)) {
|
||||
if(!first)
|
||||
div.addChild("br");
|
||||
else
|
||||
first = false;
|
||||
div.appendText(line);
|
||||
}
|
||||
|
||||
return Html(div.innerHTML);
|
||||
}
|
||||
|
||||
/// Returns true of the string appears to be html/xml - if it matches the pattern
|
||||
/// for tags or entities.
|
||||
bool appearsToBeHtml(string src) {
|
||||
|
@ -640,7 +655,7 @@ void translateInputTitles(Document document) {
|
|||
void translateInputTitles(Element rootElement) {
|
||||
foreach(form; rootElement.getElementsByTagName("form")) {
|
||||
string os;
|
||||
foreach(e; form.getElementsBySelector("input[type=text][title], textarea[title]")) {
|
||||
foreach(e; form.getElementsBySelector("input[type=text][title], input[type=email][title], textarea[title]")) {
|
||||
if(e.hasClass("has-placeholder"))
|
||||
continue;
|
||||
e.addClass("has-placeholder");
|
||||
|
|
10
oauth.d
10
oauth.d
|
@ -35,7 +35,7 @@ import std.md5;
|
|||
import std.file;
|
||||
|
||||
|
||||
Variant[string] postToFacebookWall(string[] info, string id, string message, string picture = null, string link = null) {
|
||||
Variant[string] postToFacebookWall(string[] info, string id, string message, string picture = null, string link = null, long when = 0) {
|
||||
string url = "https://graph.facebook.com/" ~ id ~ "/feed";
|
||||
|
||||
|
||||
|
@ -46,6 +46,8 @@ Variant[string] postToFacebookWall(string[] info, string id, string message, str
|
|||
data ~= "&picture=" ~ std.uri.encodeComponent(picture);
|
||||
if(link !is null && link.length)
|
||||
data ~= "&link=" ~ std.uri.encodeComponent(link);
|
||||
if(when)
|
||||
data ~= "&scheduled_publish_time=" ~ to!string(when);
|
||||
|
||||
auto response = curl(url, data);
|
||||
|
||||
|
@ -271,6 +273,8 @@ string tweet(OAuthParams params, string oauthToken, string tokenSecret, string m
|
|||
auto ret = curlOAuth(params, "http://api.twitter.com" ~ "/1/statuses/update.json", args, "POST", data);
|
||||
|
||||
auto val = jsonToVariant(ret).get!(Variant[string]);
|
||||
if("id_str" !in val)
|
||||
throw new Exception("bad result from twitter: " ~ ret);
|
||||
return val["id_str"].get!string;
|
||||
}
|
||||
|
||||
|
@ -317,7 +321,7 @@ void authorizeStepOne(Cgi cgi, OAuthParams params, string oauthCallback = null)
|
|||
Gets the final token, given the stuff from step one. This should be called
|
||||
from the callback in step one.
|
||||
|
||||
Returns [token, secret]
|
||||
Returns [token, secret, raw original data (for extended processing - twitter also sends the screen_name and user_id there)]
|
||||
*/
|
||||
string[] authorizeStepTwo(const(Cgi) cgi, OAuthParams params) {
|
||||
if("oauth_problem" in cgi.get)
|
||||
|
@ -339,7 +343,7 @@ string[] authorizeStepTwo(const(Cgi) cgi, OAuthParams params) {
|
|||
|
||||
auto vars = decodeVariables(ret);
|
||||
|
||||
return [vars["oauth_token"][0], vars["oauth_token_secret"][0]];
|
||||
return [vars["oauth_token"][0], vars["oauth_token_secret"][0], ret];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ class PostgresResult : ResultSet {
|
|||
void popFront() {
|
||||
position++;
|
||||
if(position < numRows)
|
||||
fetchNext;
|
||||
fetchNext();
|
||||
}
|
||||
|
||||
int length() {
|
||||
|
|
11
rtud.d
11
rtud.d
|
@ -297,9 +297,11 @@ Message[] parseMessages(string wegot, string eventTypeFilter = null) {
|
|||
switch(name) {
|
||||
default: break; // do nothing
|
||||
case "timestamp":
|
||||
if(data.length)
|
||||
m.timestamp = to!long(data);
|
||||
break;
|
||||
case "ttl":
|
||||
if(data.length)
|
||||
m.ttl = to!long(data);
|
||||
break;
|
||||
case "operation":
|
||||
|
@ -448,7 +450,7 @@ class NotificationConnection : RtudConnection {
|
|||
|
||||
auto bm = sort!"a.timestamp < b.timestamp"(backMessages);
|
||||
|
||||
backMessages = array(find!("a.timestamp > b")(bm, to!long(message["minimum-time"][$-1])));
|
||||
backMessages = array(find!("a.timestamp >= b")(bm, to!long(message["minimum-time"][$-1])));
|
||||
}
|
||||
|
||||
if("close-time" in message)
|
||||
|
@ -474,8 +476,11 @@ class DataConnection : RtudConnection {
|
|||
|
||||
override void handleMessage(string[][string] message) {
|
||||
string getStr(string key, string def) {
|
||||
if(key in message)
|
||||
return message[key][$ - 1];
|
||||
if(key in message) {
|
||||
auto s = message[key][$ - 1];
|
||||
if(s.length)
|
||||
return s;
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
|
|
|
@ -403,8 +403,10 @@ class LocalWebDotDApiProvider extends WebDotDApiProvider {
|
|||
// The full session ID tells it what to use, and the file hash proves
|
||||
// to D that we already have access to it.
|
||||
$magic = $this->session->sessionId . ";" . $this->session->fileHash;
|
||||
$headers = array("X-Arsd-Local: yes");
|
||||
if(strlen($magic) > 0)
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-Arsd-Session-Override: $magic"));
|
||||
$headers[] = "X-Arsd-Session-Override: $magic";
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue