From b64c2805b65538c7ad9a8b373e00060bbe453b8c Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sun, 23 Dec 2007 10:13:12 +0000 Subject: [PATCH] The web interface now automaticallty figures out its own URL, so this need no longer be specified in the configuration file. It is still available as an override (for instance to turn http://domain/index.cgi back into http://domain). Organization: Straylight/Edgeware From: rjk@greenend.org.uk <> --- CHANGES | 4 +++- README | 10 +++------- doc/disorder_config.5.in | 3 ++- lib/configuration.h | 2 +- server/cgimain.c | 42 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 3268dc4..d558d9d 100644 --- a/CHANGES +++ b/CHANGES @@ -9,7 +9,9 @@ Users are now stored in the database rather than a configuration file. ** Web Interface The web interface now uses cookies to remember user identity, and allows -online registration of new users. +online registration of new users. Also it is no longer necessary to +manually specify the URL of the web interface (but you can override it +if you don't like the value it figures out). * Changes up to version 2.0 diff --git a/README b/README index e62945d..19a9a72 100644 --- a/README +++ b/README @@ -221,19 +221,15 @@ You need to configure a number of things to make this work: install -m 755 clients/disorder.cgi ~jukebox/public_html/index.cgi -4. The config file must list the URL of the web interface explicitly: - - url http://jukebox.DOMAIN/ - -5. Try it out. You should be able to perform read-only operations straight +4. Try it out. You should be able to perform read-only operations straight away, and after visiting the 'Login' page to authenticate, perform other operations like adding a track to the queue. -6. If you run into problems, always look at the appropriate error log; the +5. If you run into problems, always look at the appropriate error log; the message you see in your web browser will usually not be sufficient to diagnose the problem all by itself. -7. If you have a huge number of top level directories, then you might find +6. If you have a huge number of top level directories, then you might find that the 'Choose' page is unreasonably large. If so add the following line to /etc/disorder/options.user: label sidebar.choosewhich choosealpha diff --git a/doc/disorder_config.5.in b/doc/disorder_config.5.in index 34cda6e..269abe8 100644 --- a/doc/disorder_config.5.in +++ b/doc/disorder_config.5.in @@ -636,7 +636,8 @@ transform dir "[[:punct:]]" "" sort g .TP .B url \fIURL\fR Specifies the URL of the web interface. This URL will be used in -generated web pages. +generated web pages. The default is inferred at runtime, so this option no +longer needs to be specified. .IP This must be the full URL, e.g. \fBhttp://myhost/cgi-bin/jukebox\fR and not \fB/cgi-bin/jukebox\fR. diff --git a/lib/configuration.h b/lib/configuration.h index 11e3487..abb95a6 100644 --- a/lib/configuration.h +++ b/lib/configuration.h @@ -205,7 +205,7 @@ struct config { struct stringlist templates; /** @brief Canonical URL of web interface */ - const char *url; + char *url; /** @brief Short display limit */ long short_display; diff --git a/server/cgimain.c b/server/cgimain.c index 61f808f..5acf9ea 100644 --- a/server/cgimain.c +++ b/server/cgimain.c @@ -40,6 +40,44 @@ #include "disorder.h" #include "api-client.h" #include "mime.h" +#include "printf.h" + +/** @brief Infer the base URL for the web interface if it's not set + * + * See RFC 3875. + */ +static void infer_url(void) { + if(!config->url) { + const char *scheme = "http", *server, *script, *e; + int port; + + /* Figure out the server. 'MUST' be set and we don't cope if it + * is not. */ + if(!(server = getenv("SERVER_NAME"))) + fatal(0, "SERVER_NAME is not set"); + server = xstrdup(server); + + /* Figure out the port. 'MUST' be set but we cope if it is not. */ + if((e = getenv("SERVER_PORT"))) + port = atoi(e); + else + port = 80; + + /* Figure out path to ourselves */ + if(!(script = getenv("SCRIPT_NAME"))) + fatal(0, "SCRIPT_NAME is not set"); + if(script[0] != '/') + fatal(0, "SCRIPT_NAME does not start with a '/'"); + script = xstrdup(script); + + if(port == 80) + byte_xasprintf(&config->url, "%s://%s%s", + scheme, server, script); + else + byte_xasprintf(&config->url, "%s://%s:%d%s", + scheme, server, port, script); + } +} int main(int argc, char **argv) { const char *cookie_env, *conf; @@ -54,12 +92,13 @@ int main(int argc, char **argv) { if((conf = getenv("DISORDER_CONFIG"))) configfile = xstrdup(conf); if(getenv("DISORDER_DEBUG")) debugging = 1; if(config_read(0)) exit(EXIT_FAILURE); + infer_url(); memset(&g, 0, sizeof g); memset(&s, 0, sizeof s); s.g = &g; g.client = disorder_get_client(); output.quote = 1; - output.sink = sink_stdio("stdout", stdout); + output.sink = sink_stdio("stdout", stdout); /* See if there's a cookie */ cookie_env = getenv("HTTP_COOKIE"); if(cookie_env) { @@ -77,6 +116,7 @@ int main(int argc, char **argv) { disorder_cgi_error(&output, &s, "connect"); return 0; } + /* TODO RFC 3875 s8.2 recommendations e.g. concerning PATH_INFO */ disorder_cgi(&output, &s); if(fclose(stdout) < 0) fatal(errno, "error closing stdout"); return 0; -- [mdw]