/*@@ @file IO.c @date Sun Sep 17 16:19:17 2000 @author Tom Goodale @desc Stuff for displaying IO callbacks on the web page. @enddesc @version $Id$ @@*/ #include "cctk.h" #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "util_String.h" #include "CactusBase/IOUtil/src/ioutil_AdvertisedFiles.h" #include "CactusConnect/HTTPD/src/http_Request.h" #include "CactusConnect/HTTPD/src/http_Content.h" static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusConnect_HTTPDExtra_IO_c) /******************************************************************** ******************** Macro Definitions ************************ ********************************************************************/ #ifndef O_BINARY #define O_BINARY 0 #endif /******************************************************************** ********************* Internal Typedefs ********************** ********************************************************************/ struct httpuFileList { struct httpuFileList *next; char *filename; char *linkname; ioAdvertisedFileDesc data; }; struct httpuMimeType { struct httpuMimeType *next; const char *name; }; /******************************************************************** ******************** Internal Routines ************************ ********************************************************************/ static int IOFileListener(const cGH *GH, const char *filename, const ioAdvertisedFileDesc *description); static int AdvertisedFilePage(const cGH *GH, httpRequest *request, void *data); static int ViewportFilePage(const cGH *GH, httpRequest *request, void *data); static int SendFilePage(const cGH *GH, httpRequest *request, void *data); /******************************************************************** ******************** External Routines ************************ ********************************************************************/ int HTTP_util_RegisterIOPages(void); /******************************************************************** ********************* Local Data ***************************** ********************************************************************/ static struct httpuFileList *filelist = NULL; static struct httpuMimeType *mimetypes = NULL; /*@@ @routine HTTP_util_RegisterIOPages @date Wed Sep 14 11:29:43 2000 @author Gabrielle Allen @desc Registers HTTPDExtra's Output and ViewPort page. @enddesc @calls IOUtil_RegisterAdvertisedFileListener HTTP_RegisterPage HTTP_ContentLink @returntype int @returndesc 0 for success @endreturndesc @@*/ int HTTP_util_RegisterIOPages(void) { ioAdvertisedFileListenerCallbacks listener; listener.advertise = IOFileListener; IOUtil_RegisterAdvertisedFileListener (NULL, CCTK_THORNSTRING, &listener); HTTP_RegisterPage("/Output/index.html", AdvertisedFilePage, NULL); HTTP_RegisterPage("/Output/viewport.html", ViewportFilePage, NULL); HTTP_ContentLink("/Output/index.html", "Files", "Downloadable files", HTTP_QUICKLINK); HTTP_ContentLink("/Output/viewport.html", "Viewport", "Viewport for certain output files", HTTP_QUICKLINK); HTTP_RegisterPage("/Output", SendFilePage, NULL); return 0; } /******************************************************************** ******************** Internal Routines ************************ ********************************************************************/ /*@@ @routine IOFileListener @date Sun Sep 17 17:56:22 2000 @author Tom Goodale @desc Listener for advertised files. @enddesc @@*/ static int IOFileListener(const cGH *GH, const char *filename, const ioAdvertisedFileDesc *description) { struct httpuFileList *entry; struct httpuMimeType *type; char *position; /* avoid compiler warning about unused parameter */ (void) (GH + 0); entry = (struct httpuFileList *)malloc(sizeof(struct httpuFileList)); if(entry) { entry->next = NULL; entry->filename = Util_Strdup(filename); entry->linkname = Util_Strdup(filename); entry->data.thorn = Util_Strdup(description->thorn); entry->data.varname = Util_Strdup(description->varname); entry->data.mimetype = Util_Strdup(description->mimetype); entry->data.slice = Util_Strdup(description->slice); entry->data.description = Util_Strdup(description->description); entry->next = filelist; filelist = entry; /* Need to mangle the filename to get a decent linkname */ for(position=entry->linkname; *position;position++) { if(*position == '/') { *position = '@'; } } for(type=mimetypes; type; type=type->next) { if(!strcmp(type->name,entry->data.mimetype)) { break; } } /* Keep a list of mimetypes too. */ if(!type) { type = (struct httpuMimeType *)malloc(sizeof(struct httpuMimeType)); if(type) { type->name = Util_Strdup(description->mimetype); type->next = mimetypes; mimetypes = type; } } } return 0; } /*@@ @routine AdvertisedFilePage @date Sun Sep 17 18:26:01 2000 @author Tom Goodale @desc Page to deal with advertised files. @enddesc @@*/ static int AdvertisedFilePage(const cGH *GH, httpRequest *request, void *data) { int retval; char message[4098]; struct httpuFileList *list; /* avoid compiler warning about unused parameter */ data = data; /* 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, "Cactus Downloadable Files\n"); HTTP_Write(request, message, strlen(message)); /* HTTP_Write out the header part. */ HTTP_ContentHeader(GH, 0, 4098, message,NULL); HTTP_Write(request, message, strlen(message)); strcpy(message, "

