From 3911e5fe8ce0a87db2fbab4795bc03da5fe12556 Mon Sep 17 00:00:00 2001 From: goodale Date: Sun, 17 Sep 2000 13:02:27 +0000 Subject: Added authentification for setting parameters and a control page. Unless one has previously authenticated by going to /control.html all paramters are read only. The default username and password are both "anon". I also added a hack so these don't get displayed on the web page - this should go away when we have parameter tags. Added http_Content.h which currently contains a function for registering a link to be displayed elsewhere. It takes the URL, the link name, a longer description line, and a flag. Currently the flag should be set to HTTP_QUICKLINK to get things displayed on the quicklinks on some pages. Still need to add a function which will allow other thorns access to this data. Tom git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/HTTPD/trunk@35 1faa4e14-9dd3-4be0-9f0e-ffe519881164 --- src/Content.c | 582 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 519 insertions(+), 63 deletions(-) (limited to 'src/Content.c') diff --git a/src/Content.c b/src/Content.c index c423d64..993747a 100644 --- a/src/Content.c +++ b/src/Content.c @@ -27,7 +27,10 @@ #include "http_Auth.h" #include "http_Steer.h" +#include "http_Content.h" + #include "cctk_Arguments.h" +#include "cctk_Parameters.h" static char *rcsid = "$Header$"; @@ -44,6 +47,15 @@ struct httpStaticPage char *mime_type; }; +struct httpLink +{ + struct httpLink *next; + char *URL; + char *name; + char *description; + int flags; +}; + /******************************************************************** ********************* Local Routine Prototypes ********************* ********************************************************************/ @@ -57,10 +69,12 @@ static int ThornParameterPage(cGH *cctkGH, httpRequest *request, void *data); static int ShowStaticPage(cGH *cctkGH, httpRequest *request, void *data); -static int AuthPage(cGH *cctkGH, httpRequest *request, void *data); - static int CompareStrings(const void *string1, const void *string2); +static int ControlPage(cGH *cctkGH, httpRequest *request, void *data); +static int ControlSet(cGH *cctkGH, httpRequest *request); +static int ControlTerminationPage(cGH *cctkGH, httpRequest *request); + /******************************************************************** ********************* Other Routine Prototypes ********************* ********************************************************************/ @@ -69,6 +83,8 @@ static int CompareStrings(const void *string1, const void *string2); ********************* Local Data ***************************** ********************************************************************/ +static struct httpLink *ContentLinks = NULL; + /******************************************************************** ********************* External Routines ********************** ********************************************************************/ @@ -110,6 +126,7 @@ void HTTP_ContentWork(CCTK_ARGUMENTS) @@*/ int HTTP_RegisterPages(void) { + DECLARE_CCTK_PARAMETERS #ifdef HTTP_DEBUG printf("Registering index.html\n"); #endif @@ -121,16 +138,78 @@ int HTTP_RegisterPages(void) RegisterParameterPages(); - /* Register a test authentication page. */ + /* Register parameter control stuff. */ + + HTTP_RegisterPage("/control.html", ControlPage, NULL); - HTTP_RegisterPage("/auth_page", AuthPage, NULL); + HTTP_ContentLink("/control.html", "Cactus Control", + "Control Panel for this run", + HTTP_QUICKLINK); - HTTP_AuthAddUser("user","goodale","foo","none"); + HTTP_AuthAddUser("user",user,password,encryption_scheme); /* Register images */ RegisterImages(); } + /*@@ + @routine HTTP_ContentLink + @date Sun Sep 17 13:17:56 2000 + @author Tom Goodale + @desc + Register content links. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +int HTTP_ContentLink(const char *URL, + const char *name, + const char *description, + int flags) +{ + int retval; + struct httpLink *link; + struct httpLink *last; + struct httpLink *current; + + link = (struct httpLink *)malloc(sizeof(struct httpLink)); + + if(link) + { + link->URL = Util_Strdup(URL); + link->name = Util_Strdup(name); + link->description = Util_Strdup(description); + link->flags = flags; + link->next = NULL; + + /* Put on list */ + if(ContentLinks) + { + for(current=ContentLinks; current; current = current->next) + { + last = current; + } + last->next = link; + } + else + { + ContentLinks = link; + } + + retval = 0; + } + else + { + retval = -1; + } + + return retval; +} + /******************************************************************** ********************* Local Routines ************************* ********************************************************************/ @@ -212,6 +291,7 @@ static int MainPage(cGH *cctkGH, httpRequest *request, void *data) { int retval; char message[4098]; + struct httpLink *link; /* Status message */ strcpy(message,"HTTP/1.0 200 OK\r\n"); @@ -231,6 +311,30 @@ static int MainPage(cGH *cctkGH, httpRequest *request, void *data) /* Write out the main header part */ HTTP_Write(request, cactus_mainheader, strlen(cactus_mainheader)); + strcpy(message, "

