Sync
authorAndrew McNab <andrew.mcnab@manchester.ac.uk>
Wed, 13 Jun 2007 13:58:30 +0000 (13:58 +0000)
committerAndrew McNab <andrew.mcnab@manchester.ac.uk>
Wed, 13 Jun 2007 13:58:30 +0000 (13:58 +0000)
org.gridsite.core/src/Makefile
org.gridsite.core/src/gridsite-storage.c [new file with mode: 0644]
org.gridsite.core/src/make-gridsite-spec
org.gridsite.core/src/mod_gridsite.c

index c05f731..7aec7ec 100644 (file)
@@ -63,7 +63,7 @@ endif
 #
 
 build: apidoc build-lib \
-       htcp gridsite-copy.cgi mod_gridsite.so \
+       htcp gridsite-copy.cgi gridsite-storage.cgi mod_gridsite.so \
        urlencode findproxyfile gsexec real-gridsite-admin.cgi
 
 build-lib: libgridsite_globus.so.$(VERSION) libgridsite_globus.a \
@@ -325,9 +325,9 @@ gsoap-test: gsoap-test.c
             $(STDSOAP2) -L$(GRIDSITEDIR)/lib \
             -lgsoapssl -lz -lssl -lcrypto -lxml2 -lm
         
-gridsite-srm.cgi: gridsite-srm.c libgridsite.so.$(VERSION)
-       gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-srm.cgi \
-            gridsite-srm.c \
+gridsite-storage.cgi: gridsite-storage.c libgridsite.so.$(VERSION)
+       gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-storage.cgi \
+            gridsite-storage.c \
             -I/usr/kerberos/include -I.\
             -I$(GRIDSITEDIR)/include \
             -DVERSION=\"$(VERSION)\" -L. \
@@ -355,6 +355,7 @@ install: apidoc install-lib
        cp -f findproxyfile $(prefix)/bin
        cp -f real-gridsite-admin.cgi $(prefix)/sbin
        cp -f gridsite-copy.cgi $(prefix)/sbin
