/*@@ @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 $Header$ @@*/ #include "cctk.h" #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 char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusConnect_HTTPDExtra_IO_c) /******************************************************************** ********************* Local Data Types *********************** ********************************************************************/ struct httpuFileList { struct httpuFileList *next; char *filename; char *linkname; ioAdvertisedFileDesc data; }; struct httpuMimeType { struct httpuMimeType *next; const char *name; }; /******************************************************************** ********************* Local Routine Prototypes ********************* ********************************************************************/ static int IOFileListener(cGH *GH, const char *filename, const ioAdvertisedFileDesc *description); static int AdvertisedFilePage(cGH *cctkGH, httpRequest *request, void *data); static int ViewportFilePage(cGH *cctkGH, httpRequest *request, void *data); static int SendFilePage(cGH *cctkGH, httpRequest *request, void *data); /******************************************************************** ********************* Other Routine Prototypes ********************* ********************************************************************/ /******************************************************************** ********************* Local Data ***************************** ********************************************************************/ static struct httpuFileList *filelist = NULL; static struct httpuMimeType *mimetypes = NULL; #ifndef O_BINARY #define O_BINARY 0 #endif /******************************************************************** ********************* External Routines ********************** ********************************************************************/ 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; } /******************************************************************** ********************* Local Routines ************************* ********************************************************************/ /*@@ @routine IOFileListener @date Sun Sep 17 17:56:22 2000 @author Tom Goodale @desc Listener for advertised files. @enddesc @calls @calledby @history @endhistory @@*/ static int IOFileListener(cGH *GH, const char *filename, const ioAdvertisedFileDesc *description) { struct httpuFileList *entry; struct httpuMimeType *type; char *position; 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 @calls @calledby @history @endhistory @@*/ static int AdvertisedFilePage(cGH *cctkGH, httpRequest *request, void *data) { int retval; char message[4098]; struct httpuFileList *list; /* 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(cctkGH, 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(cctkGH, 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 @calls @calledby @history @endhistory @@*/ static int SendFilePage(cGH *cctkGH, httpRequest *request, void *data) { int retval; char message[4098]; struct httpuFileList *list; int filedes; 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 @calls @calledby @history @endhistory @@*/ static int ViewportFilePage(cGH *cctkGH, httpRequest *request, void *data) { int retval; int foundone; char message[4098]; struct httpuFileList *list; /* 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(cctkGH, 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); 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(cctkGH, 0, 4098, message); retval = HTTP_Write(request, message, strlen(message)); return retval; }