Simulation Home Page

"); + + /* ADD QUICK LINKS (e.g. FOR PALM) */ + + if(ContentLinks) + { + strcpy(message, "
Quick links: "); + + for(link = ContentLinks; link; link=link->next) + { + if(link->flags & HTTP_QUICKLINK) + { + sprintf(message, + "%s[%s]", + message, + link->URL, + link->name); + } + } + strcat(message,"
\n
\n"); + HTTP_Write(request, message, strlen(message)); + } + + /* Some blurb */ strcpy(message, "
" "
\n", thorn); - HTTP_Write(request, message, strlen(message)); - + if(!readonly) + { + sprintf(message,"\n", thorn); + HTTP_Write(request, message, strlen(message)); + } + /* Walk through all parameters of given implementation. */ first = 1; @@ -614,7 +777,7 @@ static int ThornParameterPage(cGH *cctkGH, httpRequest *request, void *data) prefix = CCTK_ThornImplementation (pData->thorn); } - if (pData->steerable == CCTK_STEERABLE_ALWAYS) + if (pData->steerable == CCTK_STEERABLE_ALWAYS && !readonly) { sprintf(message, "%s" @@ -624,10 +787,17 @@ static int ThornParameterPage(cGH *cctkGH, httpRequest *request, void *data) } else { - sprintf(message, - "%s" - "\n", - message, prefix,pData->name, value); + /* FIXME: This is a hack - should put in parameter tags. */ + if(strcmp(thorn,CCTK_THORNSTRING) || + (strcmp(pData->name,"user") && + strcmp(pData->name,"password") && + strcmp(pData->name,"encryption_scheme"))) + { + sprintf(message, + "%s" + "\n", + message, prefix,pData->name, value); + } } free (value); } @@ -635,10 +805,15 @@ static int ThornParameterPage(cGH *cctkGH, httpRequest *request, void *data) } - strcpy(message, - "\n" - "
" @@ -373,6 +477,10 @@ static int RegisterParameterPages(void) HTTP_RegisterPage("/Parameters/index.html", MainParameterPage, NULL); + HTTP_ContentLink("/Parameters/index.html", "Parameters", + "Parameter Informatiiona and Control", + HTTP_QUICKLINK); + for (i = 0; i < CCTK_NumCompiledThorns (); i++) { thorn = CCTK_CompiledThorn(i); @@ -475,6 +583,10 @@ static int MainParameterPage(cGH *cctkGH, httpRequest *request, void *data) return retval; } +static const char *notauthorized_page = +"\nError 401: Not Authorized\ +You are not authorized to access this page\n\n"; + /*@@ @routine ThornParameterPage @date Sat Sep 16 15:13:55 2000 @@ -509,37 +621,85 @@ static int ThornParameterPage(cGH *cctkGH, httpRequest *request, void *data) const char *prefix; const httpArg *argument; + int notauthorised; + int readonly; + thorn = (const char *)data; + notauthorised = HTTP_AuthenticateBasic(request, "user"); + + readonly = notauthorised; + if(request->n_arguments > 0) { /* This is a parameter set request */ - /* Queue parameters for steering */ - first = 1; - while(argument = HTTP_ArgumentWalk(request, first)) + if(!notauthorised) { - first = 0; - fprintf(stderr, "Setting %s::%s to %s\n", thorn, argument->arg, argument->value); - HTTP_SteerQueue(thorn, argument->arg, argument->value); - } + if(!readonly) + { + /* Queue parameters for steering */ + first = 1; + while(argument = HTTP_ArgumentWalk(request, first)) + { + first = 0; + fprintf(stderr, "Setting %s::%s to %s\n", thorn, argument->arg, argument->value); + HTTP_SteerQueue(thorn, argument->arg, argument->value); + } + + /* Now redirect the browser to the normal page */ + /* Status message */ + if(request->http_major_version < 1 || + (request->http_major_version == 1 && request->http_minor_version < 1)) + { + /* Older browsers don't understand 303 */ + strcpy(message,"HTTP/1.0 302 Found\r\n"); + } + else + { + strcpy(message,"HTTP/1.0 303 See Other\r\n"); + } - /* Now redirect the browser to the normal page */ - /* Status message */ - if(request->http_major_version < 1 || - (request->http_major_version == 1 && request->http_minor_version < 1)) - { - /* Older browsers don't understand 303 */ - strcpy(message,"HTTP/1.0 302 Found\r\n"); + sprintf(message, "%sLocation: /Parameters/%s/\r\n\r\n", message, thorn); + + HTTP_Write(request, message, strlen(message)); + } + else + { + /* Redirect the browser to the normal page */ + /* Status message */ + if(request->http_major_version < 1 || + (request->http_major_version == 1 && request->http_minor_version < 1)) + { + /* Older browsers don't understand 303 */ + strcpy(message,"HTTP/1.0 302 Found\r\n"); + } + else + { + strcpy(message,"HTTP/1.0 303 See Other\r\n"); + } + + sprintf(message, "%sLocation: /Parameters/%s/\r\n\r\n", message, thorn); + + HTTP_Write(request, message, strlen(message)); + } } else { - strcpy(message,"HTTP/1.0 303 See Other\r\n"); - } - - sprintf(message, "%sLocation: /Parameters/%s/\r\n\r\n", message, thorn); + strcpy(message,"HTTP/1.0 401 Unauthorized\r\n"); + + HTTP_Write(request, message, strlen(message)); - HTTP_Write(request, message, strlen(message)); + strcpy(message,"WWW-Authenticate: Basic realm=\"foo\"\r\n"); + + HTTP_Write(request, message, strlen(message)); + + strcpy(message,"Content-Type: text/html\r\n\r\n"); + + HTTP_Write(request, message, strlen(message)); + + HTTP_Write(request, notauthorized_page, strlen(notauthorized_page)); + } } else @@ -591,9 +751,12 @@ static int ThornParameterPage(cGH *cctkGH, httpRequest *request, void *data) HTTP_Write(request, message, strlen(message)); - sprintf(message,"
%s::%s
%s::%s%s
%s::%s%s

\n" - "\n"); + if(!readonly) + { + strcpy(message, + "\n" + "\n"); + HTTP_Write(request, message, strlen(message)); + } + + strcpy(message, "

\n"); HTTP_Write(request, message, strlen(message)); } @@ -744,25 +919,12 @@ static int ShowStaticPage(cGH *cctkGH, httpRequest *request, void *data) } -/****************************************************************************** - ********************** Authentication test page ****************************** - ******************************************************************************/ - - -static const char *notauthorized_page = -"\nError 401: Not Authorized\ -You are not authorized to access this page\n\n"; - -static const char *authorized_page = -"\nAuthorized\ -Congratulations !\n\n"; - /*@@ - @routine AuthPage - @date Fri Sep 15 12:52:37 2000 + @routine ControlPage + @date Sun Sep 17 14:37:59 2000 @author Tom Goodale @desc - Test page for authentication. + Cactus Control Panel @enddesc @calls @calledby @@ -771,38 +933,113 @@ static const char *authorized_page = @endhistory @@*/ -static int AuthPage(cGH *cctkGH, httpRequest *request, void *data) +static int ControlPage(cGH *cctkGH, httpRequest *request, void *data) { + DECLARE_CCTK_PARAMETERS + int retval; - char message[1024]; + char message[4096]; int notauthorised; + struct httpLink *link; notauthorised = HTTP_AuthenticateBasic(request, "user"); if(!notauthorised) { - strcpy(message,"HTTP/1.0 200 Ok\r\n"); + /* Ok the person is authorised. */ + if(request->n_arguments == 0) + { + /* No arguments, so just display the page */ + strcpy(message,"HTTP/1.0 200 Ok\r\n"); - HTTP_Write(request, message, strlen(message)); + HTTP_Write(request, message, strlen(message)); - strcpy(message,"WWW-Authenticate: Basic realm=\"foo\"\r\n"); + strcpy(message,"WWW-Authenticate: Basic realm=\"Cactus Control\"\r\n"); - HTTP_Write(request, message, strlen(message)); + HTTP_Write(request, message, strlen(message)); - strcpy(message,"Content-Type: text/html\r\n\r\n"); + strcpy(message,"Content-Type: text/html\r\n\r\n"); - HTTP_Write(request, message, strlen(message)); - - HTTP_Write(request, authorized_page, strlen(authorized_page)); + HTTP_Write(request, message, strlen(message)); + + /* Start the page */ + strcpy(message, "Cactus Control and Status Page\n"); + strcat(message, cactus_mainheader); + strcat(message, "

Simulation Home Page

"); + + HTTP_Write(request, message, strlen(message)); + + if(ContentLinks) + { + strcpy(message, "
Quick links: "); + + for(link = ContentLinks; link; link=link->next) + { + if(link->flags & HTTP_QUICKLINK) + { + sprintf(message, + "%s[%s]", + message, + link->URL, + link->name); + } + } + strcat(message,"
\n
\n"); + + HTTP_Write(request, message, strlen(message)); + } + + strcpy(message, + "
\n" + "
\n" + "\n" + "\n"); + HTTP_Write(request, message, strlen(message)); + + sprintf(message, + "\n", + pause ? "checked" : ""); + HTTP_Write(request, message, strlen(message)); + + sprintf(message, + "\n", + pause ? "" : "checked"); + HTTP_Write(request, message, strlen(message)); + + strcpy(message, + "\n"); + HTTP_Write(request, message, strlen(message)); + + strcpy(message, + "
PAUSE
RUN
TERMINATE
\n" + "\n" + "\n" + "\n" + "
\n" + "
\n" + "
\n"); + + HTTP_Write(request, message, strlen(message)); + + /* Write out the footer part. */ + + retval = HTTP_Write(request, cactus_footer, strlen(cactus_footer)); + } + else + { + /* Arguments, so control simulation */ + ControlSet(cctkGH, request); + } } else { + /* Not authorised */ strcpy(message,"HTTP/1.0 401 Unauthorized\r\n"); HTTP_Write(request, message, strlen(message)); - strcpy(message,"WWW-Authenticate: Basic realm=\"foo\"\r\n"); + strcpy(message,"WWW-Authenticate: Basic realm=\"Cactus Control\"\r\n"); HTTP_Write(request, message, strlen(message)); @@ -813,5 +1050,224 @@ static int AuthPage(cGH *cctkGH, httpRequest *request, void *data) HTTP_Write(request, notauthorized_page, strlen(notauthorized_page)); } + return 0; } + + /*@@ + @routine ControlSet + @date Sun Sep 17 14:39:50 2000 + @author Tom Goodale + @desc + Set the status of the simulation based on the controls. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +static int ControlSet(cGH *cctkGH, httpRequest *request) +{ + char message[4096]; + const char *runstate; + + runstate = HTTP_ArgumentValue(request,"runstate"); + + switch(*runstate) + { + case 'T' : HTTP_SteerQueue(CCTK_THORNSTRING, "terminate", "yes"); + ControlTerminationPage(cctkGH, request); + break; + case 'P' : HTTP_SteerQueue(CCTK_THORNSTRING, "pause", "yes"); + break; + case 'R' : HTTP_SteerQueue(CCTK_THORNSTRING, "pause", "no"); + break; + default : + fprintf(stderr, "Unknown runstate '%s'\n", runstate); + } + + /* Now redirect the browser to the normal page */ + /* Status message */ + if(request->http_major_version < 1 || + (request->http_major_version == 1 && request->http_minor_version < 1)) + { + /* Older browsers don't understand 303 */ + strcpy(message,"HTTP/1.0 302 Found\r\n"); + } + else + { + strcpy(message,"HTTP/1.0 303 See Other\r\n"); + } + + sprintf(message, "%sLocation: /control.html/\r\n\r\n", message); + + HTTP_Write(request, message, strlen(message)); + + return 0; +} + + /*@@ + @routine ControlTerminationPage + @date Sun Sep 17 14:40:16 2000 + @author Tom Goodale + @desc + Page to be shown on termination of Cactus. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +static int ControlTerminationPage(cGH *cctkGH, httpRequest *request) +{ + int retval; + char message[4096]; + + /* Status message */ + strcpy(message,"HTTP/1.0 200 OK\r\n"); + + HTTP_Write(request, message, strlen(message)); + + /* Content-Type */ + strcpy(message,"Content-Type: text/html\r\n\r\n"); + + HTTP_Write(request, message, strlen(message)); + + /* Start the page */ + strcpy(message,"Running CACTUS Status Information : Terminated\n"); + + HTTP_Write(request, message, strlen(message)); + + /* Write out the main header part */ + HTTP_Write(request, cactus_mainheader, strlen(cactus_mainheader)); + + strcpy(message, "

Simulation Home Page

"); + + HTTP_Write(request, message, strlen(message)); + + /* Some blurb */ + strcpy(message, "
" + "
" + "

Simulation web server:

" + "

This browser is connected to a Cactus simulation which contains " + "a web server thorn. This thorn allows you to monitor the simulation, " + "and view and change parameters

" + "

Depending on which other thorns are active, there may be additional " + "features available, such as the viewing and downloading of output files

"); + + HTTP_Write(request, message, strlen(message)); + + + /* CONFIGURATION DETAILS */ + + sprintf(message, "

Configuration:

" + "
  • Flesh version %s" + "
  • \n" + "
  • Code compiled on " + __DATE__ " at "__TIME__ "
  • \n" + "
", CCTK_FullVersion()); + + HTTP_Write(request, message, strlen(message)); + + /******************************************************************************/ + + /* NEW COLUMN */ + + strcpy(message, "
"); + + HTTP_Write(request, message, strlen(message)); + + /*******************************************************************************/ + + /* CURRENT STATE OF SIMULATION */ + + if (cctkGH) + { + + sprintf(message, "

Current state:

" + "
  • Physical time %f" + " \n" + "
  • Iteration number %d" + "
  • \n", + cctkGH->cctk_time, + cctkGH->cctk_iteration); + + } + else + { + strcpy(message, "
  • Current cactus time is unknown
  • \n"); + } + + HTTP_Write(request, message, strlen(message)); + + strcpy(message, "
  • This Cactus run is over.
  • \n"); + + HTTP_Write(request, message, strlen(message)); + + strcpy(message, "
"); + + HTTP_Write(request, message, strlen(message)); + + /* LIST COMPILED THORNS */ + + { + int i; + int nthorns; + const char **thorns; + + nthorns = CCTK_NumCompiledThorns(); + + thorns = (const char **)malloc(nthorns * sizeof(char *)); + + for(i=0; i < nthorns; i++) + { + thorns[i] = CCTK_CompiledThorn (i); + } + + /* Sort the thorns */ + qsort(thorns, nthorns, sizeof(char *), CompareStrings); + + strcpy(message, "

Compiled thorns:

" + "

This list shows all thorns compiled into the executable, " + "those thorns which have been activated in the parameter " + "file for this simulation are shown in " + "red

" + "
    "); + + for(i=0; i < nthorns; i++) + { + strcat(message, "
  • "); + if (CCTK_IsThornActive(thorns[i])) + { + sprintf(message,"%s %s \n", message, thorns[i]); + } + else + { + strcat(message, thorns[i]); + } + } + strcat(message, "
"); + + free(thorns); + } + + HTTP_Write(request, message, strlen(message)); + + + /* Finish table started by blurb */ + strcpy(message, "
"); + + HTTP_Write(request, message, strlen(message)); + + /* Write out the footer part. */ + + retval = HTTP_Write(request, cactus_footer, strlen(cactus_footer)); + + /* retval = HTTP_Write(request, base_page, strlen(base_page)); */ + + return retval; +} -- cgit v1.2.3