From 1da9f87b222378f67df742f01d91dd820e86eb89 Mon Sep 17 00:00:00 2001 From: "Adam D. Ruppe" Date: Tue, 4 Dec 2018 10:40:15 -0500 Subject: [PATCH 1/4] maybe unbalanced parens --- cgi.d | 4 ++-- minigui.d | 10 ++++++++++ simpledisplay.d | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/cgi.d b/cgi.d index 439697d..a4d2bb1 100644 --- a/cgi.d +++ b/cgi.d @@ -148,7 +148,7 @@ void main() { Concepts: Input: [Cgi.get], [Cgi.post], [Cgi.request], [Cgi.files], [Cgi.cookies], [Cgi.pathInfo], [Cgi.requestMethod], - and HTTP headers ([Cgi.headers], [Cgi.userAgent], [Cgi.referrer], [Cgi.accept], [Cgi.authorization], [Cgi.lastEventId] + and HTTP headers ([Cgi.headers], [Cgi.userAgent], [Cgi.referrer], [Cgi.accept], [Cgi.authorization], [Cgi.lastEventId]) Output: [Cgi.write], [Cgi.header], [Cgi.setResponseStatus], [Cgi.setResponseContentType], [Cgi.gzipResponse] @@ -2232,7 +2232,7 @@ class Cgi { immutable(char[]) scriptName; /// The full base path of your program, as seen by the user. If your program is located at site.com/programs/apps, scriptName == "/programs/apps". immutable(char[]) scriptFileName; /// The physical filename of your script immutable(char[]) authorization; /// The full authorization string from the header, undigested. Useful for implementing auth schemes such as OAuth 1.0. Note that some web servers do not forward this to the app without taking extra steps. See requireBasicAuth's comment for more info. - immutable(char[]) accept; /// The HTTP accept header is the user agent telling what content types it is willing to accept. This is often */*; they accept everything, so it's not terribly useful. (The similar sounding Accept-Encoding header is handled automatically for chunking and gzipping. Simply set gzipResponse = true and cgi.d handles the details, zipping if the user's browser is willing to accept it. + immutable(char[]) accept; /// The HTTP accept header is the user agent telling what content types it is willing to accept. This is often */*; they accept everything, so it's not terribly useful. (The similar sounding Accept-Encoding header is handled automatically for chunking and gzipping. Simply set gzipResponse = true and cgi.d handles the details, zipping if the user's browser is willing to accept it.) immutable(char[]) lastEventId; /// The HTML 5 draft includes an EventSource() object that connects to the server, and remains open to take a stream of events. My arsd.rtud module can help with the server side part of that. The Last-Event-Id http header is defined in the draft to help handle loss of connection. When the browser reconnects to you, it sets this header to the last event id it saw, so you can catch it up. This member has the contents of that header. immutable(RequestMethod) requestMethod; /// The HTTP request verb: GET, POST, etc. It is represented as an enum in cgi.d (which, like many enums, you can convert back to string with std.conv.to()). A HTTP GET is supposed to, according to the spec, not have side effects; a user can GET something over and over again and always have the same result. On all requests, the get[] and getArray[] members may be filled in. The post[] and postArray[] members are only filled in on POST methods. diff --git a/minigui.d b/minigui.d index 02feccc..6abf1fb 100644 --- a/minigui.d +++ b/minigui.d @@ -4998,6 +4998,16 @@ class MouseActivatedWidget : Widget { } else static assert(false); +/* +/++ + Like the tablet thing, it would have a label, a description, and a switch slider thingy. + + Basically the same as a checkbox. ++/ +class OnOffSwitch : MouseActivatedWidget { + +} +*/ /// class Checkbox : MouseActivatedWidget { diff --git a/simpledisplay.d b/simpledisplay.d index d0f31e5..7529ff2 100644 --- a/simpledisplay.d +++ b/simpledisplay.d @@ -1,5 +1,15 @@ -// FIXME: if the taskbar dies, a notification icon is undocked... but never detects a new taskbar spawning // https://dpaste.dzfl.pl/7a77355acaec + +/* + Event Loop would be nices: + + * add on idle - runs when nothing else happens + * send messages without a recipient window + * setTimeout + * setInterval + +*/ + /* Text layout needs a lot of work. Plain drawText is useful but too limited. It will need some kind of text context thing which it will @@ -2629,6 +2639,21 @@ struct EventLoop { static EventLoopImpl* impl; } +version(linux) + void delegate(int, int) globalHupHandler; + +version(linux) + void makeNonBlocking(int fd) { + import fcntl = core.sys.posix.fcntl; + auto flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0); + if(flags == -1) + throw new Exception("fcntl get"); + flags |= fcntl.O_NONBLOCK; + auto s = fcntl.fcntl(fd, fcntl.F_SETFL, flags); + if(s == -1) + throw new Exception("fcntl set"); + } + struct EventLoopImpl { int refcount; @@ -2898,6 +2923,12 @@ struct EventLoopImpl { // (if you want other fds, use arsd.eventloop and compile with -version=with_eventloop), it offers a fuller api for arbitrary stuff. } } + if(flags & ep.EPOLLHUP) { + if(PosixFdReader* pfr = fd in PosixFdReader.mapping) + (*pfr).hup(flags); + if(globalHupHandler) + globalHupHandler(fd, flags); + } /+ } else { // not interested in OUT, we are just reading here. @@ -4165,6 +4196,13 @@ class PosixFdReader { onReady(fd, (flags & ep.EPOLLIN) ? true : false, (flags & ep.EPOLLOUT) ? true : false); } + void hup(uint flags) { + if(onHup) + onHup(); + } + + void delegate() onHup; + int fd = -1; __gshared PosixFdReader[int] mapping; } From 3d922ec6c649992b00f820ac04aadeb23743c35f Mon Sep 17 00:00:00 2001 From: "Adam D. Ruppe" Date: Tue, 4 Dec 2018 12:00:57 -0500 Subject: [PATCH 2/4] oh dear bug city --- cgi.d | 5 +++++ http2.d | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/cgi.d b/cgi.d index a4d2bb1..66a9be5 100644 --- a/cgi.d +++ b/cgi.d @@ -2408,6 +2408,9 @@ struct Uri { if(idx > 0 && uri[idx] == ':') { scheme = uri[0 .. idx]; idx++; + } else { + // we need to rewind; it found a / but no :, so the whole thing is prolly a path... + idx = 0; } if(idx + 2 < uri.length && uri[idx .. idx + 2] == "//") { @@ -2545,6 +2548,8 @@ struct Uri { unittest { auto uri = Uri("test.html"); assert(uri.path == "test.html"); + uri = Uri("path/1/lol"); + assert(uri.path == "path/1/lol"); uri = Uri("http://me@example.com"); assert(uri.scheme == "http"); assert(uri.userinfo == "me"); diff --git a/http2.d b/http2.d index 8a7d39c..852da5e 100644 --- a/http2.d +++ b/http2.d @@ -365,6 +365,9 @@ struct Uri { if(idx > 0 && uri[idx] == ':') { scheme = uri[0 .. idx]; idx++; + } else { + // we need to rewind; it found a / but no :, so the whole thing is prolly a path... + idx = 0; } if(idx + 2 < uri.length && uri[idx .. idx + 2] == "//") { @@ -1641,7 +1644,13 @@ class HttpApiClient() { if(uri[0] == '/') uri = uri[1 .. $]; +import std.stdio; writeln(uri); +writeln(urlBase); + auto u = Uri(uri).basedOn(Uri(urlBase)); + + writeln(u.toString()); + auto req = httpClient.navigateTo(u, requestMethod); if(oauth2Token.length) @@ -1736,6 +1745,7 @@ class HttpApiClient() { result ~= "="; result ~= encodeComponent(part[1]); } + return result; } From c267be254e75815425992f7b35b4e2b50c1d99a7 Mon Sep 17 00:00:00 2001 From: "Adam D. Ruppe" Date: Tue, 4 Dec 2018 12:10:26 -0500 Subject: [PATCH 3/4] dedebug --- http2.d | 5 ----- 1 file changed, 5 deletions(-) diff --git a/http2.d b/http2.d index 852da5e..614781b 100644 --- a/http2.d +++ b/http2.d @@ -1644,13 +1644,8 @@ class HttpApiClient() { if(uri[0] == '/') uri = uri[1 .. $]; -import std.stdio; writeln(uri); -writeln(urlBase); - auto u = Uri(uri).basedOn(Uri(urlBase)); - writeln(u.toString()); - auto req = httpClient.navigateTo(u, requestMethod); if(oauth2Token.length) From 4df6a9b08b31391acf98841b06d0a22f1bf8008f Mon Sep 17 00:00:00 2001 From: Andre Polykanine Date: Tue, 4 Dec 2018 23:43:19 +0200 Subject: [PATCH 4/4] SQLite: Fix spelling typo --- sqlite.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sqlite.d b/sqlite.d index b205029..6efeb58 100644 --- a/sqlite.d +++ b/sqlite.d @@ -43,14 +43,14 @@ import std.conv; scope(exit)) */ -Sqlite openDBAndCreateIfNotPresent(string filename, string sql, void delegate(Sqlite db) initalize = null){ +Sqlite openDBAndCreateIfNotPresent(string filename, string sql, void delegate(Sqlite db) initialize = null){ if(exists(filename)) return new Sqlite(filename); else { auto db = new Sqlite(filename); db.exec(sql); - if(initalize !is null) - initalize(db); + if(initialize !is null) + initialize(db); return db; } }