+       cp -f gridsite-storage.cgi $(prefix)/sbin
        cp -f ../CHANGES ../README ../INSTALL ../LICENSE ../VERSION \
                $(prefix)/share/doc/gridsite-$(MINOR_VERSION)
        cp -f ../doc/index.html ../doc/*.conf ../doc/*.sh ../doc/*.spec \
@@ -453,7 +454,8 @@ dist:
        cp -f Makefile grst*.c htcp.c slashgrid.c slashgrid.init \
                  urlencode.c findproxyfile.c gaclexample.c mod_gridsite*.c \
                  htproxyput.c grst_admin.h mod_ssl-private.h \
-                 gsexec.c gsexec.h gridsite-copy.c delegation.h \
+                 gsexec.c gsexec.h gridsite-copy.c gridsite-storage.c \
+                 delegation.h \
                  roffit make-gridsite-spec \
                  Doxyfile doxygen.css doxyheader.html \
                  ../dist/gridsite-$(PATCH_VERSION)/src
diff --git a/org.gridsite.core/src/gridsite-storage.c b/org.gridsite.core/src/gridsite-storage.c
new file mode 100644 (file)
index 0000000..be7ba5f
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+   Copyright (c) 2002-6, Andrew McNab, University of Manchester
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or
+   without modification, are permitted provided that the following
+   conditions are met:
+
+     o Redistributions of source code must retain the above
+       copyright notice, this list of conditions and the following
+       disclaimer. 
+     o Redistributions in binary form must reproduce the above
+       copyright notice, this list of conditions and the following
+       disclaimer in the documentation and/or other materials
+       provided with the distribution. 
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+   POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*---------------------------------------------------------------*
+ * For more about GridSite: http://www.gridsite.org/             *
+ *---------------------------------------------------------------*/
+
+#ifndef VERSION
+#define VERSION "0.0.0"
+#endif
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <malloc.h>
+#include <dirent.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <curl/curl.h>
+
+#include "gridsite.h"
+#define HTCP_SITECAST_GROUPS 32
+
+struct grst_sitecast_group { unsigned char quad1; unsigned char quad2; 
+                             unsigned char quad3; unsigned char quad4;
+                             int port; int timewait; int ttl; }
+                           sitecast_groups[HTCP_SITECAST_GROUPS];
+int last_group;
+
+void handle_sitecast_get(void)
+{
+  int request_length, response_length, i, ret, s;
+  struct sockaddr_in srv, from;
+  socklen_t fromlen;
+#define MAXBUF 8192  
+  char *https, *server_port, *request_uri, *url, *sitecast_port,
+       *sitecast_domain, *request, response[MAXBUF], *p, *groups;
+  GRSThtcpMessage msg;
+  struct timeval start_timeval, wait_timeval;
+  fd_set readsckts;
+
+  sitecast_domain = getenv("GRIDSITE_SRM_DOMAIN");
+  if (sitecast_domain == NULL)
+    {
+      puts("Status: 500 Internal Server Error\n"
+           "Content-Type: text/plain\n\n"
+           "No GRIDSITE_SRM_DOMAIN defined");
+      return;
+    }  
+
+  sitecast_port = getenv("GRIDSITE_SRM_PORT");
+  if (sitecast_port == NULL)
+    {
+      puts("Status: 500 Internal Server Error\n"
+           "Content-Type: text/plain\n\n"
+           "No GRIDSITE_SRM_PORT defined");
+      return;
+    }  
+
+  request_uri = getenv("REQUEST_URI");
+  https = getenv("HTTPS");
+  
+  if (request_uri == NULL)
+    {
+      puts("Status: 500 Internal Server Error\n"
+           "Content-Type: text/plain\n\n"
+           "REQUEST_URI not found");
+      return;
+    }
+  
+  if (https == NULL) asprintf(&url,  "http://%s:%s%s", 
+                              sitecast_domain, sitecast_port, request_uri);
+  else asprintf(&url, "https://%s:%s%s",
+                sitecast_domain, sitecast_port, request_uri);
+  
+  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
+    {
+      puts("Status: 500 Internal Server Error\n"
+           "Content-Type: text/plain\n\n"
+           "Failed to open UDP socket");
+      return;
+    }
+
+  /* loop through multicast groups since we need to take each 
+     ones timewait into account */
+
+  gettimeofday(&start_timeval, NULL);
+
+  for (i=0; i <= last_group; ++i)
+     {
+/*
+       if (verbose)
+        fprintf(stderr, "Querying multicast group %d.%d.%d.%d:%d:%d:%d\n",
+                sitecast_groups[i].quad1, sitecast_groups[i].quad2,
+                sitecast_groups[i].quad3, sitecast_groups[i].quad4,
+                sitecast_groups[i].port, sitecast_groups[i].ttl,
+                sitecast_groups[i].timewait);
+*/      
+       bzero(&srv, sizeof(srv));
+       srv.sin_family = AF_INET;
+       srv.sin_port = htons(sitecast_groups[i].port);
+       srv.sin_addr.s_addr = htonl(sitecast_groups[i].quad1*0x1000000
+                                 + sitecast_groups[i].quad2*0x10000
+                                 + sitecast_groups[i].quad3*0x100
+                                 + sitecast_groups[i].quad4);
+
+       /* send off query for this group */
+
+       GRSThtcpTSTrequestMake(&request, &request_length, 
+                                   (int) (start_timeval.tv_usec),
+                                   "GET", url, "");
+
+       sendto(s, request, request_length, 0, 
+                       (struct sockaddr *) &srv, sizeof(srv));
+
+       free(request);
+          
+       /* reusing wait_timeval is a Linux-specific feature of select() */
+       wait_timeval.tv_usec = 0;
+       wait_timeval.tv_sec  = sitecast_groups[i].timewait;
+
+       while ((wait_timeval.tv_sec > 0) || (wait_timeval.tv_usec > 0))
+            {
+              FD_ZERO(&readsckts);
+              FD_SET(s, &readsckts);
+  
+              ret = select(s + 1, &readsckts, NULL, NULL, &wait_timeval);
+
+              if (ret > 0)
+                {
+                  response_length = recvfrom(s, response, MAXBUF,
+                                             0, &from, &fromlen);
+  
+                  if ((GRSThtcpMessageParse(&msg, response, response_length) 
+                                                      == GRST_RET_OK) &&
+                      (msg.opcode == GRSThtcpTSTop) && (msg.rr == 1) && 
+                      (msg.trans_id == (int) start_timeval.tv_usec) &&
+                      (msg.resp_hdrs != NULL) &&
+                      (GRSThtcpCountstrLen(msg.resp_hdrs) > 12))
+                    { 
+                      /* found one */ 
+/*
+                      if (verbose > 0)
+                        fprintf(stderr, "Sitecast %s -> %.*s\n",
+                                *source_ptr, 
+                                GRSThtcpCountstrLen(msg.resp_hdrs) - 12,
+                                &(msg.resp_hdrs->text[10]));
+*/
+                      free(url);
+                      
+                      printf("Status: 302 Moved\nLocation: %.*s\n\n",
+                          GRSThtcpCountstrLen(msg.resp_hdrs) - 12, 
+                          &(msg.resp_hdrs->text[10]));
+                          
+                      return;
+                    }
+                }
+            }
+     }
+     
+  free(url);
+  puts("Status: 404 Not Found\nContent-Type: text/plain\n\nNot found");
+}
+
+
+int main()
+{
+  int   ret;
+  char *method, *groups, *p;
+
+  groups = getenv("GRIDSITE_SRM_GROUPS");
+  if (groups == NULL)
+    {
+      puts("Status: 500 Internal Server Error\n"
+           "Content-Type: text/plain\n\n"
+           "No GRIDSITE_SRM_GROUPS defined");
+      return 0;
+    }
+
+  p = groups;
+    
+  for (last_group=-1; last_group+1 < HTCP_SITECAST_GROUPS;)
+     {  
+       sitecast_groups[last_group+1].port     = GRST_HTCP_PORT;
+       sitecast_groups[last_group+1].timewait = 1;
+       sitecast_groups[last_group+1].ttl      = 1;
+       
+       ret = sscanf(p, "%d.%d.%d.%d:%d:%d:%d", 
+                 &(sitecast_groups[last_group+1].quad1),
+                 &(sitecast_groups[last_group+1].quad2),    
+                 &(sitecast_groups[last_group+1].quad3),
+                 &(sitecast_groups[last_group+1].quad4),    
+                 &(sitecast_groups[last_group+1].port),
+                 &(sitecast_groups[last_group+1].ttl),
+                 &(sitecast_groups[last_group+1].timewait));
+
+       if (ret == 0) break; /* end of list ? */
+
+       if (ret < 5)
+         {
+           puts("Status: 500 Internal Server Error\n"
+                "Content-Type: text/plain\n\n"
+                "Failed to parse GRIDSITE_SRM_GROUPS");
+           return 0;
+         }
+       
+       ++last_group;
+
+       if ((p = index(p, ',')) == NULL) break;       
+       ++p;
+     }
+
+  if (last_group == -1)
+    {
+      puts("Status: 500 Internal Server Error\n"
+           "Content-Type: text/plain\n\n"
+           "No groups found in GRIDSITE_SRM_GROUPS");
+      return;
+    }
+
+  method = getenv("METHOD");
+
+  if ((method != NULL) && (strcmp(method, "GET") == 0))
+    {
+      handle_sitecast_get();
+      return 0;      
+    }
+    
+  puts("Status: 400 Bad Request\n");
+  return 0;
+}
index d55c366..ef102ae 100755 (executable)
@@ -197,6 +197,7 @@ fi
 %attr(-, root, root) %{prefix}/lib/httpd/modules/mod_gridsite.so
 %attr(-, root, root) %{prefix}/sbin/real-gridsite-admin.cgi
 %attr(-, root, root) %{prefix}/sbin/gridsite-copy.cgi