Downloadable Files

"); HTTP_Write(request, message, strlen(message)); strcpy(message, "

From this page you can download various output files \n" "from the simulation. Depending on the software available on your" " local machine, you can change the browser properties to lauch" " files directly to visualization clients.

\n " "

Some of these output files can be directly viewed on " "a browser on the simulation " "viewport

" "

Many IO methods have steerable parameters which " "allow you to e.g. add fields and customise behaviour." "Depending on your authorisation, you can access the" " parameter steering page

" "
" "" "\n"); HTTP_Write(request, message, strlen(message)); for (list = filelist; list; list = list->next) { sprintf(message, "" "\n", list->linkname, list->filename, list->data.varname, list->data.description); HTTP_Write(request, message, strlen(message)); } strcpy(message,"
File NameVariableDescription
%s%s%s
"); HTTP_Write(request, message, strlen(message)); /* Write out the footer part. */ /* HTTP_Write out the footer part. */ HTTP_ContentFooter(GH, 0, 4098, message); retval = HTTP_Write(request, message, strlen(message)); return retval; } /*@@ @routine SendFilePage @date Sun Sep 17 18:43:40 2000 @author Tom Goodale @desc Sends an advertised file. @enddesc @@*/ static int SendFilePage(const cGH *GH, httpRequest *request, void *data) { char message[4098]; struct httpuFileList *list; int filedes; /* avoid compiler warning about unused parameters */ (void) (GH + 0); data = data; for (list = filelist; list; list = list->next) { if(!strcmp(list->linkname, request->residual)) { if((filedes = open(list->filename, O_RDONLY | O_BINARY)) >= 0) { strcpy(message,"HTTP/1.0 200 OK\r\n"); HTTP_Write(request, message, strlen(message)); /* Content-Type */ sprintf(message,"Content-Type: %s\r\n\r\n", list->data.mimetype); HTTP_Write(request, message, strlen(message)); HTTP_ContentSendFromFile(request, filedes); close(filedes); } else { strcpy(message,"HTTP/1.0 500 Server Internal Error\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)); sprintf(message, "\nError 500: Internal Error\n" "

Unable to open %s

\n\n", list->filename); HTTP_Write(request, message, strlen(message)); } break; } } if(!list) { strcpy(message,"HTTP/1.0 404 Not Found\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)); sprintf(message, "\nError 404: Not Found\n" "

%s does not exist

\n\n", request->uri); HTTP_Write(request, message, strlen(message)); } return 0; } /*@@ @routine AdvertisedFilePage @date Sun Sep 17 18:26:01 2000 @author Tom Goodale @desc Page to deal with advertised files. @enddesc @@*/ static int ViewportFilePage(const cGH *GH, httpRequest *request, void *data) { int retval; int foundone; char message[4098]; struct httpuFileList *list; /* avoid compiler warning about unused parameters */ (void) (GH + 0); data = data; /* 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, "Cactus Downloadable Files\n"); HTTP_Write(request, message, strlen(message)); /* HTTP_Write out the header part. */ HTTP_ContentHeader(GH, 0, 4098, message,NULL); HTTP_Write(request, message, strlen(message)); strcpy(message, "

Viewport

"); HTTP_Write(request, message, strlen(message)); strcpy(message, "

This page displays certain types of the output files " "from the download page" " as images (currently only jpegs [mime type image/jpeg]).

" "

Many IO methods have steerable parameters which " "allow you to e.g. add fields and customise behaviour." "Depending on your authorisation, you can access the" " parameter steering page

"); HTTP_Write(request, message, strlen(message)); foundone = 0; for (list = filelist; list; list = list->next) { if (CCTK_Equals(list->data.mimetype,"image/jpeg")) { if (!foundone) { strcpy(message, "
" "" "\n" "\n"); HTTP_Write(request, message, strlen(message)); foundone = 1; } sprintf(message, "\n" "\n" "\n" "\n" "\n", list->data.varname,list->linkname, list->filename, list->data.description,list->linkname,list->linkname); HTTP_Write(request, message, strlen(message)); } } if (!foundone) { strcpy(message,"

No viewable images registered!

" "
\n"); HTTP_Write(request, message, strlen(message)); } strcpy(message,"
Variable
File Name
DescriptionImage
%s
\n" "%s\n" "
%s
\n
\n"); HTTP_Write(request, message, strlen(message)); /* Write out the footer part. */ HTTP_ContentFooter(GH, 0, 4098, message); retval = HTTP_Write(request, message, strlen(message)); return retval; }