+%attr(-, root, root) %{prefix}/sbin/gridsite-storage.cgi
 
 %files commands
 %attr(-, root, root) %{prefix}/bin/htcp
index 0841f76..f5c3458 100644 (file)
@@ -1922,6 +1922,9 @@ static const char *mod_gridsite_take2_cmds(cmd_parms *a, void *cfg,
     }
     else if (strcasecmp(a->cmd->name, "GridSiteCastAlias") == 0)
     {
+      if ((parm1[strlen(parm1)-1] != '/') || (parm2[strlen(parm2)-1] != '/'))
+        return "GridSiteCastAlias URL and path must end with /";
+    
       for (i=0; i < GRST_SITECAST_ALIASES; ++i) /* look for free slot */
          {
            if (sitecastaliases[i].sitecast_url == NULL)
@@ -3261,7 +3264,17 @@ void sitecast_handle_TST_GET(server_rec *main_server,
 
   for (ialias=0; ialias < GRST_SITECAST_ALIASES ; ++ialias)
      {
-       if (sitecastaliases[ialias].sitecast_url == NULL) return; /* no match */
+       if (sitecastaliases[ialias].sitecast_url == NULL) 
+         {
+           ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server,
+              "SiteCast responder does not handle %*s requested by %s:%d",
+                        GRSThtcpCountstrLen(htcp_mesg->uri),
+                        htcp_mesg->uri->text,
+                        inet_ntoa(client_addr_ptr->sin_addr),
+                        ntohs(client_addr_ptr->sin_port));
+      
+           return; /* no match */
+         }
                              
        if ((strlen(sitecastaliases[ialias].sitecast_url)
                                 <= GRSThtcpCountstrLen(htcp_mesg->uri)) &&
@@ -3320,6 +3333,11 @@ void sitecast_handle_TST_GET(server_rec *main_server,
 
       free(location);
     }
+  else ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server,
+            "SiteCast does not find %*s (would be at %s)",
+            GRSThtcpCountstrLen(htcp_mesg->uri),
+            htcp_mesg->uri->text, filename);
+
 
   free(filename);                      
 }