myserver-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myserver-commit] [SCM] GNU MyServer branch, master, updated. 0_9_2-153-


From: Giuseppe Scrivano
Subject: [myserver-commit] [SCM] GNU MyServer branch, master, updated. 0_9_2-153-gf038e6c
Date: Fri, 16 Apr 2010 15:15:32 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU MyServer".

The branch, master has been updated
       via  f038e6c8e486ce869d0e27f9c9a70ee4c0437a13 (commit)
       via  6e91afdfa3a1828f2187a3d9bdd13c37be3b68c4 (commit)
       via  d69f285f10568981d946278f8e5fb71c9fe91b65 (commit)
       via  e14fa06a3f342cce3ee8261401168123580e8476 (commit)
       via  fd7f3de29174b1ff29b064f9b45459b972de7dcf (commit)
       via  5fb4cd0ee8856d0dd111aa850f5448b641d685f8 (commit)
       via  0442cc1ea679e7e02067103dd97d0a4ffc06a26d (commit)
       via  f9dc0edd06d506c90b00a4e99bd0a428012ca6d4 (commit)
       via  eaf34a00517172e15a224ed02fc390a1a9cdfe8f (commit)
       via  388a6be0ca412abafe0b929fdc9fa7624dd88905 (commit)
      from  e165cb33edf7a110cd2beb297fe22d25dbe88e76 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------


commit f038e6c8e486ce869d0e27f9c9a70ee4c0437a13
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 17:13:56 2010 +0200

    Silent InvalidResourceException when the read is not blocking

diff --git a/myserver/src/base/socket/socket.cpp 
b/myserver/src/base/socket/socket.cpp
index aa25567..a520b8d 100644
--- a/myserver/src/base/socket/socket.cpp
+++ b/myserver/src/base/socket/socket.cpp
@@ -549,13 +549,17 @@ int Socket::recv (char* buffer, int len, int flags)
 {
   int err = 0;
 
-  err = checked::recv (fd, buffer, len, flags);
-
-  if ( err < 0 && errno == EAGAIN && isNonBlocking)
-    return 0;
-
-  if (err == 0)
-    err = -1;
+  try
+    {
+      err = checked::recv (fd, buffer, len, flags);
+    }
+  catch (InvalidResourceException & e)
+    {
+      if (isNonBlocking)
+        return 0;
+      else
+        throw;
+    }
 
   return err;
 }



commit 6e91afdfa3a1828f2187a3d9bdd13c37be3b68c4
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 17:10:01 2010 +0200

    Handle exceptions in the control protocol handler

diff --git a/myserver/src/base/socket/socket.cpp 
b/myserver/src/base/socket/socket.cpp
index 5bce4af..aa25567 100644
--- a/myserver/src/base/socket/socket.cpp
+++ b/myserver/src/base/socket/socket.cpp
@@ -545,7 +545,7 @@ int Socket::recv (char* buffer, int len, int flags, u_long 
timeout)
  *Receive data from the socket.
  *Returns -1 on errors.
  */
-int Socket::recv (char* buffer,int len,int flags)
+int Socket::recv (char* buffer, int len, int flags)
 {
   int err = 0;
 
diff --git a/myserver/src/protocol/control/control_protocol.cpp 
b/myserver/src/protocol/control/control_protocol.cpp
index 8a13616..1d654e5 100644
--- a/myserver/src/protocol/control/control_protocol.cpp
+++ b/myserver/src/protocol/control/control_protocol.cpp
@@ -136,7 +136,7 @@ int ControlProtocol::loadProtocol ()
   else
   {
     md5.init ();
-    md5.update (tmpName, (unsigned int)strlen (tmpName));
+    md5.update (tmpName, (unsigned int) strlen (tmpName));
     md5.end ( adminLogin);
   }
 
@@ -145,7 +145,7 @@ int ControlProtocol::loadProtocol ()
   else
   {
     md5.init ();
-    md5.update (tmpPassword,(unsigned int)strlen (tmpPassword));
+    md5.update (tmpPassword,(unsigned int) strlen (tmpPassword));
     md5.end (adminPassword);
   }
 
@@ -174,7 +174,7 @@ int ControlProtocol::checkAuth (ControlHeader& header)
   md5.end (authLoginHeaderMD5);
 
   md5.init ();
-  md5.update (headerPassword, (unsigned int)strlen (headerPassword));
+  md5.update (headerPassword, (unsigned int) strlen (headerPassword));
   md5.end (authPasswordHeaderMD5);
 
   if ((! strcasecmp (adminLogin, authLoginHeaderMD5)) &&
@@ -204,333 +204,239 @@ int ControlProtocol::controlConnection (ConnectionPtr 
a, char *request,
   char *command = 0;
   char *opt = 0 ;
   int bufferSize = a->getActiveThread ()->getBufferSize ();
-  /* Input file. */
-  File *inFile = 0;
-  /* Output file. */
-  File *outFile = 0;
+  File inFile;
+  File outFile;
 
   /* Use control_header to parse the request. */
   ControlHeader header;
 
   /* Is the specified command a know one? */
   int knownCommand;
-  if (a->getToRemove ())
-  {
-    switch (a->getToRemove ())
+
+  try
     {
-      /* Remove the connection from the list. */
-    case Connection::REMOVE_OVERLOAD:
-      sendResponse (auxBuffer, bufferSize, a, CONTROL_SERVER_BUSY, header, 0);
-      return 0;
-    default:
-      return 0;
-    }
-  }
+      if (a->getToRemove ())
+        {
+          switch (a->getToRemove ())
+            {
+              /* Remove the connection from the list. */
+            case Connection::REMOVE_OVERLOAD:
+              sendResponse (auxBuffer, bufferSize, a, CONTROL_SERVER_BUSY,
+                            header, 0);
+              return 0;
+            default:
+              return 0;
+            }
+        }
 
-  ret = header.parse_header (request, nbtr, &realHeaderLength);
+      /*
+       *On errors remove the connection from the connections list.
+       *For return values look at protocol/control/control_errors.h.
+       *Returning 0 from the controlConnection we will remove the connection
+       *from the active connections list.
+       */
+      if (header.parse_header (request, nbtr, &realHeaderLength) != CONTROL_OK)
+        {
+          /* parse_header returns -1 on an incomplete header.  */
+          if (ret == -1)
+            return 2;
 
-  /*
-   *On errors remove the connection from the connections list.
-   *For return values look at protocol/control/control_errors.h.
-   *Returning 0 from the controlConnection we will remove the connection
-   *from the active connections list.
-   */
-  if (ret != CONTROL_OK)
-  {
-    /* parse_header returns -1 on an incomplete header.  */
-    if (ret == -1)
-    {
-      return 2;
-    }
-    sendResponse (auxBuffer, bufferSize, a, ret, header, 0);
-    return 0;
-  }
-  specifiedLength = header.getLength ();
-  version = header.getVersion ();
-  timeout=getTicks ();
-  if (specifiedLength)
-  {
-    inFile = new File ();
-    if (inFile == 0)
-    {
-      a->host->warningsLogWrite (_("Control: internal error"));
-      return 0;
-    }
+          sendResponse (auxBuffer, bufferSize, a, ret, header, 0);
+          return 0;
+        }
 
-    inFilePath << getdefaultwd (0,0) << "/ControlInput_" << (u_int) id;
+      specifiedLength = header.getLength ();
+      version = header.getVersion ();
+      timeout = getTicks ();
+      if (specifiedLength)
+        {
+          inFilePath << getdefaultwd (0,0) << "/ControlInput_" << (u_int) id;
 
-    ret = inFile->createTemporaryFile (inFilePath.str ().c_str ());
-    if (ret)
-      {
-        a->host->warningsLogWrite (_("Control: internal error"));
-        sendResponse (auxBuffer, bufferSize, a, CONTROL_INTERNAL, header, 0);
-        inFile->close ();
-        FilesUtility::deleteFile (inFilePath.str ().c_str ());
-        delete inFile;
-        return 0;
-      }
-    if (nbtr - realHeaderLength)
-      {
-        ret = inFile->writeToFile (request + realHeaderLength,
-                                   nbtr - realHeaderLength,
-                                   &nbw);
-        dataWritten += nbw;
-        if (ret)
-          {
-            a->host->warningsLogWrite (_("Control: internal error"));
-            sendResponse (auxBuffer, bufferSize, a, CONTROL_INTERNAL, header,
-                          0);
-            inFile->close ();
-            FilesUtility::deleteFile (inFilePath.str ().c_str ());
-            delete inFile;
-            inFile=0;
-            return 0;
-          }
-      }
-  }
+          inFile.createTemporaryFile (inFilePath.str ().c_str ());
 
-  /* Check if there are other bytes waiting to be read. */
-  if (specifiedLength && (specifiedLength
-                          != static_cast<int>(nbtr - realHeaderLength)))
-    {
-      /* Check if we can read all the specified data. */
-      while (specifiedLength != static_cast<int>(nbtr - realHeaderLength))
+          if (nbtr - realHeaderLength)
+            {
+              inFile.writeToFile (request + realHeaderLength,
+                                  nbtr - realHeaderLength, &nbw);
+              dataWritten += nbw;
+            }
+        }
+
+      /* Check if there are other bytes waiting to be read. */
+      if (specifiedLength && (specifiedLength
+                              != static_cast<int>(nbtr - realHeaderLength)))
         {
-          if (a->socket->bytesToRead ())
+          /* Check if we can read all the specified data. */
+          while (specifiedLength != static_cast<int>(nbtr - realHeaderLength))
             {
-              ret = a->socket->recv (auxBuffer, bufferSize, 0);
-              if (ret == -1)
+              if (a->socket->bytesToRead ())
                 {
-                  a->host->warningsLogWrite (_("Control: internal error"));
-                  sendResponse (auxBuffer, bufferSize, a, CONTROL_INTERNAL, 
header,
-                                0);
-                  inFile->close ();
-                  FilesUtility::deleteFile (inFilePath.str ().c_str ());
-                  delete inFile;
-                  inFile=0;
-                  return -1;
+                  u_long ret;
+                  ret = a->socket->recv (auxBuffer, bufferSize, 0);
+                  inFile.writeToFile (auxBuffer, ret, &nbw);
+                  dataWritten += nbw;
+                  if (dataWritten >=  specifiedLength)
+                    break;
+                  timeout = getTicks ();
                 }
-              ret = inFile->writeToFile (auxBuffer, ret, &nbw);
-              dataWritten += nbw;
-              if (ret)
+              else if (getTicks () - timeout > MYSERVER_SEC (5))
                 {
-                  a->host->warningsLogWrite (_("Control: internal error"));
-                  sendResponse (auxBuffer, bufferSize, a, CONTROL_INTERNAL,
-                                header, 0);
-                  inFile->close ();
+                  sendResponse (auxBuffer, bufferSize, a, CONTROL_BAD_LEN, 
header,
+                                0);
+                  inFile.close ();
                   FilesUtility::deleteFile (inFilePath.str ().c_str ());
-                  delete inFile;
-                  inFile=0;
+                  return 0;
                 }
-
-              if (dataWritten >=  specifiedLength)
-                break;
-              timeout = getTicks ();
-            }
-          else if (getTicks () - timeout > MYSERVER_SEC (5))
-            {
-              sendResponse (auxBuffer, bufferSize, a, CONTROL_BAD_LEN, header,
-                            0);
-              inFile->close ();
-              FilesUtility::deleteFile (inFilePath.str ().c_str ());
-              delete inFile;
-              inFile=0;
-              return 0;
-            }
-          else
-            {
-              /* Wait a bit.  */
-              Thread::wait (2);
+              else
+                Thread::wait (2);
             }
         }
-    }
-  if (inFile)
-    {
-      inFile->seek (0);
-    }
 
-  if (strcasecmp (version, "CONTROL/1.0"))
-    {
-      a->host->warningsLogWrite (_("Control: specified version not 
supported"));
-      if (inFile)
+      inFile.seek (0);
+
+      if (strcasecmp (version, "CONTROL/1.0"))
         {
-          inFile->close ();
+          a->host->warningsLogWrite (_("Control: specified version not 
supported"));
+          inFile.close ();
           FilesUtility::deleteFile (inFilePath.str ().c_str ());
-          delete inFile;
-          inFile = 0;
+          sendResponse (auxBuffer, bufferSize, a, CONTROL_BAD_VERSION, header, 
0);
+          return 0;
         }
-      sendResponse (auxBuffer, bufferSize, a, CONTROL_BAD_VERSION, header, 0);
-      return 0;
-    }
 
-  authorized = checkAuth (header);
+      authorized = checkAuth (header);
 
-  /*
-   * If the client is not authorized remove the connection.
-   */
-  if (authorized == 0)
-    {
-      if (inFile)
+      /*
+       * If the client is not authorized remove the connection.
+       */
+      if (authorized == 0)
         {
-          inFile->close ();
+          inFile.close ();
           FilesUtility::deleteFile (inFilePath.str ().c_str ());
-          delete inFile;
-          inFile=0;
+          sendResponse (auxBuffer, bufferSize, a, CONTROL_AUTH, header, 0);
+          return 0;
         }
-      sendResponse (auxBuffer, bufferSize, a, CONTROL_AUTH, header, 0);
-      return 0;
-    }
-  /*
-   * If the specified length is different from the length that the
-   * server can read, remove the connection.
-   */
-  if (dataWritten != specifiedLength)
-    {
-      if (inFile)
+      /*
+       * If the specified length is different from the length that the
+       * server can read, remove the connection.
+       */
+      if (dataWritten != specifiedLength)
         {
-          inFile->close ();
+          inFile.close ();
           FilesUtility::deleteFile (inFilePath.str ().c_str ());
-          delete inFile;
-          inFile = 0;
+          sendResponse (auxBuffer, bufferSize, a, CONTROL_BAD_LEN, header, 0);
+          return 0;
         }
-      sendResponse (auxBuffer, bufferSize, a, CONTROL_BAD_LEN, header, 0);
-      return 0;
-    }
-
-  command = header.getCommand ();
-  opt     = header.getOptions ();
-
-  knownCommand = 0;
 
-  /* Create an out file. This can be used by commands needing it. */
-    outFile = new File ();
-  outFilePath << getdefaultwd (0, 0) << "/ControlOutput_" << (u_int) id;
-
-  ret = outFile->createTemporaryFile (outFilePath.str ().c_str ());
-  if (ret)
-    {
-      a->host->warningsLogWrite (_("Control: internal error"));
-      sendResponse (auxBuffer, bufferSize, a, CONTROL_INTERNAL, header, 0);
-      delete outFile;
-      inFile->close ();
-      delete inFile;
+      command = header.getCommand ();
+      opt = header.getOptions ();
 
-      FilesUtility::deleteFile (inFilePath.str ().c_str ());
-      FilesUtility::deleteFile (outFilePath.str ().c_str ());
+      knownCommand = 0;
 
-      inFile=0;
-      outFile=0;
-      return 0;
-    }
-  if (!strcmp (command, "SHOWCONNECTIONS"))
-    {
-      knownCommand = 1;
-      ret = showConnections (a, outFile, request, bufferSize, header);
-    }
-  else if (!strcmp (command, "KILLCONNECTION"))
-    {
-      char buff[11];
-      u_long id;
-      knownCommand = 1;
-      strncpy (buff, header.getOptions (), 10 );
-      buff[10] = '\0';
-      id = header.getOptions () ? atol (buff) : 0;
-      ret = killConnection (a, id, outFile, request, bufferSize, header);
-    }
-  else if (!strcmp (command, "REBOOT"))
-    {
-      knownCommand = 1;
-      Server::getInstance ()->delayedReboot ();
-      ret = 0;
-    }
-  else if (!strcmp (command, "GETFILE"))
-    {
-      knownCommand = 1;
-      ret = getFile (a, header.getOptions (), inFile, outFile, request,
-                     bufferSize, header);
-    }
-  else if (!strcmp (command, "PUTFILE"))
-    {
-      knownCommand = 1;
-      ret = putFile (a,header.getOptions (), inFile, outFile, request,
-                     bufferSize, header);
-    }
-  else if (!strcmp (command, "DISABLEREBOOT"))
-    {
-      Server::getInstance ()->disableAutoReboot ();
-      knownCommand = 1;
+      /* Create an out file. This can be used by commands needing it. */
+      outFilePath << getdefaultwd (0, 0) << "/ControlOutput_" << (u_int) id;
 
-    }
-  else if (!strcmp (command, "ENABLEREBOOT"))
-    {
-      Server::getInstance ()->enableAutoReboot ();
-      knownCommand = 1;
+      outFile.createTemporaryFile (outFilePath.str ().c_str ());
 
-    }
-  else if (!strcmp (command, "VERSION"))
-    {
-      knownCommand = 1;
-      ret = getVersion (a, outFile, request, bufferSize, header);
-    }
+      if (!strcmp (command, "SHOWCONNECTIONS"))
+        {
+          knownCommand = 1;
+          ret = showConnections (a, &outFile, request, bufferSize, header);
+        }
+      else if (!strcmp (command, "KILLCONNECTION"))
+        {
+          char buff[11];
+          u_long id;
+          knownCommand = 1;
+          strncpy (buff, header.getOptions (), 10 );
+          buff[10] = '\0';
+          id = header.getOptions () ? atol (buff) : 0;
+          ret = killConnection (a, id, &outFile, request, bufferSize, header);
+        }
+      else if (!strcmp (command, "REBOOT"))
+        {
+          knownCommand = 1;
+          Server::getInstance ()->delayedReboot ();
+          ret = 0;
+        }
+      else if (!strcmp (command, "GETFILE"))
+        {
+          knownCommand = 1;
+          ret = getFile (a, header.getOptions (), &inFile, &outFile, request,
+                         bufferSize, header);
+        }
+      else if (!strcmp (command, "PUTFILE"))
+        {
+          knownCommand = 1;
+          ret = putFile (a,header.getOptions (), &inFile, &outFile, request,
+                         bufferSize, header);
+        }
+      else if (!strcmp (command, "DISABLEREBOOT"))
+        {
+          Server::getInstance ()->disableAutoReboot ();
+          knownCommand = 1;
 
-  if (knownCommand)
-    {
-      char *connection;
-      outFile->seek (0);
-      if (ret)
-        sendResponse (auxBuffer, bufferSize, a, CONTROL_INTERNAL, header, 0);
-      else
-        sendResponse (auxBuffer, bufferSize, a, CONTROL_OK, header, outFile);
+        }
+      else if (!strcmp (command, "ENABLEREBOOT"))
+        {
+          Server::getInstance ()->enableAutoReboot ();
+          knownCommand = 1;
 
-      if (inFile)
+        }
+      else if (!strcmp (command, "VERSION"))
         {
-          inFile->close ();
-          delete inFile;
-          inFile = NULL;
+          knownCommand = 1;
+          ret = getVersion (a, &outFile, request, bufferSize, header);
         }
 
-      if (outFile)
+      if (knownCommand)
         {
-          outFile->close ();
-          delete outFile;
-          outFile = NULL;
-        }
+          char *connection;
+          outFile.seek (0);
+          if (ret)
+            sendResponse (auxBuffer, bufferSize, a, CONTROL_INTERNAL, header, 
0);
+          else
+            sendResponse (auxBuffer, bufferSize, a, CONTROL_OK, header, 
&outFile);
 
-      FilesUtility::deleteFile (inFilePath.str ().c_str ());
-      FilesUtility::deleteFile (outFilePath.str ().c_str ());
-      connection = header.getConnection ();
+          inFile.close ();
+          outFile.close ();
 
-      /*
-       * If the Keep-Alive was specified keep the connection in the
-       * active connections list.
-       */
-      if (! strcasecmp (connection, "keep-alive"))
-        return ClientsThread::KEEP_CONNECTION;
+          FilesUtility::deleteFile (inFilePath.str ().c_str ());
+          FilesUtility::deleteFile (outFilePath.str ().c_str ());
+          connection = header.getConnection ();
+
+          /*
+           * If the Keep-Alive was specified keep the connection in the
+           * active connections list.
+           */
+          if (! strcasecmp (connection, "keep-alive"))
+            return ClientsThread::KEEP_CONNECTION;
+          else
+            return ClientsThread::DELETE_CONNECTION;
+        }
       else
-        return ClientsThread::DELETE_CONNECTION;
-    }
-  else
-    {
-      sendResponse (auxBuffer, bufferSize, a, CONTROL_CMD_NOT_FOUND, header, 
0);
-
-      if (inFile)
         {
-          inFile->close ();
-          delete inFile;
-          inFile = NULL;
-        }
+          sendResponse (auxBuffer, bufferSize, a, CONTROL_CMD_NOT_FOUND,
+                        header, 0);
 
-      if (outFile)
-        {
-          outFile->close ();
-          delete outFile;
-          outFile = NULL;
+          inFile.close ();
+          outFile.close ();
+          FilesUtility::deleteFile (inFilePath.str ().c_str ());
+          FilesUtility::deleteFile (outFilePath.str ().c_str ());
+
+          return ClientsThread::DELETE_CONNECTION;
         }
+    }
+  catch (exception & e)
+    {
+      inFile.close ();
+      outFile.close ();
       FilesUtility::deleteFile (inFilePath.str ().c_str ());
       FilesUtility::deleteFile (outFilePath.str ().c_str ());
-
+      a->host->warningsLogWrite (_E ("Control: internal error"), &e);
       return ClientsThread::DELETE_CONNECTION;
     }
+
+  return ClientsThread::DELETE_CONNECTION;
 }
 
 /*!
@@ -541,9 +447,10 @@ int ControlProtocol::addToLog (int retCode, ConnectionPtr 
con, char *buffer,
 {
   string time;
   getRFC822GMTTime (time, 32);
-  gnulib::snprintf (buffer, bufferSize, "%s [%s] %s:%s:%s - %s - %i", 
con->getIpAddr (),
-            time.c_str (), header.getCommand (), header.getVersion (),
-            header.getOptions (), header.getAuthLogin (), retCode);
+  gnulib::snprintf (buffer, bufferSize, "%s [%s] %s:%s:%s - %s - %i",
+                    con->getIpAddr (), time.c_str (), header.getCommand (),
+                    header.getVersion (), header.getOptions (),
+                    header.getAuthLogin (), retCode);
   con->host->accessesLogWrite ("%s", buffer);
   return 0;
 }
@@ -566,25 +473,13 @@ int ControlProtocol::sendResponse (char *buffer, int 
buffersize,
 
   /* Build and send the first line.  */
   gnulib::snprintf (buffer, buffersize, "/%i\r\n", errID);
-  if (a->socket->send (buffer, strlen (buffer), 0) < 0)
-    {
-      a->host->warningsLogWrite (_("Control: socket error"));
-      return -1;
-    }
+  a->socket->send (buffer, strlen (buffer), 0);
 
-  gnulib::snprintf (buffer, buffersize, "/LEN %u\r\n", (u_int)dataLength);
-  if (a->socket->send (buffer, strlen (buffer), 0) < 0)
-    {
-      a->host->warningsLogWrite (_("Control: socket error"));
-      return -1;
-    }
+  gnulib::snprintf (buffer, buffersize, "/LEN %u\r\n", (u_int) dataLength);
+  a->socket->send (buffer, strlen (buffer), 0);
 
   /* Send the end of the header.  */
-  if (a->socket->send ("\r\n", 2, 0) < 0)
-    {
-      a->host->warningsLogWrite (_("Control: socket error"));
-      return -1;
-    }
+  a->socket->send ("\r\n", 2, 0);
 
   /* Flush the content of the file if any.  */
   if (dataLength)
@@ -593,24 +488,13 @@ int ControlProtocol::sendResponse (char *buffer, int 
buffersize,
       u_long nbr;
       for ( ; ; )
         {
-          int err;
-          if (outFile->read (buffer, min (dataToSend, buffersize), &nbr))
-            {
-              a->host->warningsLogWrite (_("Control: internal error"));
-              return -1;
-            }
+          outFile->read (buffer, min (dataToSend, buffersize), &nbr);
 
           dataToSend -= nbr;
-          err = a->socket->send (buffer, nbr, 0);
+          a->socket->send (buffer, nbr, 0);
 
           if (dataToSend == 0)
             break;
-
-          if (err == -1)
-            {
-              a->host->warningsLogWrite (_("Control: socket error"));
-              return -1;
-            }
         }
     }
 



commit d69f285f10568981d946278f8e5fb71c9fe91b65
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 16:36:27 2010 +0200

    Handle exceptions in the FTP protocol handler

diff --git a/myserver/src/protocol/ftp/ftp.cpp 
b/myserver/src/protocol/ftp/ftp.cpp
index eb0d55e..3ae3867 100644
--- a/myserver/src/protocol/ftp/ftp.cpp
+++ b/myserver/src/protocol/ftp/ftp.cpp
@@ -333,7 +333,7 @@ int Ftp::controlConnection (ConnectionPtr pConnection, char 
*request,
     {
       pFtpuserData->m_nFtpstate = FtpuserData::UNAVAILABLE;
       ftpReply (421);
-      return 0;
+      return ClientsThread::DELETE_CONNECTION;
     }
 
   m_nLocalControlport = pConnection->getLocalPort ();
@@ -350,7 +350,16 @@ int Ftp::controlConnection (ConnectionPtr pConnection, 
char *request,
   td.pProtocolInterpreter = this;
   td.m_nParseLength = 0;
 
-  return parseControlConnection ();
+  try
+    {
+      return parseControlConnection ();
+    }
+  catch (exception & e)
+    {
+      return ClientsThread::DELETE_CONNECTION;
+    }
+
+  return ClientsThread::DELETE_CONNECTION;
 }
 
 
@@ -844,7 +853,7 @@ DEFINE_THREAD (SendAsciiFile, pParam)
       pFtpuserData->closeDataConnection ();
       pFtpuserData->m_DataConnBusy.unlock ();
     }
-  catch (bad_alloc & ba)
+  catch (exception & e)
     {
       if (file != NULL)
         file->close ();
@@ -1023,7 +1032,7 @@ DEFINE_THREAD (SendImageFile, pParam)
       file->close ();
       delete file;
     }
-  catch (bad_alloc & ba)
+  catch (exception & e)
     {
       if (file != NULL)
         file->close ();
@@ -1229,7 +1238,7 @@ DEFINE_THREAD (ReceiveAsciiFile, pParam)
         }
       file.close ();
     }
-  catch (bad_alloc & ba)
+  catch (exception & e)
     {
       file.close ();
     }
@@ -1378,7 +1387,7 @@ DEFINE_THREAD (ReceiveImageFile, pParam)
         }
       file.close ();
     }
-  catch (bad_alloc & ba)
+  catch (exception & e)
     {
       file.close ();
     }



commit e14fa06a3f342cce3ee8261401168123580e8476
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 16:08:57 2010 +0200

    ISAPI handles exceptions properly

diff --git a/myserver/src/http_handler/isapi/isapi.cpp 
b/myserver/src/http_handler/isapi/isapi.cpp
index e2adc2b..0d4be8e 100644
--- a/myserver/src/http_handler/isapi/isapi.cpp
+++ b/myserver/src/http_handler/isapi/isapi.cpp
@@ -53,7 +53,8 @@ BOOL WINAPI ISAPI_ServerSupportFunctionExport (HCONN hConn, 
DWORD dwHSERRequest,
   Isapi::isapiMutex->unlock ();
   if (ConnInfo == NULL)
     {
-      Server::getInstance ()->log ("isapi::ServerSupportFunctionExport: 
invalid hConn");
+      Server::getInstance ()->log
+        ("ISAPI::ServerSupportFunctionExport: invalid hConn");
       return HttpDataHandler::RET_FAILURE;
     }
 
@@ -64,11 +65,11 @@ BOOL WINAPI ISAPI_ServerSupportFunctionExport (HCONN hConn, 
DWORD dwHSERRequest,
       mapInfo=(HSE_URL_MAPEX_INFO*)lpdwDataType;
       mapInfo->lpszPath = 0;
       tmp.assign (mapInfo->lpszPath);
-      ret=ConnInfo->td->http->getPath (tmp,(char*)lpvBuffer, 0);
+      ret=ConnInfo->td->http->getPath (tmp,(char*) lpvBuffer, 0);
       if (ret != 200)
         return 1;
 
-      mapInfo->cchMatchingURL=(DWORD)strlen ((char*)lpvBuffer);
+      mapInfo->cchMatchingURL=(DWORD)strlen ((char*) lpvBuffer);
       mapInfo->cchMatchingPath=(DWORD)strlen (mapInfo->lpszPath);
       delete [] mapInfo->lpszPath;
       mapInfo->lpszPath = new char[tmp.length () + 1];
@@ -84,12 +85,13 @@ BOOL WINAPI ISAPI_ServerSupportFunctionExport (HCONN hConn, 
DWORD dwHSERRequest,
       break;
 
     case HSE_REQ_MAP_URL_TO_PATH:
-      if (((char*)lpvBuffer)[0])
-        strcpy (uri,(char*)lpvBuffer);
+      if (((char*) lpvBuffer)[0])
+        strcpy (uri,(char*) lpvBuffer);
       else
         lstrcpyn (uri,ConnInfo->td->request.uri.c_str (),
-                 (int)ConnInfo->td->request.uri.length 
()-ConnInfo->td->pathInfo.length () +1);
-      ret = ConnInfo->td->http->getPath (tmp ,uri,0);
+                 (int) ConnInfo->td->request.uri.length ()
+                  - ConnInfo->td->pathInfo.length () + 1);
+      ret = ConnInfo->td->http->getPath (tmp, uri, 0);
       if (ret != 200)
         {
           if (buffer)
@@ -102,28 +104,32 @@ BOOL WINAPI ISAPI_ServerSupportFunctionExport (HCONN 
hConn, DWORD dwHSERRequest,
           SetLastError (ERROR_INSUFFICIENT_BUFFER);
           return HttpDataHandler::RET_FAILURE;
         }
-      strcpy ((char*)lpvBuffer, tmp.c_str ());
-      if (FilesUtility::completePath ((char**)&lpvBuffer,(int*)lpdwSize,  1))
+      strcpy ((char*) lpvBuffer, tmp.c_str ());
+      if (FilesUtility::completePath ((char **) &lpvBuffer, (int *) lpdwSize,
+                                      1))
         {
           SetLastError (ERROR_INSUFFICIENT_BUFFER);
           return HttpDataHandler::RET_FAILURE;
         }
-      *lpdwSize=(DWORD)strlen ((char*)lpvBuffer);
+      *lpdwSize=(DWORD)strlen ((char*) lpvBuffer);
       break;
 
     case HSE_REQ_SEND_URL_REDIRECT_RESP:
-      return ((Isapi*)ConnInfo->isapi)->Redirect (ConnInfo->td,
-                                                 ConnInfo->connection,(char 
*)lpvBuffer);
+      return ((Isapi*) ConnInfo->isapi)->Redirect (ConnInfo->td,
+                                                   ConnInfo->connection,
+                                                   (char *) lpvBuffer);
       break;
 
     case HSE_REQ_SEND_URL:
-      return ((Isapi*)ConnInfo->isapi)->Senduri (ConnInfo->td,
-                                                ConnInfo->connection,(char 
*)lpvBuffer);
+      return ((Isapi*) ConnInfo->isapi)->Senduri (ConnInfo->td,
+                                                ConnInfo->connection,
+                                                  (char *) lpvBuffer);
       break;
 
     case HSE_REQ_SEND_RESPONSE_HEADER:
-      return ((Isapi*)ConnInfo->isapi)->SendHeader (ConnInfo->td,
-                                                   ConnInfo->connection,(char 
*)lpvBuffer);
+      return ((Isapi*) ConnInfo->isapi)->SendHeader (ConnInfo->td,
+                                                     ConnInfo->connection,
+                                                     (char *) lpvBuffer);
       break;
 
     case HSE_REQ_DONE_WITH_SESSION:
@@ -228,7 +234,7 @@ BOOL WINAPI ISAPI_WriteClientExport (HCONN hConn, LPVOID 
Buffer, LPDWORD lpdwByt
   if (!ConnInfo->headerSent)
     {
       int headerSize = 0;
-      u_long size = (u_long)strlen (buffer);
+      u_long size = (u_long) strlen (buffer);
       strncat (buffer, (char*)Buffer, *lpdwBytes);
       ConnInfo->headerSize += *lpdwBytes;
       if (buffer[0] == '\r')
@@ -263,14 +269,15 @@ BOOL WINAPI ISAPI_WriteClientExport (HCONN hConn, LPVOID 
Buffer, LPDWORD lpdwByt
       /*!
        *Handle the HTTP header if exists.
        */
-      if (headerSize)
+      if (! headerSize)
+        nbw = *lpdwBytes;
+      else
         {
           int len = ConnInfo->headerSize-headerSize;
 
-          HttpHeaders::buildHTTPResponseHeaderStruct 
(ConnInfo->td->buffer->getBuffer (),
-                                                      &ConnInfo->td->response,
-                                                      
&(ConnInfo->td->nBytesToRead));
-
+          HttpHeaders::buildHTTPResponseHeaderStruct
+            (ConnInfo->td->buffer->getBuffer (), &ConnInfo->td->response,
+             &(ConnInfo->td->nBytesToRead));
 
           if (!ConnInfo->td->appendOutputs)
             {
@@ -302,7 +309,8 @@ BOOL WINAPI ISAPI_WriteClientExport (HCONN hConn, LPVOID 
Buffer, LPDWORD lpdwByt
 
           /*! If only the header was requested return. */
           if (ConnInfo->headerSent && ConnInfo->onlyHeader
-              || ConnInfo->td->response.getStatusType () == 
HttpResponseHeader::SUCCESSFUL)
+              || ConnInfo->td->response.getStatusType ()
+              == HttpResponseHeader::SUCCESSFUL)
             return 0;
 
           /*!Send the first chunk. */
@@ -313,7 +321,7 @@ BOOL WINAPI ISAPI_WriteClientExport (HCONN hConn, LPVOID 
Buffer, LPDWORD lpdwByt
                 {
                   sprintf (chunkSize, "%x\r\n", len);
                   if (ConnInfo->chain.getStream ()->write (chunkSize,
-                                                           (int)strlen 
(chunkSize), &nbw))
+                                                           (int) strlen 
(chunkSize), &nbw))
                     return HttpDataHandler::RET_FAILURE;
                 }
 
@@ -340,10 +348,6 @@ BOOL WINAPI ISAPI_WriteClientExport (HCONN hConn, LPVOID 
Buffer, LPDWORD lpdwByt
                 }
             }
         }
-      else
-        {
-          nbw = *lpdwBytes;
-        }
     }
   else/*!Continue to send data chunks*/
     {
@@ -351,8 +355,8 @@ BOOL WINAPI ISAPI_WriteClientExport (HCONN hConn, LPVOID 
Buffer, LPDWORD lpdwByt
         {
           sprintf (chunkSize, "%x\r\n", *lpdwBytes);
           nbw = ConnInfo->connection->socket->send (chunkSize,
-                                                    (int)strlen (chunkSize), 
0);
-          if ((nbw == (u_long)-1) || (!nbw))
+                                                    (int) strlen (chunkSize), 
0);
+          if ((nbw == (u_long) -1) || (! nbw))
             return HttpDataHandler::RET_FAILURE;
         }
 
@@ -398,11 +402,12 @@ BOOL WINAPI ISAPI_ReadClientExport (HCONN hConn, LPVOID 
lpvBuffer,
   Isapi::isapiMutex->unlock ();
   if (ConnInfo == NULL)
   {
-    ((Vhost*)(ConnInfo->td->connection->host))->warningsLogWrite (_("ISAPI: 
internal error"));
+    ((Vhost*)(ConnInfo->td->connection->host))->warningsLogWrite
+      (_("ISAPI: internal error"));
     return HttpDataHandler::RET_FAILURE;
   }
 
-  ConnInfo->td->inputData.read ((char*)lpvBuffer, *lpdwSize, &NumRead);
+  ConnInfo->td->inputData.read ((char*) lpvBuffer, *lpdwSize, &NumRead);
 
   if (NumRead == -1)
     {
@@ -432,7 +437,7 @@ BOOL WINAPI ISAPI_GetServerVariableExport (HCONN hConn,
   if (ConnInfo == NULL)
     {
       Server::getInstance ()->log (
-                            "Isapi::GetServerVariableExport: invalid hConn");
+                            "ISAPI::GetServerVariableExport: invalid hConn");
       return HttpDataHandler::RET_FAILURE;
     }
 
@@ -464,15 +469,15 @@ BOOL WINAPI ISAPI_GetServerVariableExport (HCONN hConn,
        */
       char *localEnv;
       int variableNameLen;
-      ((char*)lpvBuffer)[0]='\0';
+      ((char*) lpvBuffer)[0] = '\0';
       localEnv = ConnInfo->envString;
-      variableNameLen = (int)strlen (lpszVariableName);
-      for (u_long i = 0;;i += (u_long)strlen (&localEnv[i]) + 1)
+      variableNameLen = (int) strlen (lpszVariableName);
+      for (u_long i = 0;;i += (u_long) strlen (&localEnv[i]) + 1)
         {
           if (((localEnv[i + variableNameLen]) == '=') &&
               (!strncmp (&localEnv[i], lpszVariableName, variableNameLen)))
             {
-              strncpy ((char*)lpvBuffer, &localEnv[i + variableNameLen + 1],
+              strncpy ((char*) lpvBuffer, &localEnv[i + variableNameLen + 1],
                        *lpdwSize);
               break;
             }
@@ -480,7 +485,7 @@ BOOL WINAPI ISAPI_GetServerVariableExport (HCONN hConn,
             break;
         }
     }
-  *lpdwSize = (DWORD) strlen ((char*)lpvBuffer);
+  *lpdwSize = (DWORD) strlen ((char*) lpvBuffer);
   return ret;
 }
 
@@ -514,123 +519,96 @@ BOOL Isapi::buildAllHttpHeaders (HttpThreadContext* td, 
ConnectionPtr /*!a*/,
       ostringstream rangeBuffer;
       rangeBuffer << "HTTP_RANGE:" << td->request.rangeType << "=" ;
       if (td->request.rangeByteBegin)
-        {
-          rangeBuffer << (int)td->request.rangeByteBegin;
-        }
+        rangeBuffer << (int)td->request.rangeByteBegin;
       rangeBuffer << "-";
       if (td->request.rangeByteEnd)
         rangeBuffer << td->request.rangeByteEnd;
       valLen += sprintf (&ValStr[valLen], "%s\n", rangeBuffer.str ().c_str ());
     }
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("accept-encoding");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen], "HTTP_ACCEPT_ENCODING:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
-
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("accept-language");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_ACCEPT_LANGUAGE:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  HttpRequestHeader::Entry* e = td->request.other.get ("accept-encoding");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen], "HTTP_ACCEPT_ENCODING:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
+  e = td->request.other.get ("accept-language");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_ACCEPT_LANGUAGE:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("accept-charset");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_ACCEPT_CHARSET:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("accept-charset");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_ACCEPT_CHARSET:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("pragma");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_PRAGMA:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("pragma");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_PRAGMA:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("connection");
-    if (e && (valLen + 30< maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_CONNECTION:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("connection");
+  if (e && (valLen + 30< maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_CONNECTION:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("cookie");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_COOKIE:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("cookie");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_COOKIE:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("host");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_HOST:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("host");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_HOST:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("date");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_DATE:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("date");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_DATE:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("if-modified-since");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_IF_MODIFIED_SINCE:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("if-modified-since");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_IF_MODIFIED_SINCE:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("referer");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_REFERER:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("referer");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_REFERER:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("user-agent");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_USER_AGENT:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("user-agent");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_USER_AGENT:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
-  {
-    HttpRequestHeader::Entry* e = td->request.other.get ("from");
-    if (e && (valLen + 30 < maxLen))
-      valLen += sprintf (&ValStr[valLen],"HTTP_FROM:%s\n",
-                         e->value->c_str ());
-    else if (valLen + 30 < maxLen)
-      return 1;
-  }
+  e = td->request.other.get ("from");
+  if (e && (valLen + 30 < maxLen))
+    valLen += sprintf (&ValStr[valLen],"HTTP_FROM:%s\n",
+                       e->value->c_str ());
+  else if (valLen + 30 < maxLen)
+    return 1;
 
   return 0;
 }
@@ -646,7 +624,7 @@ BOOL Isapi::buildAllRawHeaders (HttpThreadContext* 
td,ConnectionPtr a,
   char *ValStr = (char*)output;
   if (buildAllHttpHeaders (td, a, output, dwMaxLen))
     return 1;
-  valLen = (DWORD)strlen (ValStr);
+  valLen = (DWORD) strlen (ValStr);
 
   if (td->pathInfo.length () && (valLen + 30 < maxLen))
     valLen += sprintf (&ValStr[valLen], "PATH_INFO:%s\n",
@@ -737,7 +715,7 @@ int Isapi::send (HttpThreadContext* td,
    *ISAPI works only on the windows architecture.
    */
 #ifdef WIN32
-  DWORD Ret;
+  DWORD ret;
   EXTENSION_CONTROL_BLOCK ExtCtrlBlk;
   DynamicLibrary appHnd;
   HSE_VERSION_INFO Ver;
@@ -745,191 +723,200 @@ int Isapi::send (HttpThreadContext* td,
   PFN_GETEXTENSIONVERSION GetExtensionVersion;
   PFN_HTTPEXTENSIONPROC HttpExtensionProc;
   const char *loadLib;
-  int retvalue = 0;
+  int retvalue = HttpDataHandler::RET_OK;
+
   /*! Under windows there is MAX_PATH then we can use it. */
   char fullpath[MAX_PATH * 2 + 5];
 
-  if (execute)
-    sprintf (fullpath, "%s", cgipath);
-  else
+  try
     {
-      if (cgipath && strlen (cgipath))
-        sprintf (fullpath, "%s \"%s\"", cgipath, td->filenamePath.c_str ());
+      if (execute)
+        sprintf (fullpath, "%s", cgipath);
       else
-        sprintf (fullpath, "%s", td->filenamePath.c_str ());
-    }
+        {
+          if (cgipath && strlen (cgipath))
+            sprintf (fullpath, "%s \"%s\"", cgipath, td->filenamePath.c_str 
());
+          else
+            sprintf (fullpath, "%s", td->filenamePath.c_str ());
+        }
 
-  if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
-    return td->http->sendAuth ();
+      if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
+        return td->http->sendAuth ();
 
-  td->inputData.seek (0);
+      td->inputData.seek (0);
 
-  EnterCriticalSection (&GetTableEntryCritSec);
-  connIndex = 0;
-  Isapi::isapiMutex->lock ();
-  while ((connTable[connIndex].Allocated != 0) &&
-         (connIndex < maxConnections))
-    {
-      connIndex++;
-    }
-  Isapi::isapiMutex->unlock ();
-  LeaveCriticalSection (&GetTableEntryCritSec);
+      EnterCriticalSection (&GetTableEntryCritSec);
+      connIndex = 0;
 
-  if (connIndex == maxConnections)
-    {
-      td->connection->host->warningsLogWrite (_("ISAPI: max connections"));
-      return td->http->raiseHTTPError (503);
-    }
-  if (execute)
-    loadLib = scriptpath;
-  else
-    loadLib = cgipath;
+      Isapi::isapiMutex->lock ();
+      while ((connTable[connIndex].Allocated != 0) &&
+             (connIndex < maxConnections))
+        connIndex++;
+      Isapi::isapiMutex->unlock ();
 
-  Ret = appHnd.loadLibrary (loadLib);
+      LeaveCriticalSection (&GetTableEntryCritSec);
 
-  if (Ret)
-    {
-      td->connection->host->warningsLogWrite (_("ISAPI: cannot load %s"), 
loadLib);
-      return td->http->raiseHTTPError (500);
-    }
+      if (connIndex == maxConnections)
+        {
+          td->connection->host->warningsLogWrite (_("ISAPI: max connections"));
+          return td->http->raiseHTTPError (503);
+        }
+      if (execute)
+        loadLib = scriptpath;
+      else
+        loadLib = cgipath;
 
-  connTable[connIndex].chain.setStream (td->connection->socket);
-  if (td->mime)
-    {
-      u_long nbw;
-      if (td->mime && Server::getInstance ()->getFiltersFactory ()->chain (
-                                                                           
&(connTable[connIndex].chain),
-                                                                           
td->mime->filters,
-                                                                           
td->connection->socket,
-                                                                           
&nbw, 1))
+      ret = appHnd.loadLibrary (loadLib);
+      if (ret)
+        {
+          td->connection->host->warningsLogWrite (_("ISAPI: cannot load %s"), 
loadLib);
+          return td->http->raiseHTTPError (500);
+        }
+
+      connTable[connIndex].chain.setStream (td->connection->socket);
+      if (td->mime)
+        {
+          u_long nbw;
+          if (td->mime)
+            Server::getInstance ()->getFiltersFactory ()->chain (
+                                             &(connTable[connIndex].chain),
+                                             td->mime->filters,
+                                             td->connection->socket,
+                                             &nbw, 1);
+        }
+
+      connTable[connIndex].connection = td->connection;
+      connTable[connIndex].td = td;
+      connTable[connIndex].onlyHeader = onlyHeader;
+      connTable[connIndex].headerSent = 0;
+      connTable[connIndex].headerSize = 0;
+      connTable[connIndex].dataSent = 0;
+      connTable[connIndex].Allocated = 1;
+      connTable[connIndex].isapi = this;
+      connTable[connIndex].ISAPIDoneEvent = CreateEvent (NULL, 1, 0, NULL);
+
+      GetExtensionVersion = (PFN_GETEXTENSIONVERSION)appHnd.getProc 
("GetExtensionVersion");
+
+      if (GetExtensionVersion == NULL)
         {
           td->connection->host->warningsLogWrite (_("ISAPI: internal error"));
+          appHnd.close ();
           connTable[connIndex].chain.clearAllFilters ();
           return td->http->raiseHTTPError (500);
         }
-    }
 
-  connTable[connIndex].connection = td->connection;
-  connTable[connIndex].td = td;
-  connTable[connIndex].onlyHeader = onlyHeader;
-  connTable[connIndex].headerSent = 0;
-  connTable[connIndex].headerSize = 0;
-  connTable[connIndex].dataSent = 0;
-  connTable[connIndex].Allocated = 1;
-  connTable[connIndex].isapi = this;
-  connTable[connIndex].ISAPIDoneEvent = CreateEvent (NULL, 1, 0, NULL);
+      if (!GetExtensionVersion (&Ver))
+        {
+          td->connection->host->warningsLogWrite (_("ISAPI: internal error"));
+          appHnd.close ();
+          connTable[connIndex].chain.clearAllFilters ();
+          return td->http->raiseHTTPError (500);
+        }
 
-  GetExtensionVersion = (PFN_GETEXTENSIONVERSION)appHnd.getProc 
("GetExtensionVersion");
+      if (Ver.dwExtensionVersion > MAKELONG (HSE_VERSION_MINOR,
+                                             HSE_VERSION_MAJOR))
+        {
+          td->connection->host->warningsLogWrite (_("ISAPI: version not 
supported"));
+          appHnd.close ();
+          connTable[connIndex].chain.clearAllFilters ();
+          return td->http->raiseHTTPError (500);
+        }
 
-  if (GetExtensionVersion == NULL)
-    {
-      td->connection->host->warningsLogWrite (_("ISAPI: internal error"));
-      appHnd.close ();
-      connTable[connIndex].chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+      /* Store the environment string in the auxiliaryBuffer.  */
+      connTable[connIndex].envString=td->auxiliaryBuffer->getBuffer ();
+
+      /* Build the environment string.  */
+      td->scriptPath.assign (scriptpath);
+
+      string tmp;
+      tmp.assign (cgipath);
+      FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
+      tmp.assign (scriptpath);
+      FilesUtility::splitPath (tmp, td->scriptDir, td->scriptFile);
+
+      connTable[connIndex].envString[0] = '\0';
+      Env::buildEnvironmentString (td,connTable[connIndex].envString);
+
+      ZeroMemory (&ExtCtrlBlk, sizeof (ExtCtrlBlk));
+      ExtCtrlBlk.cbSize = sizeof (ExtCtrlBlk);
+      ExtCtrlBlk.dwVersion = MAKELONG (HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
+      ExtCtrlBlk.GetServerVariable = ISAPI_GetServerVariableExport;
+      ExtCtrlBlk.ReadClient  = ISAPI_ReadClientExport;
+      ExtCtrlBlk.WriteClient = ISAPI_WriteClientExport;
+      ExtCtrlBlk.ServerSupportFunction = ISAPI_ServerSupportFunctionExport;
+      ExtCtrlBlk.ConnID = (HCONN) (connIndex + 1);
+      ExtCtrlBlk.dwHttpStatusCode = 200;
+      ExtCtrlBlk.lpszLogData[0] = '0';
+      ExtCtrlBlk.lpszMethod = (char*) td->request.cmd.c_str ();
+      ExtCtrlBlk.lpszQueryString =(char*) td->request.uriOpts.c_str ();
+      ExtCtrlBlk.lpszPathInfo = (char*) (td->pathInfo.length ()
+                                         ? td->pathInfo.c_str ()
+                                         : "") ;
+      if (td->pathInfo.length ())
+        ExtCtrlBlk.lpszPathTranslated = (char*) td->pathTranslated.c_str ();
+      else
+        ExtCtrlBlk.lpszPathTranslated = (char*) td->filenamePath.c_str ();
+      ExtCtrlBlk.cbTotalBytes = td->inputData.getFileSize ();
+      ExtCtrlBlk.cbAvailable = 0;
+      ExtCtrlBlk.lpbData = 0;
 
-  if (!GetExtensionVersion (&Ver))
-    {
-      td->connection->host->warningsLogWrite (_("ISAPI: internal error"));
-      appHnd.close ();
-      connTable[connIndex].chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
 
-  if (Ver.dwExtensionVersion > MAKELONG (HSE_VERSION_MINOR,
-                                         HSE_VERSION_MAJOR))
-    {
-      td->connection->host->warningsLogWrite (_("ISAPI: version not 
supported"));
-      appHnd.close ();
-      connTable[connIndex].chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+      HttpRequestHeader::Entry *content = td->request.other.get 
("content-type");
+      ExtCtrlBlk.lpszContentType = content ? (char*)content->value->c_str () : 
NULL;
 
-  /* Store the environment string in the auxiliaryBuffer.  */
-  connTable[connIndex].envString=td->auxiliaryBuffer->getBuffer ();
+      connTable[connIndex].td->buffer->setLength (0);
+      connTable[connIndex].td->buffer->getAt (0)='\0';
+      HttpExtensionProc = (PFN_HTTPEXTENSIONPROC) appHnd.getProc 
("HttpExtensionProc");
+      if (HttpExtensionProc == NULL)
+        {
+          td->connection->host->warningsLogWrite (_("ISAPI: cannot find 
entry-point"));
+          appHnd.close ();
+          connTable[connIndex].chain.clearAllFilters ();
+          return td->http->raiseHTTPError (500);
+        }
 
-  /* Build the environment string.  */
-  td->scriptPath.assign (scriptpath);
+      ret = HttpExtensionProc (&ExtCtrlBlk);
+      if (ret == HSE_STATUS_PENDING)
+        WaitForSingleObject (connTable[connIndex].ISAPIDoneEvent, 
td->http->getTimeout ());
 
-  string tmp;
-  tmp.assign (cgipath);
-  FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
-  tmp.assign (scriptpath);
-  FilesUtility::splitPath (tmp, td->scriptDir, td->scriptFile);
-
-  connTable[connIndex].envString[0]='\0';
-  Env::buildEnvironmentString (td,connTable[connIndex].envString);
-
-  ZeroMemory (&ExtCtrlBlk, sizeof (ExtCtrlBlk));
-  ExtCtrlBlk.cbSize = sizeof (ExtCtrlBlk);
-  ExtCtrlBlk.dwVersion = MAKELONG (HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
-  ExtCtrlBlk.GetServerVariable = ISAPI_GetServerVariableExport;
-  ExtCtrlBlk.ReadClient  = ISAPI_ReadClientExport;
-  ExtCtrlBlk.WriteClient = ISAPI_WriteClientExport;
-  ExtCtrlBlk.ServerSupportFunction = ISAPI_ServerSupportFunctionExport;
-  ExtCtrlBlk.ConnID = (HCONN) (connIndex + 1);
-  ExtCtrlBlk.dwHttpStatusCode = 200;
-  ExtCtrlBlk.lpszLogData[0] = '0';
-  ExtCtrlBlk.lpszMethod = (char*)td->request.cmd.c_str ();
-  ExtCtrlBlk.lpszQueryString =(char*) td->request.uriOpts.c_str ();
-  ExtCtrlBlk.lpszPathInfo = td->pathInfo.length () ? (char*)td->pathInfo.c_str 
() : (CHAR*)"" ;
-  if (td->pathInfo.length ())
-    ExtCtrlBlk.lpszPathTranslated = (char*)td->pathTranslated.c_str ();
-  else
-    ExtCtrlBlk.lpszPathTranslated = (char*)td->filenamePath.c_str ();
-  ExtCtrlBlk.cbTotalBytes = td->inputData.getFileSize ();
-  ExtCtrlBlk.cbAvailable = 0;
-  ExtCtrlBlk.lpbData = 0;
+      u_long nbw = 0;
+      HttpRequestHeader::Entry *connection
+        = connTable[connIndex].td->request.other.get ("connection");
 
+      if (connection && !stringcmpi (connection->value->c_str (), 
"keep-alive"))
+        connTable[connIndex].chain.getStream ()->write ("0\r\n\r\n", 5, &nbw);
 
-  HttpRequestHeader::Entry *content = td->request.other.get ("content-type");
-  ExtCtrlBlk.lpszContentType = content ? (char*)content->value->c_str () : 
NULL;
+      switch (ret)
+        {
+        case HSE_STATUS_SUCCESS_AND_KEEP_CONN:
+          retvalue = HttpDataHandler::RET_OK;
+          break;
+
+        case 0:
+        case HSE_STATUS_SUCCESS:
+        case HSE_STATUS_ERROR:
+        default:
+          retvalue = HttpDataHandler::RET_FAILURE;
+          break;
+        }
 
-  connTable[connIndex].td->buffer->setLength (0);
-  connTable[connIndex].td->buffer->getAt (0)='\0';
-  HttpExtensionProc = (PFN_HTTPEXTENSIONPROC)appHnd.getProc 
("HttpExtensionProc");
-  if (HttpExtensionProc == NULL)
-    {
-      td->connection->host->warningsLogWrite (_("ISAPI: internal error"));
       appHnd.close ();
-      connTable[connIndex].chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
-
-  Ret = HttpExtensionProc (&ExtCtrlBlk);
-  if (Ret == HSE_STATUS_PENDING)
-    WaitForSingleObject (connTable[connIndex].ISAPIDoneEvent, 
td->http->getTimeout ());
 
-  {
-    u_long nbw = 0;
-    HttpRequestHeader::Entry *connection = 
connTable[connIndex].td->request.other.get ("connection");
-
-    if (connection && !stringcmpi (connection->value->c_str (), "keep-alive"))
-      Ret = connTable[connIndex].chain.getStream ()->write ("0\r\n\r\n", 5, 
&nbw);
-  }
+      ostringstream tmps;
+      tmps << connTable[connIndex].dataSent;
+      connTable[connIndex].td->response.contentLength.assign (tmps.str ());
+      connTable[connIndex].chain.clearAllFilters ();
+      connTable[connIndex].Allocated = 0;
 
-  switch (Ret)
+    }
+  catch (exception & e)
     {
-    case HSE_STATUS_SUCCESS_AND_KEEP_CONN:
-      retvalue = HttpDataHandler::RET_OK;
-      break;
-
-    case 0:
-    case HSE_STATUS_SUCCESS:
-    case HSE_STATUS_ERROR:
-    default:
-      retvalue = HttpDataHandler::RET_FAILURE;
-      break;
+      td->connection->host->warningsLogWrite (_E ("ISAPI: internal error"),
+                                              &e);
+      connTable[connIndex].chain.clearAllFilters ();
+      return td->http->raiseHTTPError (500);
     }
 
-  appHnd.close ();
-
-  ostringstream tmps;
-  tmps << connTable[connIndex].dataSent;
-  connTable[connIndex].td->response.contentLength.assign (tmps.str ());
-  connTable[connIndex].chain.clearAllFilters ();
-  connTable[connIndex].Allocated = 0;
   return retvalue;
 #else
   /*



commit fd7f3de29174b1ff29b064f9b45459b972de7dcf
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 15:48:10 2010 +0200

    Wincgi handles exceptions properly

diff --git a/myserver/src/http_handler/wincgi/wincgi.cpp 
b/myserver/src/http_handler/wincgi/wincgi.cpp
index 05154d0..143764e 100644
--- a/myserver/src/http_handler/wincgi/wincgi.cpp
+++ b/myserver/src/http_handler/wincgi/wincgi.cpp
@@ -84,350 +84,293 @@ int WinCgi::send (HttpThreadContext* td, const char* 
scriptpath,
   u_long nbw = 0;
   ostringstream stream;
 
-  if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
-    return td->http->sendAuth ();
+  try
+    {
+      if (! (td->permissions & MYSERVER_PERMISSION_EXECUTE))
+        return td->http->sendAuth ();
 
-  if (!FilesUtility::nodeExists (scriptpath))
-    return td->http->raiseHTTPError (404);
+      if (!FilesUtility::nodeExists (scriptpath))
+        return td->http->raiseHTTPError (404);
 
-  FilesUtility::splitPath (scriptpath, pathname, execname);
+      FilesUtility::splitPath (scriptpath, pathname, execname);
 
-  getdefaultwd (dataFilePath,MAX_PATH);
-  GetShortPathName (dataFilePath,dataFilePath,MAX_PATH);
-  sprintf (&dataFilePath[strlen (dataFilePath)],"/data_%u.ini",td->id);
+      getdefaultwd (dataFilePath,MAX_PATH);
+      GetShortPathName (dataFilePath,dataFilePath,MAX_PATH);
+      sprintf (&dataFilePath[strlen (dataFilePath)],"/data_%u.ini",td->id);
 
-  strcpy (outFilePath,td->outputDataPath.c_str ());
-  strcat (outFilePath,"WC");
-  td->inputData.seek (0);
-  chain.setStream (td->connection->socket);
-  if (td->mime)
-    {
-      u_long nbw2;
-      if (td->mime
-          && Server::getInstance ()->getFiltersFactory ()->chain (&chain,
-                                                       td->mime->filters,
-                                        td->connection->socket, &nbw2, 1))
+      strcpy (outFilePath,td->outputDataPath.c_str ());
+      strcat (outFilePath,"WC");
+      td->inputData.seek (0);
+      chain.setStream (td->connection->socket);
+      if (td->mime)
         {
-          td->connection->host->warningsLogWrite (_("WinCGI: internal error"));
-          chain.clearAllFilters ();
-          return td->http->raiseHTTPError (500);
+          u_long nbw2;
+          Server::getInstance ()->getFiltersFactory ()->chain (&chain,
+                                                          td->mime->filters,
+                                                        td->connection->socket,
+                                                               &nbw2, 1);
         }
-    }
 
-  /* The WinCGI protocol uses a .ini file to send data to the new process.  */
-  ret = DataFileHandle.openFile (dataFilePath, File::FILE_CREATE_ALWAYS
-                                 | File::WRITE);
-  if (ret)
-    {
-      td->connection->host->warningsLogWrite (_("WinCGI: internal error"));
-      return td->http->raiseHTTPError (500);
-    }
+      /* The WinCGI protocol uses a .ini file to send data to the new process. 
 */
+      DataFileHandle.openFile (dataFilePath, File::FILE_CREATE_ALWAYS
+                               | File::WRITE);
 
-  td->auxiliaryBuffer->setLength (0);
-  buffer = td->auxiliaryBuffer->getBuffer ();
-
-  strcpy (buffer, "[CGI]\r\n");
-  DataFileHandle.writeToFile (buffer,7,&nbr);
-
-  strcpy (buffer, "CGI Version=CGI/1.3a WIN\r\n");
-  DataFileHandle.writeToFile (buffer,26,&nbr);
-
-  *td->auxiliaryBuffer << "Server Admin=" <<
-    td->securityToken.getData ("server.admin", MYSERVER_VHOST_CONF |
-                                     MYSERVER_SERVER_CONF, "")<< "\r\n";
-  DataFileHandle.writeToFile (buffer,td->auxiliaryBuffer->getLength (),&nbr);
-
-  {
-    if (td->request.isKeepAlive ())
-      {
-        strcpy (buffer,"Request Keep-Alive=No\r\n");
-        DataFileHandle.writeToFile (buffer, 23, &nbr);
-      }
-    else
-      {
-        strcpy (buffer,"Request Keep-Alive=Yes\r\n");
-        DataFileHandle.writeToFile (buffer, 24, &nbr);
-      }
-  }
-
-  td->auxiliaryBuffer->setLength (0);
-  *td->auxiliaryBuffer << "Request Method=" << td->request.cmd << "\r\n";
-  DataFileHandle.writeToFile (buffer, td->auxiliaryBuffer->getLength (), &nbr);
-
-  td->auxiliaryBuffer->setLength (0);
-  *td->auxiliaryBuffer << "Request Protocol=HTTP/" << td->request.ver << 
"\r\n";
-  DataFileHandle.writeToFile (buffer, td->auxiliaryBuffer->getLength (), &nbr);
-
-  td->auxiliaryBuffer->setLength (0);
-  *td->auxiliaryBuffer << "Executable Path=" << execname << "\r\n";
-  DataFileHandle.writeToFile (buffer,td->auxiliaryBuffer->getLength (),&nbr);
-
-  if (td->request.uriOpts[0])
-    {
-      sprintf (buffer, "Query String=%s\r\n", td->request.uriOpts.c_str ());
-      DataFileHandle.writeToFile (buffer,(u_long)strlen (buffer), &nbr);
-    }
+      td->auxiliaryBuffer->setLength (0);
+      buffer = td->auxiliaryBuffer->getBuffer ();
 
-  {
-    HttpRequestHeader::Entry *referer = td->request.other.get ("referer");
+      strcpy (buffer, "[CGI]\r\n");
+      DataFileHandle.writeToFile (buffer,7,&nbr);
 
-    if (referer && referer->value->length ())
-      {
-        sprintf (buffer,"Referer=%s\r\n", referer->value->c_str ());
-        DataFileHandle.writeToFile (buffer,(u_long)strlen (buffer),&nbr);
-      }
-  }
+      strcpy (buffer, "CGI Version=CGI/1.3a WIN\r\n");
+      DataFileHandle.writeToFile (buffer,26,&nbr);
 
-  {
-    HttpRequestHeader::Entry *contentType = td->request.other.get 
("content-type");
+      *td->auxiliaryBuffer << "Server Admin=" <<
+        td->securityToken.getData ("server.admin", MYSERVER_VHOST_CONF |
+                                   MYSERVER_SERVER_CONF, "")<< "\r\n";
+      DataFileHandle.writeToFile (buffer,td->auxiliaryBuffer->getLength (), 
&nbr);
 
-    if (contentType && contentType->value->length ())
-      {
-        sprintf (buffer, "Content Type=%s\r\n", contentType->value->c_str ());
-        DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
-      }
-  }
+      if (td->request.isKeepAlive ())
+        {
+          strcpy (buffer,"Request Keep-Alive=No\r\n");
+          DataFileHandle.writeToFile (buffer, 23, &nbr);
+        }
+      else
+        {
+          strcpy (buffer,"Request Keep-Alive=Yes\r\n");
+          DataFileHandle.writeToFile (buffer, 24, &nbr);
+        }
 
-  {
-    HttpRequestHeader::Entry *userAgent = td->request.other.get ("user-agent");
+      td->auxiliaryBuffer->setLength (0);
+      *td->auxiliaryBuffer << "Request Method=" << td->request.cmd << "\r\n";
+      DataFileHandle.writeToFile (buffer, td->auxiliaryBuffer->getLength (), 
&nbr);
 
-    if (userAgent && userAgent->value->length ())
-      {
-        sprintf (buffer,"User Agent=%s\r\n", userAgent->value->c_str ());
-        DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
-      }
-  }
+      td->auxiliaryBuffer->setLength (0);
+      *td->auxiliaryBuffer << "Request Protocol=HTTP/" << td->request.ver << 
"\r\n";
+      DataFileHandle.writeToFile (buffer, td->auxiliaryBuffer->getLength (), 
&nbr);
 
-  sprintf (buffer,"Content File=%s\r\n", td->inputData.getFilename ());
-  DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
+      td->auxiliaryBuffer->setLength (0);
+      *td->auxiliaryBuffer << "Executable Path=" << execname << "\r\n";
+      DataFileHandle.writeToFile (buffer,td->auxiliaryBuffer->getLength 
(),&nbr);
 
-  if (td->request.contentLength[0])
-    {
-      sprintf (buffer, "Content Length=%s\r\n",
-              td->request.contentLength.c_str ());
-      DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
-    }
-  else
-    {
-      strcpy (buffer, "Content Length=0\r\n");
-      DataFileHandle.writeToFile (buffer, 18, &nbr);
-    }
+      if (td->request.uriOpts[0])
+        {
+          sprintf (buffer, "Query String=%s\r\n", td->request.uriOpts.c_str 
());
+          DataFileHandle.writeToFile (buffer,(u_long) strlen (buffer), &nbr);
+        }
 
-  strcpy (buffer,"Server Software=MyServer\r\n");
-  DataFileHandle.writeToFile (buffer, 26, &nbr);
+      HttpRequestHeader::Entry *referer = td->request.other.get ("referer");
+      if (referer && referer->value->length ())
+        {
+          sprintf (buffer,"Referer=%s\r\n", referer->value->c_str ());
+          DataFileHandle.writeToFile (buffer,(u_long) strlen (buffer),&nbr);
+        }
 
-  sprintf (buffer, "Remote Address=%s\r\n", td->connection->getIpAddr ());
-  DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
+      HttpRequestHeader::Entry *contentType = td->request.other.get 
("content-type");
+      if (contentType && contentType->value->length ())
+        {
+          sprintf (buffer, "Content Type=%s\r\n", contentType->value->c_str 
());
+          DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
+        }
 
-  sprintf (buffer, "Server Port=%u\r\n", td->connection->getLocalPort ());
-  DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
+      HttpRequestHeader::Entry *userAgent = td->request.other.get 
("user-agent");
+      if (userAgent && userAgent->value->length ())
+        {
+          sprintf (buffer,"User Agent=%s\r\n", userAgent->value->c_str ());
+          DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
+        }
 
-  {
-    HttpRequestHeader::Entry *host = td->request.other.get ("host");
-    if (host)
-      sprintf (buffer, "Server Name=%s\r\n", host->value->c_str ());
-    DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
-  }
+      sprintf (buffer,"Content File=%s\r\n", td->inputData.getFilename ());
+      DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
 
-  strcpy (buffer, "[System]\r\n");
-  DataFileHandle.writeToFile (buffer, 10, &nbr);
+      if (td->request.contentLength[0])
+        {
+          sprintf (buffer, "Content Length=%s\r\n",
+                   td->request.contentLength.c_str ());
+          DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
+        }
+      else
+        {
+          strcpy (buffer, "Content Length=0\r\n");
+          DataFileHandle.writeToFile (buffer, 18, &nbr);
+        }
 
-  sprintf (buffer, "Output File=%s\r\n", outFilePath);
-  DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
+      strcpy (buffer,"Server Software=MyServer\r\n");
+      DataFileHandle.writeToFile (buffer, 26, &nbr);
 
-  sprintf (buffer,"Content File=%s\r\n", td->inputData.getFilename ());
-  DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
+      sprintf (buffer, "Remote Address=%s\r\n", td->connection->getIpAddr ());
+      DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
 
-  /*
-   *Compute the local offset from the GMT time
-   */
-  {
-    tm tmpTm;
-    ltime = 100;
-    gmhour = myserver_gmtime ( &ltime, &tmpTm)->tm_hour;
-    bias = myserver_localtime (&ltime, &tmpTm)->tm_hour - gmhour;
-  }
-  sprintf (buffer, "GMT Offset=%i\r\n", bias);
-  DataFileHandle.writeToFile (buffer, (u_long)strlen (buffer), &nbr);
+      sprintf (buffer, "Server Port=%u\r\n", td->connection->getLocalPort ());
+      DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
 
-  sprintf (buffer, "Debug Mode=No\r\n", bias);
-  DataFileHandle.writeToFile (buffer, 15, &nbr);
+      HttpRequestHeader::Entry *host = td->request.other.get ("host");
+      if (host)
+        sprintf (buffer, "Server Name=%s\r\n", host->value->c_str ());
+      DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
 
-  DataFileHandle.close ();
+      strcpy (buffer, "[System]\r\n");
+      DataFileHandle.writeToFile (buffer, 10, &nbr);
 
-  /*
-   *Create the out file.
-   */
-  if (!FilesUtility::nodeExists (outFilePath))
-    {
-      ret = OutFileHandle.openFile (outFilePath, File::FILE_CREATE_ALWAYS);
-      if (ret)
-        {
-          td->connection->host->warningsLogWrite (_("WinCGI: internal error"));
-          DataFileHandle.close ();
-          FilesUtility::deleteFile (outFilePath);
-          FilesUtility::deleteFile (dataFilePath);
-          chain.clearAllFilters ();
-          return td->http->raiseHTTPError (500);
-        }
-    }
-  OutFileHandle.close ();
-  spi.cmdLine.assign ("cmd /c \"");
-  spi.cmdLine.append (scriptpath);
-  spi.cmdLine.append ("\" ");
-  spi.cmdLine.append (dataFilePath);
-  spi.cwd.assign (pathname);
-  spi.envString = 0;
-  if (proc.exec (&spi, true))
-    {
-      td->connection->host->warningsLogWrite (_("WinCGI: error executing %s"), 
scriptpath);
+      sprintf (buffer, "Output File=%s\r\n", outFilePath);
+      DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
 
-      FilesUtility::deleteFile (outFilePath);
-      FilesUtility::deleteFile (dataFilePath);
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+      sprintf (buffer,"Content File=%s\r\n", td->inputData.getFilename ());
+      DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
 
-  ret=OutFileHandle.openFile (outFilePath, File::FILE_OPEN_ALWAYS|
-                              File::READ);
-  if (ret)
-    {
-      ostringstream msg;
-      msg << "WinCGI: Error opening output file " << outFilePath;
-      td->connection->host->warningsLogWrite (msg.str ().c_str ());
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
-  OutFileHandle.read (buffer,td->auxiliaryBuffer->getRealLength 
(),&nBytesRead);
-  if (!nBytesRead)
-    {
-      ostringstream msg;
-      msg << "WinCGI: Error zero bytes read from the WinCGI output file "
-          << outFilePath;
-      td->connection->host->warningsLogWrite (msg.str ().c_str ());
-      OutFileHandle.close ();
-      FilesUtility::deleteFile (outFilePath);
-      FilesUtility::deleteFile (dataFilePath);
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+      /*
+       *Compute the local offset from the GMT time
+       */
+      tm tmpTm;
+      ltime = 100;
+      gmhour = myserver_gmtime ( &ltime, &tmpTm)->tm_hour;
+      bias = myserver_localtime (&ltime, &tmpTm)->tm_hour - gmhour;
 
-  for (u_long i = 0; i < nBytesRead; i++)
-    {
-      if ((buffer[i] == '\r') && (buffer[i+1] == '\n')
-         &&(buffer[i+2] == '\r') && (buffer[i+3] == '\n'))
-        {
-          /*
-           *The HTTP header ends with a \r\n\r\n sequence so
-           *determinate where it ends and set the header size
-           *to i + 4.
-           */
-          headerSize = i + 4;
-          break;
-        }
-    }
+      sprintf (buffer, "GMT Offset=%i\r\n", bias);
+      DataFileHandle.writeToFile (buffer, (u_long) strlen (buffer), &nbr);
 
-  if (td->request.isKeepAlive ())
-    td->response.setValue ("connection", "keep-alive");
+      sprintf (buffer, "Debug Mode=No\r\n", bias);
+      DataFileHandle.writeToFile (buffer, 15, &nbr);
 
-  HttpHeaders::buildHTTPResponseHeaderStruct (buffer, &td->response, 
&(td->nBytesToRead));
+      DataFileHandle.close ();
 
-  /*
-   *Always specify the size of the HTTP contents.
-   */
-  stream << OutFileHandle.getFileSize () - headerSize;
-  td->response.contentLength.assign (stream.str ());
-  if (!td->appendOutputs)
-    {
-      if (HttpHeaders::sendHeader (td->response, *chain.getStream (),
-                                   *td->buffer, td))
+      /*
+       *Create the out file.
+       */
+      if (! FilesUtility::nodeExists (outFilePath))
+        OutFileHandle.openFile (outFilePath, File::FILE_CREATE_ALWAYS
+                                | File::WRITE);
+
+      OutFileHandle.close ();
+      spi.cmdLine.assign ("cmd /c \"");
+      spi.cmdLine.append (scriptpath);
+      spi.cmdLine.append ("\" ");
+      spi.cmdLine.append (dataFilePath);
+      spi.cwd.assign (pathname);
+      spi.envString = 0;
+      try
         {
-          OutFileHandle.close ();
+          proc.exec (&spi, true);
+        }
+      catch (exception & e)
+        {
+          td->connection->host->warningsLogWrite (_E ("WinCGI: error executing 
%s"),
+                                                  scriptpath, &e);
           FilesUtility::deleteFile (outFilePath);
           FilesUtility::deleteFile (dataFilePath);
           chain.clearAllFilters ();
-          return HttpDataHandler::RET_FAILURE;
+          return td->http->raiseHTTPError (500);
         }
 
-      if (onlyHeader)
+      OutFileHandle.openFile (outFilePath, File::FILE_OPEN_ALWAYS | 
File::READ);
+      OutFileHandle.read (buffer,td->auxiliaryBuffer->getRealLength (), 
&nBytesRead);
+      if (! nBytesRead)
         {
+          ostringstream msg;
+          msg << "WinCGI: Error zero bytes read from the WinCGI output file "
+              << outFilePath;
+          td->connection->host->warningsLogWrite (msg.str ().c_str ());
           OutFileHandle.close ();
           FilesUtility::deleteFile (outFilePath);
           FilesUtility::deleteFile (dataFilePath);
           chain.clearAllFilters ();
-          return HttpDataHandler::RET_OK;
+          return td->http->raiseHTTPError (500);
         }
 
-      u_long written;
-      chain.write ((char*)(buffer + headerSize), nBytesRead - headerSize,
-                   &written);
-      nbw += written;
-    }
-  else
-    {
-      u_long nbw2;
-      HttpHeaders::buildHTTPResponseHeader (td->buffer->getBuffer (),
-                                            &td->response);
-      if (onlyHeader)
+      for (u_long i = 0; i < nBytesRead; i++)
         {
-          chain.clearAllFilters ();
-          return HttpDataHandler::RET_OK;
+          if ((buffer[i] == '\r') && (buffer[i+1] == '\n')
+              &&(buffer[i+2] == '\r') && (buffer[i+3] == '\n'))
+            {
+              /*
+                The HTTP header ends with a \r\n\r\n sequence so
+                determinate where it ends and set the header size
+                to i + 4.
+               */
+              headerSize = i + 4;
+              break;
+            }
         }
 
-      td->outputData.writeToFile ((char*)(buffer + headerSize),
-                                  nBytesRead - headerSize,
-                                  &nbw2);
-      nbw += nbw2;
-    }
+      if (td->request.isKeepAlive ())
+        td->response.setValue ("connection", "keep-alive");
 
-  if (td->response.getStatusType () == HttpResponseHeader::SUCCESSFUL)
-    {
-      /* Flush the rest of the file.  */
-      do
+      HttpHeaders::buildHTTPResponseHeaderStruct (buffer, &td->response, 
&(td->nBytesToRead));
+
+      /*
+       *Always specify the size of the HTTP contents.
+       */
+      stream << OutFileHandle.getFileSize () - headerSize;
+      td->response.contentLength.assign (stream.str ());
+      if (!td->appendOutputs)
+        {
+          HttpHeaders::sendHeader (td->response, *chain.getStream (),
+                                   *td->buffer, td);
+
+          if (onlyHeader)
+            {
+              OutFileHandle.close ();
+              FilesUtility::deleteFile (outFilePath);
+              FilesUtility::deleteFile (dataFilePath);
+              chain.clearAllFilters ();
+              return HttpDataHandler::RET_OK;
+            }
+
+          u_long written;
+          chain.write ((char*)(buffer + headerSize), nBytesRead - headerSize,
+                       &written);
+          nbw += written;
+        }
+      else
         {
-          OutFileHandle.read (buffer, td->auxiliaryBuffer->getLength (),
-                             &nBytesRead);
-          if (nBytesRead)
+          u_long nbw2;
+          HttpHeaders::buildHTTPResponseHeader (td->buffer->getBuffer (),
+                                                &td->response);
+          if (onlyHeader)
             {
-              int ret;
+              chain.clearAllFilters ();
+              return HttpDataHandler::RET_OK;
+            }
+
+          td->outputData.writeToFile ((char*) (buffer + headerSize),
+                                      nBytesRead - headerSize,
+                                      &nbw2);
+          nbw += nbw2;
+        }
+
+      if (td->response.getStatusType () == HttpResponseHeader::SUCCESSFUL)
+        {
+          /* Flush the rest of the file.  */
+          do
+            {
+              OutFileHandle.read (buffer, td->auxiliaryBuffer->getLength (),
+                                  &nBytesRead);
+              if (! nBytesRead)
+                break;
+
               if (td->appendOutputs)
-                {
-                  ret = td->outputData.writeToFile (buffer, nBytesRead, &nbw);
-                  if (ret)
-                    {
-                      OutFileHandle.close ();
-                      FilesUtility::deleteFile (outFilePath);
-                      FilesUtility::deleteFile (dataFilePath);
-                      chain.clearAllFilters ();
-                      return HttpDataHandler::RET_FAILURE;
-                    }
-                }
+                td->outputData.writeToFile (buffer, nBytesRead, &nbw);
               else
                 {
                   u_long nbw2;
-                  ret = chain.write ((char*)buffer, nBytesRead, &nbw2);
-                  if (ret == -1)
-                    {
-                      OutFileHandle.close ();
-                      FilesUtility::deleteFile (outFilePath);
-                      FilesUtility::deleteFile (dataFilePath);
-                      chain.clearAllFilters ();
-                      return HttpDataHandler::RET_FAILURE;
-                    }
+                  chain.write ((char*) buffer, nBytesRead, &nbw2);
                 }
             }
-          else
-            break;
+          while (nBytesRead);
+        }
+      td->sentData += nbw;
 
-        }while (nBytesRead);
+      chain.clearAllFilters ();
+      OutFileHandle.close ();
+      FilesUtility::deleteFile (outFilePath);
+      FilesUtility::deleteFile (dataFilePath);
+    }
+  catch (exception & e)
+    {
+      td->connection->host->warningsLogWrite (_E ("WinCGI: internal error",
+                                                  &e));
+      chain.clearAllFilters ();
+      return td->http->raiseHTTPError (500);
     }
-  td->sentData += nbw;
-
-  chain.clearAllFilters ();
-  OutFileHandle.close ();
-  FilesUtility::deleteFile (outFilePath);
-  FilesUtility::deleteFile (dataFilePath);
-
   return HttpDataHandler::RET_OK;
 #else
   td->connection->host->warningsLogWrite (_("WinCGI: not implemented"));



commit 5fb4cd0ee8856d0dd111aa850f5448b641d685f8
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 15:03:42 2010 +0200

    Proxy handles exceptions properly

diff --git a/myserver/src/http_handler/proxy/proxy.cpp 
b/myserver/src/http_handler/proxy/proxy.cpp
index 97ba057..3f96454 100644
--- a/myserver/src/http_handler/proxy/proxy.cpp
+++ b/myserver/src/http_handler/proxy/proxy.cpp
@@ -68,68 +68,63 @@ int Proxy::send (HttpThreadContext *td,
       return td->http->raiseHTTPError (500);
     }
 
-  req.ver.assign ("HTTP/1.1");
-  req.cmd.assign (td->request.cmd);
-  req.uri.assign ("/");
-  req.uri.append (destUrl.getResource ());
-  req.uri.append (td->pathInfo);
-  req.setValue ("Connection", "Close");
+  try
+    {
+      req.ver.assign ("HTTP/1.1");
+      req.cmd.assign (td->request.cmd);
+      req.uri.assign ("/");
+      req.uri.append (destUrl.getResource ());
+      req.uri.append (td->pathInfo);
+      req.setValue ("Connection", "Close");
 
-  ostringstream host;
-  host << destUrl.getHost ();
-  if (destUrl.getPort () != 80 )
-    host << ":" << destUrl.getPort ();
+      ostringstream host;
+      host << destUrl.getHost ();
+      if (destUrl.getPort () != 80 )
+        host << ":" << destUrl.getPort ();
 
-  req.setValue ("Host", host.str ().c_str ());
+      req.setValue ("Host", host.str ().c_str ());
 
-  string xForwardedFor;
-  td->request.getValue ("X-Forwarded-For", &xForwardedFor);
-  if (xForwardedFor.size ())
-    xForwardedFor.append (", ");
-  xForwardedFor.append (td->connection->getIpAddr ());
-  req.setValue ("X-Forwarded-For", xForwardedFor.c_str ());
+      string xForwardedFor;
+      td->request.getValue ("X-Forwarded-For", &xForwardedFor);
+      if (xForwardedFor.size ())
+        xForwardedFor.append (", ");
+      xForwardedFor.append (td->connection->getIpAddr ());
+      req.setValue ("X-Forwarded-For", xForwardedFor.c_str ());
 
-  if (sock.connect (destUrl.getHost ().c_str (), destUrl.getPort ()))
-    return td->http->raiseHTTPError (500);
+      sock.connect (destUrl.getHost ().c_str (), destUrl.getPort ());
 
-  u_long hdrLen =
-    HttpHeaders::buildHTTPRequestHeader (td->auxiliaryBuffer->getBuffer (),
-                                         &req);
+      u_long hdrLen =
+        HttpHeaders::buildHTTPRequestHeader (td->auxiliaryBuffer->getBuffer (),
+                                             &req);
 
 
-  if (sock.write (td->auxiliaryBuffer->getBuffer (), hdrLen, &nbw))
-    {
-      chain.clearAllFilters ();
-      return HttpDataHandler::RET_FAILURE;
-    }
+      sock.write (td->auxiliaryBuffer->getBuffer (), hdrLen, &nbw);
 
-  if (td->request.uriOptsPtr &&
-      td->inputData.fastCopyToSocket (&sock, 0, td->auxiliaryBuffer, &nbw))
-    {
-      sock.close ();
-      return td->http->raiseHTTPError (500);
-    }
+      if (td->request.uriOptsPtr)
+        td->inputData.fastCopyToSocket (&sock, 0, td->auxiliaryBuffer, &nbw);
 
-  chain.setStream (td->connection->socket);
+      chain.setStream (td->connection->socket);
+      if (td->mime)
+        Server::getInstance ()->getFiltersFactory ()->chain (&chain,
+                                                             td->mime->filters,
+                                                             
td->connection->socket,
+                                                             &nbw,
+                                                             1);
 
-  if (td->mime
-      && Server::getInstance ()->getFiltersFactory ()->chain (&chain,
-                                                              
td->mime->filters,
-                                                         
td->connection->socket,
-                                                              &nbw,
-                                                              1))
-    {
+
+      flushToClient (td, sock, chain, onlyHeader);
+
+      chain.clearAllFilters ();
       sock.close ();
+      req.free ();
+    }
+  catch (exception & e)
+    {
+      chain.clearAllFilters ();
       return td->http->raiseHTTPError (500);
     }
 
-  int ret = flushToClient (td, sock, chain, onlyHeader);
-
-  chain.clearAllFilters ();
-  sock.close ();
-  req.free ();
-
-  return ret;
+  return HttpDataHandler::RET_OK;
 }
 
 /*!
@@ -151,8 +146,6 @@ int Proxy::flushToClient (HttpThreadContext* td, Socket& 
client,
                          td->auxiliaryBuffer->getRealLength () - read,
                          0,
                          td->http->getTimeout ());
-      if (ret < 0)
-        return td->http->raiseHTTPError (500);
 
       read += ret;
 
@@ -193,27 +186,16 @@ int Proxy::flushToClient (HttpThreadContext* td, Socket& 
client,
   u_long hdrLen = HttpHeaders::buildHTTPResponseHeader (td->buffer->getBuffer 
(),
                                                         &td->response);
 
-  if (out.getStream ()->write (td->buffer->getBuffer (),
-                               hdrLen,
-                               &nbw))
-    return HttpDataHandler::RET_FAILURE;
+  out.getStream ()->write (td->buffer->getBuffer (), hdrLen, &nbw);
 
   if (onlyHeader)
     return HttpDataHandler::RET_OK;
 
-  ret = readPayLoad (td,
-                     &td->response,
-                     &out,
-                     &client,
-                     td->auxiliaryBuffer->getBuffer () + headerLength,
-                     read - headerLength,
-                     td->http->getTimeout (),
-                     useChunks,
-                     keepalive,
-                     hasTransferEncoding ? &transferEncoding : NULL);
-
-  if (ret == -1)
-    return HttpDataHandler::RET_FAILURE;
+  readPayLoad (td, &td->response, &out, &client,
+               td->auxiliaryBuffer->getBuffer () + headerLength,
+               read - headerLength, td->http->getTimeout (),
+               useChunks, keepalive,
+               hasTransferEncoding ? &transferEncoding : NULL);
 
   td->sentData += ret;
   return HttpDataHandler::RET_OK;
@@ -273,84 +255,63 @@ int Proxy::readPayLoad (HttpThreadContext* td,
 
   /* If it is specified a transfer encoding read data using it.  */
   if (serverTransferEncoding)
-  {
-    if (!serverTransferEncoding->compare ("chunked"))
     {
-      for (;;)
+      if (!serverTransferEncoding->compare ("chunked"))
         {
-          if (HttpDataRead::readChunkedPostData (initBuffer,
-                                                 &inPos,
-                                                 initBufferSize,
-                                                 client,
-                                                 td->buffer->getBuffer (),
+          for (;;)
+            {
+              HttpDataRead::readChunkedPostData (initBuffer, &inPos, 
initBufferSize,
+                                                 client, td->buffer->getBuffer 
(),
                                                  td->buffer->getRealLength () 
- 1,
-                                                 &nbr,
-                                                 timeout,
-                                                 NULL,
-                                                 1))
-            return HttpDataHandler::RET_FAILURE;
+                                                 &nbr, timeout, NULL, 1);
 
-          if (!nbr)
-            break;
+              if (!nbr)
+                break;
 
-          if (HttpDataHandler::appendDataToHTTPChannel (td,
+              HttpDataHandler::appendDataToHTTPChannel (td,
                                                         td->buffer->getBuffer 
(),
-                                                        nbr,
-                                                        &(td->outputData),
-                                                        out,
-                                                        td->appendOutputs,
-                                                        useChunks))
-            return HttpDataHandler::RET_FAILURE;
-
-          written += nbr;
+                                                        nbr, &(td->outputData),
+                                                        out, td->appendOutputs,
+                                                        useChunks);
+              written += nbr;
+            }
         }
     }
-  }
-  /* If it is not specified an encoding, read the data as it is.  */
-  else for (;;)
-  {
-
-    u_long len = td->buffer->getRealLength () - 1;
-
-    if (contentLength && length < len)
-      len = length;
-
-    if (len == 0)
-      break;
-
-    if (HttpDataRead::readContiguousPrimitivePostData (initBuffer,
-                                                      &inPos,
-                                                      initBufferSize,
-                                                      client,
-                                                      td->buffer->getBuffer (),
-                                                      len,
-                                                      &nbr,
-                                                      timeout))
-      return HttpDataHandler::RET_FAILURE;
+  else
+    {
+      /* If it is not specified an encoding, read the data as it is.  */
+      for (;;)
+        {
+          u_long len = td->buffer->getRealLength () - 1;
 
-    if (contentLength == 0 && nbr == 0)
-      break;
+          if (contentLength && length < len)
+            len = length;
 
-    if (length)
-      length -= nbr;
+          if (len == 0)
+            break;
 
-    if (nbr && HttpDataHandler::appendDataToHTTPChannel (td,
+          HttpDataRead::readContiguousPrimitivePostData (initBuffer, &inPos,
+                                                         initBufferSize, 
client,
                                                          td->buffer->getBuffer 
(),
-                                                         nbr,
-                                                         &(td->outputData),
-                                                         out,
-                                                         td->appendOutputs,
-                                                         useChunks))
-      return HttpDataHandler::RET_FAILURE;
+                                                         len, &nbr, timeout);
 
-    written += nbr;
+          if (contentLength == 0 && nbr == 0)
+            break;
 
-    if (contentLength && length == 0)
-      break;
-  }
+          if (length)
+            length -= nbr;
 
-  if (useChunks && out->getStream ()->write ("0\r\n\r\n", 5, &nbw))
-    return HttpDataHandler::RET_FAILURE;
+          HttpDataHandler::appendDataToHTTPChannel (td, td->buffer->getBuffer 
(),
+                                                    nbr, &(td->outputData), 
out,
+                                                    td->appendOutputs, 
useChunks);
+          written += nbr;
+
+          if (contentLength && length == 0)
+            break;
+        }
+    }
+  if (useChunks)
+    out->getStream ()->write ("0\r\n\r\n", 5, &nbw);
 
-  return written;
+  return HttpDataHandler::RET_OK;
 }



commit 0442cc1ea679e7e02067103dd97d0a4ffc06a26d
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 14:47:20 2010 +0200

    Scgi handles exceptions properly

diff --git a/myserver/src/http_handler/scgi/scgi.cpp 
b/myserver/src/http_handler/scgi/scgi.cpp
index f75b0b1..08bca7e 100644
--- a/myserver/src/http_handler/scgi/scgi.cpp
+++ b/myserver/src/http_handler/scgi/scgi.cpp
@@ -47,8 +47,6 @@ int Scgi::send (HttpThreadContext* td, const char* scriptpath,
   ScgiContext con;
   FiltersChain chain;
 
-  int ret;
-
   string outDataPath;
 
   int sizeEnvString;
@@ -60,159 +58,153 @@ int Scgi::send (HttpThreadContext* td, const char* 
scriptpath,
 
   td->scriptPath.assign (scriptpath);
 
-  if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
-    return td->http->sendAuth ();
-
-  {
-    string tmp;
-    tmp.assign (cgipath);
-    FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
-    tmp.assign (scriptpath);
-    FilesUtility::splitPath (tmp, td->scriptDir, td->scriptFile);
-  }
-
-  chain.setStream (td->connection->socket);
-  if (td->mime)
-  {
-    u_long nbw;
-    if (td->mime && Server::getInstance ()->getFiltersFactory ()->chain 
(&chain,
-                                                    td->mime->filters,
-                                                    td->connection->socket,
-                                                    &nbw,
-                                                    1))
-    {
-      td->connection->host->warningsLogWrite (_("SCGI: internal error"));
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
-  }
-
-  td->buffer->setLength (0);
-  td->auxiliaryBuffer->getAt (0) = '\0';
-
-  {
-    /* Do not modify the text between " and ".  */
-    int i;
-    int subString = cgipath[0] == '"';
-    int len = strlen (cgipath);
-    string tmpCgiPath;
-    for (i = 1; i < len; i++)
-    {
-      if (!subString && cgipath[i]==' ')
-        break;
-      if (cgipath[i] == '"' && cgipath[i - 1] != '\\')
-        subString = !subString;
-    }
-    /*!
-      Save the cgi path and the possible arguments.
-      the (x < len) case is when additional arguments are specified.
-      If the cgipath is enclosed between " and " do not consider them
-      when splitting directory and file name.
-     */
-    if (len)
+  try
     {
-      if (i < len)
-      {
-        string tmpString (cgipath);
-        int begin = tmpString[0]=='"' ? 1: 0;
-        int end = tmpString[i] == '"' ? i - 1: i;
-        tmpCgiPath.assign (tmpString.substr (begin, end - begin));
-        moreArg.assign (tmpString.substr (i, len - 1));
-      }
-      else
-      {
-        int begin = (cgipath[0] == '"') ? 1 : 0;
-        int end   = (cgipath[len] == '"') ? len - 1 : len;
-        tmpCgiPath.assign (&cgipath[begin], end - begin);
-        moreArg.assign ("");
-      }
-      FilesUtility::splitPath (tmpCgiPath, td->cgiRoot, td->cgiFile);
-    }
-    tmpCgiPath.assign (scriptpath);
-    FilesUtility::splitPath (tmpCgiPath, td->scriptDir, td->scriptFile);
-  }
+      string tmp;
+      if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
+        return td->http->sendAuth ();
+
+      tmp.assign (cgipath);
+      FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
+      tmp.assign (scriptpath);
+      FilesUtility::splitPath (tmp, td->scriptDir, td->scriptFile);
+
+      chain.setStream (td->connection->socket);
+      if (td->mime)
+        {
+          u_long nbw;
+          if (td->mime)
+            Server::getInstance ()->getFiltersFactory ()->chain (&chain,
+                                                                 
td->mime->filters,
+                                                                 
td->connection->socket,
+                                                                 &nbw,
+                                                                 1);
+        }
+
+      td->buffer->setLength (0);
+      td->auxiliaryBuffer->getAt (0) = '\0';
 
-  if (execute)
-  {
-    if (cgipath && strlen (cgipath))
-    {
-#ifdef WIN32
       {
-        int x;
-        string cgipathString (cgipath);
-        int len = strlen (cgipath);
+        /* Do not modify the text between " and ".  */
+        int i;
         int subString = cgipath[0] == '"';
+        int len = strlen (cgipath);
+        string tmpCgiPath;
+        for (i = 1; i < len; i++)
+          {
+            if (!subString && cgipath[i]==' ')
+              break;
+            if (cgipath[i] == '"' && cgipath[i - 1] != '\\')
+              subString = !subString;
+          }
 
-        cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile << "\" "
-                << moreArg << " \"" <<  td->filenamePath << "\"";
+        /*
+          Save the cgi path and the possible arguments.
+          the (x < len) case is when additional arguments are specified.
+          If the cgipath is enclosed between " and " do not consider them
+          when splitting directory and file name.
+        */
+        if (len)
+          {
+            if (i < len)
+              {
+                string tmpString (cgipath);
+                int begin = tmpString[0]=='"' ? 1: 0;
+                int end = tmpString[i] == '"' ? i - 1: i;
+                tmpCgiPath.assign (tmpString.substr (begin, end - begin));
+                moreArg.assign (tmpString.substr (i, len - 1));
+              }
+            else
+              {
+                int begin = (cgipath[0] == '"') ? 1 : 0;
+                int end   = (cgipath[len] == '"') ? len - 1 : len;
+                tmpCgiPath.assign (&cgipath[begin], end - begin);
+                moreArg.assign ("");
+              }
+            FilesUtility::splitPath (tmpCgiPath, td->cgiRoot, td->cgiFile);
+          }
+        tmpCgiPath.assign (scriptpath);
+        FilesUtility::splitPath (tmpCgiPath, td->scriptDir, td->scriptFile);
       }
+
+      if (execute)
+        {
+          if (cgipath && strlen (cgipath))
+            {
+#ifdef WIN32
+              {
+                int x;
+                string cgipathString (cgipath);
+                int len = strlen (cgipath);
+                int subString = cgipath[0] == '"';
+
+                cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile << "\" "
+                        << moreArg << " \"" <<  td->filenamePath << "\"";
+              }
 #else
-       cmdLine << cgipath << " " << td->filenamePath;
+              cmdLine << cgipath << " " << td->filenamePath;
 #endif
-    }/*if (execute).  */
-    else
-    {
-      cmdLine << scriptpath;
-    }
-  }
-  else
-  {
+            }/*if (execute).  */
+          else
+            {
+              cmdLine << scriptpath;
+            }
+        }
+      else
+        {
 #ifdef WIN32
-    cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile
-            << "\" " << moreArg;
+          cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile
+                  << "\" " << moreArg;
 #else
-    cmdLine << cgipath;
+          cmdLine << cgipath;
 #endif
-  }
-
-  Env::buildEnvironmentString (td, td->buffer->getBuffer ());
-  sizeEnvString = buildScgiEnvironmentString (td,td->buffer->getBuffer (),
-                                             td->auxiliaryBuffer->getBuffer 
());
-  if (sizeEnvString == -1)
-  {
-    td->connection->host->warningsLogWrite (_("SCGI: internal error"));
-    chain.clearAllFilters ();
-    return td->http->raiseHTTPError (500);
-  }
-  td->inputData.close ();
-  if (td->inputData.openFile (td->inputDataPath, File::READ |
-                            File::FILE_OPEN_ALWAYS |
-                            File::NO_INHERIT))
-  {
-    td->connection->host->warningsLogWrite (_("SCGI: internal error"));
-    chain.clearAllFilters ();
-    return td->http->raiseHTTPError (500);
-  }
-
-  server = connect (&con, cmdLine.str ().c_str ());
-
-  if (server == 0)
-  {
-    td->connection->host->warningsLogWrite (_("SCGI: error connecting to the 
process %s"),
-                                           cmdLine.str ().c_str ());
-    chain.clearAllFilters ();
-    return td->http->raiseHTTPError (500);
-  }
-  ret = sendNetString (&con, td->auxiliaryBuffer->getBuffer (), sizeEnvString);
-
-  if (td->request.contentLength.size () &&
-     !td->request.contentLength.compare ("0"))
-  {
-    if (sendPostData (&con))
-     {
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
-  }
+        }
+
+      Env::buildEnvironmentString (td, td->buffer->getBuffer ());
+      sizeEnvString = buildScgiEnvironmentString (td,td->buffer->getBuffer (),
+                                                  
td->auxiliaryBuffer->getBuffer ());
+      if (sizeEnvString == -1)
+        {
+          td->connection->host->warningsLogWrite (_("SCGI: internal error"));
+          chain.clearAllFilters ();
+          return td->http->raiseHTTPError (500);
+        }
+      td->inputData.close ();
+      td->inputData.openFile (td->inputDataPath, File::READ
+                              | File::FILE_OPEN_ALWAYS | File::NO_INHERIT);
 
-  ret = sendResponse (&con, onlyHeader, &chain);
+      try
+        {
+          server = connect (&con, cmdLine.str ().c_str ());
+        }
+      catch (exception & e)
+        {
+          td->connection->host->warningsLogWrite
+            (_E ("SCGI: error connecting to the process %s"),
+             cmdLine.str ().c_str (), &e);
+          chain.clearAllFilters ();
+          return td->http->raiseHTTPError (500);
+        }
 
+      sendNetString (&con, td->auxiliaryBuffer->getBuffer (), sizeEnvString);
+      if (td->request.contentLength.size ()
+          && !td->request.contentLength.compare ("0"))
+        sendPostData (&con);
 
-  chain.clearAllFilters ();
-  con.tempOut.close ();
+      sendResponse (&con, onlyHeader, &chain);
 
-  con.sock.close ();
-  return ret;
+      chain.clearAllFilters ();
+      con.tempOut.close ();
+      con.sock.close ();
+    }
+  catch (exception & e)
+    {
+      td->connection->host->warningsLogWrite (_E ("SCGI: internal error"), &e);
+      chain.clearAllFilters ();
+      return td->http->raiseHTTPError (500);
+    }
+
+  return HttpDataHandler::RET_OK;
 }
 
 
@@ -272,21 +264,19 @@ int Scgi::sendResponse (ScgiContext* ctx, int onlyHeader, 
FiltersChain* chain)
                                                 &td->response,
                                                 &(td->nBytesToRead));
 
-  if (HttpHeaders::sendHeader (td->response, *td->connection->socket,
-                               *td->auxiliaryBuffer, td))
-    return HttpDataHandler::RET_FAILURE;
+  HttpHeaders::sendHeader (td->response, *td->connection->socket,
+                           *td->auxiliaryBuffer, td);
 
   if (onlyHeader)
     return HttpDataHandler::RET_OK;
 
   if (read - headerSize)
-    if (appendDataToHTTPChannel (td, td->auxiliaryBuffer->getBuffer () + 
headerSize,
-                                 read - headerSize,
-                                 &(td->outputData),
-                                 chain,
-                                 td->appendOutputs,
-                                 useChunks))
-      return HttpDataHandler::RET_FAILURE;
+    appendDataToHTTPChannel (td, td->auxiliaryBuffer->getBuffer () + 
headerSize,
+                             read - headerSize,
+                             &(td->outputData),
+                             chain,
+                             td->appendOutputs,
+                             useChunks);
 
   sentData += read - headerSize;
 
@@ -301,22 +291,18 @@ int Scgi::sendResponse (ScgiContext* ctx, int onlyHeader, 
FiltersChain* chain)
           if (!nbr || (nbr == (u_long)-1))
             break;
 
-          if (appendDataToHTTPChannel (td, td->auxiliaryBuffer->getBuffer (),
-                                       nbr,
-                                       &(td->outputData),
-                                       chain,
-                                       td->appendOutputs,
-                                       useChunks))
-            return HttpDataHandler::RET_FAILURE;
+          appendDataToHTTPChannel (td, td->auxiliaryBuffer->getBuffer (),
+                                   nbr,
+                                   &(td->outputData),
+                                   chain,
+                                   td->appendOutputs,
+                                   useChunks);
 
           sentData += nbr;
         }
 
       if (!td->appendOutputs && useChunks)
-        {
-          if (chain->getStream ()->write ("0\r\n\r\n", 5, &nbw))
-            return HttpDataHandler::RET_FAILURE;
-        }
+        chain->getStream ()->write ("0\r\n\r\n", 5, &nbw);
     }
   /* For logging activity.  */
   td->sentData += sentData;
@@ -332,14 +318,9 @@ int Scgi::sendNetString (ScgiContext* ctx, const char* 
data, int len)
   char header[7];
   int headerLen = sprintf (header, "%i:", len);
 
-  if (ctx->sock.send (header, headerLen, 0) == -1)
-    return -1;
-
-  if (ctx->sock.send (data, len, 0) == -1)
-    return -1;
-
-  if (ctx->sock.send (",", 1, 0) == -1)
-    return -1;
+  ctx->sock.send (header, headerLen, 0);
+  ctx->sock.send (data, len, 0);
+  ctx->sock.send (",", 1, 0);
 
   return 0;
 }
@@ -352,15 +333,15 @@ int Scgi::sendPostData (ScgiContext* ctx)
   u_long nbr;
   do
     {
-      if (ctx->td->inputData.read (ctx->td->auxiliaryBuffer->getBuffer (),
-                                   ctx->td->auxiliaryBuffer->getRealLength (),
-                                   &nbr))
-        return -1;
+      ctx->td->inputData.read (ctx->td->auxiliaryBuffer->getBuffer (),
+                               ctx->td->auxiliaryBuffer->getRealLength (),
+                               &nbr);
 
-      if (nbr && (ctx->sock.send (ctx->td->auxiliaryBuffer->getBuffer (), nbr, 
0) == -1))
-        return -1;
+      if (nbr)
+        ctx->sock.send (ctx->td->auxiliaryBuffer->getBuffer (), nbr, 0);
     }
   while (nbr);
+
   return 0;
 }
 
@@ -425,8 +406,9 @@ int Scgi::buildScgiEnvironmentString (HttpThreadContext* 
td, char* src,
       if (max == 0)
         return -1;
 
-      if (! strcasecmp (varName, "CONTENT_LENGTH") || ! strcasecmp (varName, 
"SCGI") ||
-          !varNameLen || !varValueLen)
+      if (! strcasecmp (varName, "CONTENT_LENGTH")
+          || ! strcasecmp (varName, "SCGI")
+          || !varNameLen || !varValueLen)
         continue;
 
       for (i = 0; i < varNameLen; i++)
@@ -440,7 +422,7 @@ int Scgi::buildScgiEnvironmentString (HttpThreadContext* 
td, char* src,
       if (*(++sptr) == '\0')
         break;
     }
-  return static_cast<int>(ptr - dest);
+  return static_cast<int> (ptr - dest);
 }
 
 /*!



commit f9dc0edd06d506c90b00a4e99bd0a428012ca6d4
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 14:32:39 2010 +0200

    Fastcgi handles exceptions properly

diff --git a/myserver/src/http_handler/fastcgi/fastcgi.cpp 
b/myserver/src/http_handler/fastcgi/fastcgi.cpp
index 6a50412..9bfc7de 100644
--- a/myserver/src/http_handler/fastcgi/fastcgi.cpp
+++ b/myserver/src/http_handler/fastcgi/fastcgi.cpp
@@ -89,239 +89,229 @@ int FastCgi::send (HttpThreadContext* td, const char* 
scriptpath,
   if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
     return td->http->sendAuth ();
 
-  string tmp;
-  tmp.assign (cgipath);
-  FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
-  tmp.assign (scriptpath);
-  FilesUtility::splitPath (tmp, td->scriptDir, td->scriptFile);
-  chain.setStream (td->connection->socket);
-
-  if (td->mime
-      && Server::getInstance ()->getFiltersFactory ()->chain (&chain,
-                                                              
td->mime->filters,
-                                                              
td->connection->socket,
-                                                              &nbw,
-                                                              1))
+  try
     {
-      td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+      string tmp;
+      tmp.assign (cgipath);
+      FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
+      tmp.assign (scriptpath);
+      FilesUtility::splitPath (tmp, td->scriptDir, td->scriptFile);
+      chain.setStream (td->connection->socket);
+
+      if (td->mime)
+        Server::getInstance ()->getFiltersFactory ()->chain (&chain,
+                                                             td->mime->filters,
+                                                             
td->connection->socket,
+                                                             &nbw,
+                                                             1);
 
-  td->buffer->setLength (0);
-  td->auxiliaryBuffer->getAt (0) = '\0';
+      td->buffer->setLength (0);
+      td->auxiliaryBuffer->getAt (0) = '\0';
 
 
-  /*! Do not modify the text between " and ".  */
-  int i;
-  int subString = cgipath[0] == '"';
-  int len = strlen (cgipath);
-  string tmpCgiPath;
-  for (i = 1; i < len; i++)
-    {
-      if (!subString && cgipath[i]==' ')
-        break;
-      if (cgipath[i] == '"' && cgipath[i - 1] != '\\')
-        subString = !subString;
-    }
-  /*!
-    Save the cgi path and the possible arguments.
-    the (x < len) case is when additional arguments are specified.
-    If the cgipath is enclosed between " and " do not consider them
-    when splitting directory and file name.
-   */
-  if (len)
-    {
-      if (i < len)
+      /* Do not modify the text between " and ".  */
+      int i;
+      int subString = cgipath[0] == '"';
+      int len = strlen (cgipath);
+      string tmpCgiPath;
+      for (i = 1; i < len; i++)
         {
-          string tmpString (cgipath);
-          int begin = tmpString[0]=='"' ? 1: 0;
-          int end = tmpString[i] == '"' ? i - 1: i;
-          tmpCgiPath.assign (tmpString.substr (begin, end - begin));
-          moreArg.assign (tmpString.substr (i, len - 1));
+          if (!subString && cgipath[i]==' ')
+            break;
+          if (cgipath[i] == '"' && cgipath[i - 1] != '\\')
+            subString = !subString;
         }
-      else
+
+      /*
+        Save the cgi path and the possible arguments.
+        the (x < len) case is when additional arguments are specified.
+        If the cgipath is enclosed between " and " do not consider them
+        when splitting directory and file name.
+      */
+      if (len)
         {
-          int begin = (cgipath[0] == '"') ? 1 : 0;
-          int end   = (cgipath[len] == '"') ? len - 1 : len;
-          tmpCgiPath.assign (&cgipath[begin], end - begin);
-          moreArg.assign ("");
+          if (i < len)
+            {
+              string tmpString (cgipath);
+              int begin = tmpString[0]=='"' ? 1: 0;
+              int end = tmpString[i] == '"' ? i - 1: i;
+              tmpCgiPath.assign (tmpString.substr (begin, end - begin));
+              moreArg.assign (tmpString.substr (i, len - 1));
+            }
+          else
+            {
+              int begin = (cgipath[0] == '"') ? 1 : 0;
+              int end   = (cgipath[len] == '"') ? len - 1 : len;
+              tmpCgiPath.assign (&cgipath[begin], end - begin);
+              moreArg.assign ("");
+            }
+          FilesUtility::splitPath (tmpCgiPath, td->cgiRoot, td->cgiFile);
         }
-      FilesUtility::splitPath (tmpCgiPath, td->cgiRoot, td->cgiFile);
-    }
-  tmpCgiPath.assign (scriptpath);
-  FilesUtility::splitPath (tmpCgiPath, td->scriptDir, td->scriptFile);
-
+      tmpCgiPath.assign (scriptpath);
+      FilesUtility::splitPath (tmpCgiPath, td->scriptDir, td->scriptFile);
 
-  if (execute)
-    {
-      if (cgipath && strlen (cgipath))
+      if (execute)
         {
+          if (cgipath && strlen (cgipath))
+            {
 #ifdef WIN32
-          {
-            int x;
-            string cgipathString (cgipath);
-            int len = strlen (cgipath);
-            int subString = cgipath[0] == '"';
-
-            cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile << "\" "
-                    << moreArg << " \"" <<  td->filenamePath << "\"";
-          }
+              {
+                int x;
+                string cgipathString (cgipath);
+                int len = strlen (cgipath);
+                int subString = cgipath[0] == '"';
+
+                cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile << "\" "
+                        << moreArg << " \"" <<  td->filenamePath << "\"";
+              }
 #else
-          cmdLine << cgipath << " " << td->filenamePath;
+              cmdLine << cgipath << " " << td->filenamePath;
 #endif
-        }/*if (execute).  */
+            }/*if (execute).  */
+          else
+            cmdLine << scriptpath;
+        }
       else
-        cmdLine << scriptpath;
-    }
-  else
-    {
+        {
 #ifdef WIN32
-      cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile
-              << "\" " << moreArg;
+          cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile
+                  << "\" " << moreArg;
 #else
-      cmdLine << cgipath;
+          cmdLine << cgipath;
 #endif
-    }
-
-  td->inputData.close ();
-  if (td->inputData.openFile (td->inputDataPath, File::READ |
-                              File::FILE_OPEN_ALWAYS |
-                              File::NO_INHERIT))
-    {
-      td->buffer->setLength (0);
-      td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
-
-  server = connect (&con, cmdLine.str ().c_str ());
-
-  if (server == NULL)
-    {
-      td->buffer->setLength (0);
-      td->connection->host->warningsLogWrite (_("FastCGI: cannot connect to 
the %s process"),
-                                              cmdLine.str ().c_str ());
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+        }
 
-  id = td->id + 1;
+      td->inputData.close ();
+      td->inputData.openFile (td->inputDataPath, File::READ
+                              | File::FILE_OPEN_ALWAYS
+                              | File::NO_INHERIT);
 
-  if (fastCgiRequest (&con, id))
-    return td->http->raiseHTTPError (500);
+      server = connect (&con, cmdLine.str ().c_str ());
+      if (server == NULL)
+        {
+          td->buffer->setLength (0);
+          td->connection->host->warningsLogWrite
+              (_("FastCGI: cannot connect to the %s process"),
+               cmdLine.str ().c_str ());
+          chain.clearAllFilters ();
+          return td->http->raiseHTTPError (500);
+        }
 
-  /*! Now read the output. This flag is used by the external loop.  */
-  exit = 0;
+      id = td->id + 1;
+      if (fastCgiRequest (&con, id))
+        return td->http->raiseHTTPError (500);
 
-  /*! Return 1 if keep the connection. A nonzero value also mean no errors. */
-  ret = HttpDataHandler::RET_OK;
+      /* Now read the output. This flag is used by the external loop.  */
+      exit = 0;
 
-  initialTicks = getTicks ();
+      /* Return 1 if keep the connection. A nonzero value also mean no errors. 
 */
+      ret = HttpDataHandler::RET_OK;
 
-  td->buffer->setLength (0);
-  checkDataChunks (td, &con.keepalive, &con.useChunks);
+      initialTicks = getTicks ();
 
-  do
-    {
-      u_long dim;
-      u_long timeout = td->http->getTimeout ();
+      td->buffer->setLength (0);
+      checkDataChunks (td, &con.keepalive, &con.useChunks);
 
-      if (readHeader (&con, &header, initialTicks, timeout, id))
+      do
         {
-          exit = 1;
-          ret = td->http->raiseHTTPError (500);
-          break;
-        }
+          u_long dim;
+          u_long timeout = td->http->getTimeout ();
 
-      /*!
-       *contentLengthB1 is the high word of the content length value
-       *while contentLengthB0 is the low one.
-       *To retrieve the value of content length push left contentLengthB1
-       *of eight byte then do an or with contentLengthB0.
-       */
-      dim = (header.contentLengthB1 << 8) | header.contentLengthB0;
+          readHeader (&con, &header, initialTicks, timeout, id);
 
-      if (dim == 0)
-        {
-          exit = 1;
-          ret = HttpDataHandler::RET_FAILURE;
-        }
-      else
-        {
-          bool headerCompleted = false;
-          u_long timeout = td->http->getTimeout ();
+          /*
+           *contentLengthB1 is the high word of the content length value
+           *while contentLengthB0 is the low one.
+           *To retrieve the value of content length push left contentLengthB1
+           *of eight byte then do an or with contentLengthB0.
+           */
+          dim = (header.contentLengthB1 << 8) | header.contentLengthB0;
 
-          switch (header.type)
+          if (dim == 0)
             {
-            case FCGISTDERR:
-              con.sock.close ();
-              td->http->raiseHTTPError (501);
               exit = 1;
               ret = HttpDataHandler::RET_FAILURE;
-              break;
-            case FCGISTDOUT:
-              headerCompleted = false;
-              ret = sendData (&con, dim, static_cast<u_long>(timeout),
-                              &chain, &headerCompleted, onlyHeader);
+            }
+          else
+            {
+              bool headerCompleted = false;
+              u_long timeout = td->http->getTimeout ();
 
-              if (ret)
+              switch (header.type)
                 {
+                case FCGISTDERR:
+                  con.sock.close ();
+                  td->http->raiseHTTPError (501);
                   exit = 1;
-                  if (ret == 1)
-                    responseCompleted = true;
-                  else
-                    ret = HttpDataHandler::RET_FAILURE;
+                  ret = HttpDataHandler::RET_FAILURE;
+                  break;
+
+                case FCGISTDOUT:
+                  headerCompleted = false;
+                  ret = sendData (&con, dim, static_cast<u_long>(timeout),
+                                  &chain, &headerCompleted, onlyHeader);
+
+                  if (ret)
+                    {
+                      exit = 1;
+                      if (ret == 1)
+                        responseCompleted = true;
+                      else
+                        ret = HttpDataHandler::RET_FAILURE;
+
+                      break;
+                    }
+
+                  if (headerCompleted)
+                    {
+                      exit = 1;
+                      break;
+                    }
 
                   break;
-                }
 
-              if (headerCompleted)
-                {
+                case FCGIEND_REQUEST:
                   exit = 1;
                   break;
-                }
 
-              break;
-            case FCGIEND_REQUEST:
-              exit = 1;
-              break;
-            case FCGIGET_VALUES_RESULT:
-            case FCGIUNKNOWN_TYPE:
-            default:
-              break;
+                case FCGIGET_VALUES_RESULT:
+                case FCGIUNKNOWN_TYPE:
+                default:
+                  break;
+                }
             }
-        }
 
-      if (header.paddingLength)
-        {
-          u_long toPad = header.paddingLength;
-          u_long timeout = td->http->getTimeout ();
-          while (toPad)
+          if (header.paddingLength)
             {
-              if (td->buffer->getRealLength () < toPad)
-                toPad =  td->buffer->getRealLength ();
-
-              nbr = con.sock.recv (td->buffer->getBuffer (), toPad,
-                                   0, static_cast<u_long>(timeout));
-              if (nbr == (u_long)-1)
+              u_long toPad = header.paddingLength;
+              u_long timeout = td->http->getTimeout ();
+              while (toPad)
                 {
-                  exit = 1;
-                  ret = HttpDataHandler::RET_FAILURE;
-                  break;
+                  if (td->buffer->getRealLength () < toPad)
+                    toPad =  td->buffer->getRealLength ();
+
+                  nbr = con.sock.recv (td->buffer->getBuffer (), toPad,
+                                       0, static_cast<u_long> (timeout));
+                  toPad -= nbr;
                 }
-              toPad -= nbr;
             }
-        }
-    }while (!exit);
+        }while (!exit);
 
-  /* Send the last null chunk if needed.  */
-  if (!responseCompleted && con.useChunks &&
-      (td->response.getStatusType () == HttpResponseHeader::SUCCESSFUL))
-    chain.getStream ()->write ("0\r\n\r\n", 5, &nbw);
+      /* Send the last null chunk if needed.  */
+      if (!responseCompleted && con.useChunks &&
+          (td->response.getStatusType () == HttpResponseHeader::SUCCESSFUL))
+        chain.getStream ()->write ("0\r\n\r\n", 5, &nbw);
 
-  chain.clearAllFilters ();
-  con.sock.close ();
+      chain.clearAllFilters ();
+      con.sock.close ();
+    }
+  catch (exception & e)
+    {
+      td->connection->host->warningsLogWrite (_E ("FastCGI: internal error"),
+                                              &e);
+      chain.clearAllFilters ();
+      return td->http->raiseHTTPError (500);
+    }
 
   return ret;
 }
@@ -336,10 +326,8 @@ int FastCgi::sendFcgiBody (FcgiContext* con, char* buffer, 
int len, int type,
   FcgiHeader header;
   generateFcgiHeader ( header, type, id, len );
 
-  if (con->sock.send ((char*)&header, sizeof (header), 0) == -1)
-    return -1;
-  if (con->sock.send ((char*)buffer, len, 0) == -1)
-    return -1;
+  con->sock.send ((char*) &header, sizeof (header), 0);
+  con->sock.send ((char*) buffer, len, 0);
   return 0;
 }
 
@@ -416,7 +404,7 @@ int FastCgi::buildFASTCGIEnvironmentString 
(HttpThreadContext*, char* src,
     if (*(++sptr) == '\0')
       break;
   }
-  return static_cast<int>(ptr - dest);
+  return static_cast<int> (ptr - dest);
 }
 
 /*!
@@ -487,7 +475,6 @@ FastCgiServer* FastCgi::connect (FcgiContext* con, const 
char* path)
   if (server)
   {
     int ret = processServerManager->connect (&(con->sock), server);
-
     if (ret == -1)
       return 0;
   }
@@ -568,74 +555,33 @@ int FastCgi::fastCgiRequest (FcgiContext* con, int id)
   tBody.flags = 0;
   memset ( tBody.reserved, 0, sizeof ( tBody.reserved ) );
 
-  if (sendFcgiBody (con, (char*)&tBody, sizeof (tBody), FCGIBEGIN_REQUEST, id))
-  {
-    td->buffer->setLength (0);
-    td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-    return 1;
-  }
-
-  if (sendFcgiBody (con, td->auxiliaryBuffer->getBuffer (), sizeEnvString,
-                  FCGIPARAMS, id))
-  {
-    td->buffer->setLength (0);
-    td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-    return 1;
-  }
-
-  if (sendFcgiBody (con, 0, 0, FCGIPARAMS, id))
-  {
-    td->buffer->setLength (0);
-    td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-    return 1;
-  }
+  sendFcgiBody (con, (char*)&tBody, sizeof (tBody), FCGIBEGIN_REQUEST, id);
+  sendFcgiBody (con, td->auxiliaryBuffer->getBuffer (), sizeEnvString,
+                FCGIPARAMS, id);
+  sendFcgiBody (con, 0, 0, FCGIPARAMS, id);
 
   if (atoi (td->request.contentLength.c_str ()))
   {
     td->buffer->setLength (0);
+    td->inputData.seek (0);
 
-
-    if (td->inputData.seek (0))
-      {
-        td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-        return 1;
-      }
-
-    /*! Send the STDIN data.  */
+    /* Send the STDIN data.  */
     do
     {
-      if (td->inputData.read (td->buffer->getBuffer (),
-                                    maxStdinChunk, &nbr))
-      {
-        td->buffer->setLength (0);
-        td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-        return 1;
-      }
+      td->inputData.read (td->buffer->getBuffer (), maxStdinChunk, &nbr);
 
       if (!nbr)
         break;
 
       generateFcgiHeader (header, FCGISTDIN, id, nbr);
-      if (con->sock.send ((char*)&header, sizeof (header), 0) == -1)
-        return 1;
-
-      if (con->sock.send (td->buffer->getBuffer (), nbr, 0) == -1)
-        {
-          td->buffer->setLength (0);
-          td->connection->host->warningsLogWrite (_("FastCGI: internal 
error"));
-          return 1;
-        }
+      con->sock.send ((char*) &header, sizeof (header), 0);
+      con->sock.send (td->buffer->getBuffer (), nbr, 0);
     }
     while (nbr == maxStdinChunk);
   }
 
-  /*! Final stdin chunk.  */
-  if (sendFcgiBody (con, 0, 0, FCGISTDIN, id))
-    {
-      td->buffer->setLength (0);
-      td->connection->host->warningsLogWrite (_("FastCGI: internal error"));
-      return 1;
-    }
+  /* Final stdin chunk.  */
+  sendFcgiBody (con, 0, 0, FCGISTDIN, id);
 
   return 0;
 }
@@ -677,8 +623,6 @@ int FastCgi::sendData (FcgiContext* con, u_long dim, u_long 
timeout,
                                 std::min ((u_long) td->buffer->getRealLength 
(),
                                              dim - td->buffer->getLength ()),
                                    0, timeout);
-      if (nbr == (u_long)-1 || nbr == 0)
-        return -1;
 
       td->buffer->setLength (td->buffer->getLength () + nbr);
 
@@ -691,14 +635,13 @@ int FastCgi::sendData (FcgiContext* con, u_long dim, 
u_long timeout,
   if (onlyHeader || con->td->response.getStatusType () != 
HttpResponseHeader::SUCCESSFUL)
     return 1;
 
-  if (HttpDataHandler::appendDataToHTTPChannel (con->td,
-                                                con->td->buffer->getBuffer (),
-                                                con->td->buffer->getLength (),
-                                                &(con->td->outputData),
-                                                chain,
-                                                con->td->appendOutputs,
-                                                con->useChunks))
-    return -1;
+  HttpDataHandler::appendDataToHTTPChannel (con->td,
+                                            con->td->buffer->getBuffer (),
+                                            con->td->buffer->getLength (),
+                                            &(con->td->outputData),
+                                            chain,
+                                            con->td->appendOutputs,
+                                            con->useChunks);
 
   con->td->sentData += con->td->buffer->getLength ();
 
@@ -738,7 +681,7 @@ int FastCgi::handleHeader (FcgiContext* con, FiltersChain* 
chain, bool* response
     ! strcasecmp (con->td->securityToken.getData ("fastcgi.sendfile.allow",
                                               MYSERVER_VHOST_CONF
                                               | MYSERVER_SERVER_CONF, "NO"),
-              "YES");
+                  "YES");
   if (allowSendfile)
     {
       string *sendfile = con->td->response.getValue ("X-Sendfile", NULL);
@@ -785,15 +728,13 @@ int FastCgi::handleHeader (FcgiContext* con, 
FiltersChain* chain, bool* response
   if (con->td->response.getStatusType () == HttpResponseHeader::SUCCESSFUL &&
       size - headerSize)
     {
-      if (HttpDataHandler::appendDataToHTTPChannel (con->td,
-                                                    con->td->buffer->getBuffer 
() + headerSize,
-                                                    size - headerSize,
-                                                    &(con->td->outputData),
-                                                    chain,
-                                                    con->td->appendOutputs,
-                                                    con->useChunks))
-        return 1;
-
+      HttpDataHandler::appendDataToHTTPChannel (con->td,
+                                                con->td->buffer->getBuffer () 
+ headerSize,
+                                                size - headerSize,
+                                                &(con->td->outputData),
+                                                chain,
+                                                con->td->appendOutputs,
+                                                con->useChunks);
       con->td->sentData += size - headerSize;
     }
 



commit eaf34a00517172e15a224ed02fc390a1a9cdfe8f
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 14:13:43 2010 +0200

    Mscgi handles exceptions properly

diff --git a/myserver/src/http_handler/mscgi/mscgi.cpp 
b/myserver/src/http_handler/mscgi/mscgi.cpp
index cf3a245..2b349d4 100644
--- a/myserver/src/http_handler/mscgi/mscgi.cpp
+++ b/myserver/src/http_handler/mscgi/mscgi.cpp
@@ -81,72 +81,77 @@ int MsCgi::send (HttpThreadContext* td, const char* exec, 
const char* cmdLine,
   if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
     return td->http->sendAuth ();
 
-  td->scriptPath.assign (exec);
-
-  {
-    string tmp;
-    tmp.assign (exec);
-    FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
-    FilesUtility::splitPath (exec, td->scriptDir, td->scriptFile);
-  }
-
-  Env::buildEnvironmentString (td,data.envString);
-  chain.setStream (td->connection->socket);
-
-  if (td->mime && Server::getInstance ()->getFiltersFactory ()->chain (&chain,
-                                                                      
td->mime->filters,
-                                                                      
td->connection->socket,
-                                                                      &nbw,
-                                                                      1))
+  try
     {
-      td->connection->host->warningsLogWrite (_("MSCGI: internal error"));
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
-
-  checkDataChunks (td, &(data.keepAlive), &(data.useChunks));
-
-  ret = hinstLib.loadLibrary (exec, 0);
+      td->scriptPath.assign (exec);
+
+      {
+        string tmp;
+        tmp.assign (exec);
+        FilesUtility::splitPath (tmp, td->cgiRoot, td->cgiFile);
+        FilesUtility::splitPath (exec, td->scriptDir, td->scriptFile);
+      }
+
+      Env::buildEnvironmentString (td,data.envString);
+      chain.setStream (td->connection->socket);
+
+      if (td->mime)
+        Server::getInstance ()->getFiltersFactory ()->chain (&chain,
+                                                             td->mime->filters,
+                                                             
td->connection->socket,
+                                                             &nbw, 1);
+
+      checkDataChunks (td, &(data.keepAlive), &(data.useChunks));
+      try
+        {
+          hinstLib.loadLibrary (exec, 0);
+        }
+      catch (exception & e)
+        {
+          td->connection->host->warningsLogWrite (_E ("MSCGI: cannot load %s"),
+                                                  exec, &e);
+          chain.clearAllFilters ();
+          /* Internal server error.  */
+          return td->http->raiseHTTPError (500);
+        }
+
+      td->auxiliaryBuffer->getAt (0) = '\0';
+      ProcMain = (CGIMAIN) hinstLib.getProc ( "myserver_main");
+      if (ProcMain)
+        (ProcMain)(td->request.uriOpts.c_str (), &data);
+      else
+        {
+          td->connection->host->warningsLogWrite
+            (_("MSCGI: cannot find entry-point for %s"),exec);
+          return td->http->raiseHTTPError (500);
+        }
+      hinstLib.close ();
+
+      if (data.errorPage)
+        {
+          chain.clearAllFilters ();
+          return td->http->raiseHTTPError (data.errorPage);
+        }
+
+      if (!td->appendOutputs && data.useChunks && !data.error)
+        chain.getStream ()->write ("0\r\n\r\n", 5, &nbw);
+
+      if (!data.error)
+        return HttpDataHandler::RET_FAILURE;
+
+      ostringstream tmp;
+      tmp << td->sentData;
+      td->response.contentLength.assign (tmp.str ());
 
-  if (ret)
-    {
-      td->connection->host->warningsLogWrite (_("MSCGI: cannot load %s"), 
exec);
       chain.clearAllFilters ();
-      /* Internal server error.  */
-      return td->http->raiseHTTPError (500);
-    }
 
-  td->auxiliaryBuffer->getAt (0) = '\0';
-
-  ProcMain = (CGIMAIN) hinstLib.getProc ( "myserver_main");
-  if (ProcMain)
-    (ProcMain)(td->request.uriOpts.c_str (), &data);
-  else
-    {
-      td->connection->host->warningsLogWrite (_("MSCGI: cannot find 
entry-point for %s"), exec);
-      return td->http->raiseHTTPError (500);
     }
-  hinstLib.close ();
-
-
-  if (data.errorPage)
+  catch (exception & e)
     {
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (data.errorPage);
+      td->connection->host->warningsLogWrite (_E ("Cgi: internal error"), &e);
+      return td->http->raiseHTTPError (500);
     }
 
-  if (!td->appendOutputs && data.useChunks && !data.error
-      && chain.getStream ()->write ("0\r\n\r\n", 5, &nbw))
-    return HttpDataHandler::RET_FAILURE;
-
-  if (!data.error)
-    return HttpDataHandler::RET_FAILURE;
-
-  ostringstream tmp;
-  tmp << td->sentData;
-  td->response.contentLength.assign (tmp.str ());
-
-  chain.clearAllFilters ();
   return HttpDataHandler::RET_OK;
 }
 
@@ -164,14 +169,13 @@ int MsCgi::write (const char* data, u_long len, 
MsCgiData* mcd)
   if (mcd->onlyHeader)
     return 0;
 
-  if (HttpDataHandler::appendDataToHTTPChannel (mcd->td,
-                                                (char*) data,
-                                                len,
-                                                &(mcd->td->outputData),
-                                                mcd->filtersChain,
-                                                mcd->td->appendOutputs,
-                                                mcd->useChunks))
-    return 1;
+  HttpDataHandler::appendDataToHTTPChannel (mcd->td,
+                                            (char*) data,
+                                            len,
+                                            &(mcd->td->outputData),
+                                            mcd->filtersChain,
+                                            mcd->td->appendOutputs,
+                                            mcd->useChunks);
 
   mcd->td->sentData +=len;
   return 0;
@@ -190,9 +194,8 @@ int MsCgi::sendHeader (MsCgiData* mcd)
   if (mcd->headerSent)
     return 0;
 
-  if (HttpHeaders::sendHeader (td->response, *td->connection->socket,
-                               *td->auxiliaryBuffer, td))
-    return 1;
+  HttpHeaders::sendHeader (td->response, *td->connection->socket,
+                           *td->auxiliaryBuffer, td);
 
   mcd->headerSent = true;
   return 0;



commit 388a6be0ca412abafe0b929fdc9fa7624dd88905
Author: Giuseppe Scrivano <address@hidden>
Date:   Fri Apr 16 14:08:15 2010 +0200

    Cgi handles exceptions properly

diff --git a/myserver/src/http_handler/cgi/cgi.cpp 
b/myserver/src/http_handler/cgi/cgi.cpp
index 45bce5a..d01187e 100644
--- a/myserver/src/http_handler/cgi/cgi.cpp
+++ b/myserver/src/http_handler/cgi/cgi.cpp
@@ -80,235 +80,225 @@ int Cgi::send (HttpThreadContext* td, const char* 
scriptpath,
   int len = strlen (cgipath);
   int i;
 
-  if (!(td->permissions & MYSERVER_PERMISSION_EXECUTE))
-    return td->http->sendAuth ();
+  try
+    {
+      if (! (td->permissions & MYSERVER_PERMISSION_EXECUTE))
+        return td->http->sendAuth ();
 
-  td->scriptPath.assign (scriptpath);
+      td->scriptPath.assign (scriptpath);
 
-  if (!FilesUtility::nodeExists (scriptpath))
-    return td->http->raiseHTTPError (404);
+      if (!FilesUtility::nodeExists (scriptpath))
+        return td->http->raiseHTTPError (404);
 
-  int subString = cgipath[0] == '"';
-  /* Do not modify the text between " and ".  */
-  for (i = 1; i < len; i++)
-    {
-      if (!subString && cgipath[i] == ' ')
-        break;
-      if (cgipath[i] == '"' && cgipath[i - 1] != '\\')
-        subString = !subString;
-    }
+      int subString = cgipath[0] == '"';
+      /* Do not modify the text between " and ".  */
+      for (i = 1; i < len; i++)
+        {
+          if (!subString && cgipath[i] == ' ')
+            break;
+          if (cgipath[i] == '"' && cgipath[i - 1] != '\\')
+            subString = !subString;
+        }
 
-  /*
-   *Save the cgi path and the possible arguments.
-   *the (x < len) case is when additional arguments are specified.
-   *If the cgipath is enclosed between " and " do not consider them
-   *when splitting directory and file name.
-   */
-  if (i < len)
-    {
-      string tmpString (cgipath);
-      int begin = tmpString[0] == '"' ? 1 : 0;
-      int end   = tmpString[i] == '"' ? i : i - 1;
-      tmpCgiPath.assign (tmpString.substr (begin, end - 1));
-      moreArg.assign (tmpString.substr (i, len - 1));
-    }
-  else
-    {
-      int begin = (cgipath[0] == '"') ? 1 : 0;
-      int end   = (cgipath[len] == '"') ? len-1 : len;
-      tmpCgiPath.assign (&cgipath[begin], end-begin);
-      moreArg.assign ("");
-    }
-  FilesUtility::splitPath (tmpCgiPath, td->cgiRoot, td->cgiFile);
+      /*
+        Save the cgi path and the possible arguments.
+        the (x < len) case is when additional arguments are specified.
+        If the cgipath is enclosed between " and " do not consider them
+        when splitting directory and file name.
+      */
+      if (i < len)
+        {
+          string tmpString (cgipath);
+          int begin = tmpString[0] == '"' ? 1 : 0;
+          int end   = tmpString[i] == '"' ? i : i - 1;
+          tmpCgiPath.assign (tmpString.substr (begin, end - 1));
+          moreArg.assign (tmpString.substr (i, len - 1));
+        }
+      else
+        {
+          int begin = (cgipath[0] == '"') ? 1 : 0;
+          int end   = (cgipath[len] == '"') ? len-1 : len;
+          tmpCgiPath.assign (&cgipath[begin], end-begin);
+          moreArg.assign ("");
+        }
+      FilesUtility::splitPath (tmpCgiPath, td->cgiRoot, td->cgiFile);
 
-  tmpScriptPath.assign (scriptpath);
-  FilesUtility::splitPath (tmpScriptPath, td->scriptDir, td->scriptFile);
+      tmpScriptPath.assign (scriptpath);
+      FilesUtility::splitPath (tmpScriptPath, td->scriptDir, td->scriptFile);
 
-  chain.setStream (td->connection->socket);
+      chain.setStream (td->connection->socket);
 
-  if (execute)
-    {
-      const char *args = 0;
-      if (td->request.uriOpts.length ())
-        args = td->request.uriOpts.c_str ();
-      else if (td->pathInfo.length ())
-        args = &td->pathInfo[1];
-
-    if (cgipath && strlen (cgipath))
-      cmdLine << tmpCgiPath << " " << moreArg << " "
-              << td->scriptFile <<  (args ? args : "" ) ;
-    else
-      cmdLine << tmpScriptPath << moreArg << " " << (args ? args : "" );
-
-    nph = td->scriptFile.length () > 4 && td->scriptFile[0] == 'n'
-      && td->scriptFile[1] == 'p' && td->scriptFile[2] == 'h'
-      && td->scriptFile[3] == '-' ;
-
-    if (cgipath && strlen (cgipath))
-      {
-        spi.cmd.assign (tmpCgiPath);
-        spi.arg.append (" ");
-        spi.arg.assign (moreArg);
-        spi.arg.append (" ");
-        spi.arg.append (td->scriptFile);
+      if (execute)
+        {
+          const char *args = 0;
+          if (td->request.uriOpts.length ())
+            args = td->request.uriOpts.c_str ();
+          else if (td->pathInfo.length ())
+            args = &td->pathInfo[1];
+
+          if (cgipath && strlen (cgipath))
+            cmdLine << tmpCgiPath << " " << moreArg << " "
+                    << td->scriptFile <<  (args ? args : "" ) ;
+          else
+            cmdLine << tmpScriptPath << moreArg << " " << (args ? args : "" );
 
-        if (args)
-          {
-            spi.arg.append (" ");
-            spi.arg.append (args);
-          }
-      }
-    else
-      {
-      spi.cmd.assign (scriptpath);
-      spi.arg.assign (moreArg);
+          nph = td->scriptFile.length () > 4 && td->scriptFile[0] == 'n'
+            && td->scriptFile[1] == 'p' && td->scriptFile[2] == 'h'
+            && td->scriptFile[3] == '-' ;
 
-      if (args)
-        {
-          spi.arg.append (" ");
-          spi.arg.append (args);
+          if (cgipath && strlen (cgipath))
+            {
+              spi.cmd.assign (tmpCgiPath);
+              spi.arg.append (" ");
+              spi.arg.assign (moreArg);
+              spi.arg.append (" ");
+              spi.arg.append (td->scriptFile);
+              if (args)
+                {
+                  spi.arg.append (" ");
+                  spi.arg.append (args);
+                }
+            }
+          else
+            {
+              spi.cmd.assign (scriptpath);
+              spi.arg.assign (moreArg);
+              if (args)
+                {
+                  spi.arg.append (" ");
+                  spi.arg.append (args);
+                }
+            }
         }
-    }
-    }
-  else
-    {
-      if (!FilesUtility::nodeExists (tmpCgiPath.c_str ()))
+      else
         {
-          if (tmpCgiPath.length () > 0)
-            td->connection->host->warningsLogWrite (_("Cgi: cannot find the %s 
file")),
-              tmpCgiPath.c_str ();
-          else
-            td->connection->host->warningsLogWrite (_("Cgi: Executable file 
not specified"));
+          if (! FilesUtility::nodeExists (tmpCgiPath.c_str ()))
+            {
+              if (tmpCgiPath.length () > 0)
+                td->connection->host->warningsLogWrite
+                         (_("Cgi: cannot find the %s file")),
+                         tmpCgiPath.c_str ();
+              else
+                td->connection->host->warningsLogWrite
+                           (_("Cgi: Executable file not specified"));
+
+              td->scriptPath.assign ("");
+              td->scriptFile.assign ("");
+              td->scriptDir.assign ("");
+              chain.clearAllFilters ();
+              return td->http->raiseHTTPError (500);
+            }
 
-          td->scriptPath.assign ("");
-          td->scriptFile.assign ("");
-          td->scriptDir.assign ("");
-          chain.clearAllFilters ();
-          return td->http->raiseHTTPError (500);
+          spi.arg.assign (moreArg);
+          spi.arg.append (" ");
+          spi.arg.append (td->scriptFile);
+
+          cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile << "\" "
+                  << moreArg << " " << td->scriptFile;
+
+          spi.cmd.assign (td->cgiRoot);
+          spi.cmd.append ("/");
+          spi.cmd.append (td->cgiFile);
+
+          if (td->cgiFile.length () > 4 && td->cgiFile[0] == 'n'
+              && td->cgiFile[1] == 'p' && td->cgiFile[2] == 'h'
+              && td->cgiFile[3] == '-' )
+            nph = true;
+          else
+            nph = false;
         }
 
-      spi.arg.assign (moreArg);
-      spi.arg.append (" ");
-      spi.arg.append (td->scriptFile);
+      /*
+        Open the stdout file for the new CGI process.
+      */
+      stdOutFile.create ();
 
-    cmdLine << "\"" << td->cgiRoot << "/" << td->cgiFile << "\" "
-            << moreArg << " " << td->scriptFile;
+      /* Open the stdin file for the new CGI process.  */
+      stdInFile.openFile (td->inputDataPath,
+                          File::READ | File::FILE_OPEN_ALWAYS);
 
-    spi.cmd.assign (td->cgiRoot);
-    spi.cmd.append ("/");
-    spi.cmd.append (td->cgiFile);
+      /*
+        Build the environment string used by the CGI process.
+        Use the td->auxiliaryBuffer to build the environment string.
+      */
+      (td->auxiliaryBuffer->getBuffer ())[0] = '\0';
+      Env::buildEnvironmentString (td, td->auxiliaryBuffer->getBuffer ());
+
+      spi.cmdLine = cmdLine.str ();
+      spi.cwd.assign (td->scriptDir);
+
+      spi.gid = atoi (td->securityToken.getData ("cgi.gid", 
MYSERVER_VHOST_CONF |
+                                                 MYSERVER_MIME_CONF |
+                                                 MYSERVER_SECURITY_CONF |
+                                                 MYSERVER_SERVER_CONF, "0"));
+      spi.uid = atoi (td->securityToken.getData ("cgi.uid", 
MYSERVER_VHOST_CONF |
+                                                 MYSERVER_MIME_CONF |
+                                                 MYSERVER_SECURITY_CONF |
+                                                 MYSERVER_SERVER_CONF, "0"));
+      spi.chroot.assign (td->securityToken.getData ("cgi.chroot", 
MYSERVER_VHOST_CONF |
+                                                    MYSERVER_MIME_CONF |
+                                                    MYSERVER_SECURITY_CONF |
+                                                    MYSERVER_SERVER_CONF, ""));
+
+      spi.stdError = (FileHandle) stdOutFile.getWriteHandle ();
+      spi.stdIn = (FileHandle) stdInFile.getHandle ();
+      spi.stdOut = (FileHandle) stdOutFile.getWriteHandle ();
+      spi.envString = td->auxiliaryBuffer->getBuffer ();
+
+      if (spi.stdError == (FileHandle) -1 ||
+          spi.stdIn == (FileHandle) -1 ||
+          spi.stdOut == (FileHandle) -1)
+        {
+          td->connection->host->warningsLogWrite (_("Cgi: internal error"));
+          stdOutFile.close ();
+          chain.clearAllFilters ();
+          return td->http->raiseHTTPError (500);
+        }
 
-    if (td->cgiFile.length () > 4 && td->cgiFile[0] == 'n'
-        && td->cgiFile[1] == 'p' && td->cgiFile[2] == 'h'
-        && td->cgiFile[3] == '-' )
-      nph = true;
-    else
-      nph = false;
-    }
+      /* Execute the CGI process. */
+      {
+        int ret;
+        if (Process::getForkServer ()->isInitialized ())
+          {
+            int pid;
+            int port;
+
+            Process::getForkServer ()->executeProcess (&spi,
+                                                       ForkServer::FLAG_USE_IN
+                                                       | 
ForkServer::FLAG_USE_OUT
+                                                       | 
ForkServer::FLAG_USE_ERR,
+                                                       &pid, &port);
+            cgiProc.setPid (pid);
+          }
+        else
+          cgiProc.exec (&spi);
 
-  /*
-   *Open the stdout file for the new CGI process.
-   */
-  if (stdOutFile.create ())
-    {
-      td->connection->host->warningsLogWrite (_("Cgi: internal error"));
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+        /* Close the write stream of the pipe on the server.  */
+        stdOutFile.closeWrite ();
+      }
 
-  /* Open the stdin file for the new CGI process. */
-  if (stdInFile.openFile (td->inputDataPath,
-                         File::READ | File::FILE_OPEN_ALWAYS))
-    {
-      td->connection->host->warningsLogWrite (_("Cgi: internal error"));
-      stdOutFile.close ();
-      chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
+      sendData (td, stdOutFile, chain, cgiProc, onlyHeader, nph);
 
-  /*
-   *Build the environment string used by the CGI process.
-   *Use the td->auxiliaryBuffer to build the environment string.
-   */
-  (td->auxiliaryBuffer->getBuffer ())[0] = '\0';
-  Env::buildEnvironmentString (td, td->auxiliaryBuffer->getBuffer ());
-
-  spi.cmdLine = cmdLine.str ();
-  spi.cwd.assign (td->scriptDir);
-
-  spi.gid = atoi (td->securityToken.getData ("cgi.gid", MYSERVER_VHOST_CONF |
-                                             MYSERVER_MIME_CONF |
-                                             MYSERVER_SECURITY_CONF |
-                                             MYSERVER_SERVER_CONF, "0"));
-  spi.uid = atoi (td->securityToken.getData ("cgi.uid", MYSERVER_VHOST_CONF |
-                                             MYSERVER_MIME_CONF |
-                                             MYSERVER_SECURITY_CONF |
-                                             MYSERVER_SERVER_CONF, "0"));
-  spi.chroot.assign (td->securityToken.getData ("cgi.chroot", 
MYSERVER_VHOST_CONF |
-                                                MYSERVER_MIME_CONF |
-                                                MYSERVER_SECURITY_CONF |
-                                                MYSERVER_SERVER_CONF, ""));
-
-  spi.stdError = (FileHandle) stdOutFile.getWriteHandle ();
-  spi.stdIn = (FileHandle) stdInFile.getHandle ();
-  spi.stdOut = (FileHandle) stdOutFile.getWriteHandle ();
-  spi.envString = td->auxiliaryBuffer->getBuffer ();
-
-  if (spi.stdError == (FileHandle) -1 ||
-      spi.stdIn == (FileHandle) -1 ||
-      spi.stdOut == (FileHandle) -1)
-    {
-      td->connection->host->warningsLogWrite (_("Cgi: internal error"));
       stdOutFile.close ();
+      stdInFile.close ();
+      cgiProc.terminateProcess ();
       chain.clearAllFilters ();
-      return td->http->raiseHTTPError (500);
-    }
 
-  /* Execute the CGI process. */
-  {
-    int ret;
-    if (Process::getForkServer ()->isInitialized ())
-      {
-        int pid;
-        int port;
-
-        ret = Process::getForkServer ()->executeProcess (&spi,
-                                                         
ForkServer::FLAG_USE_IN |
-                                                         
ForkServer::FLAG_USE_OUT |
-                                                         
ForkServer::FLAG_USE_ERR,
-                                                         &pid,
-                                                         &port);
-        cgiProc.setPid (pid);
-      }
-    else
-      ret = cgiProc.exec (&spi);
+      cgiProc.terminateProcess ();
 
-    if ( ret == -1)
+      /* Delete the file only if it was created by the CGI module.  */
+      if (!td->inputData.getHandle ())
+        FilesUtility::deleteFile (td->inputDataPath.c_str ());
+    }
+  catch (exception & e)
     {
-      stdInFile.close ();
+      td->connection->host->warningsLogWrite (_E ("Cgi: internal error"), &e);
       stdOutFile.close ();
-      td->connection->host->warningsLogWrite (_("Cgi: internal error"));
       chain.clearAllFilters ();
       return td->http->raiseHTTPError (500);
-      }
-    /* Close the write stream of the pipe on the server.  */
-    stdOutFile.closeWrite ();
-  }
-
-  int ret = sendData (td, stdOutFile, chain, cgiProc, onlyHeader, nph);
-
-  stdOutFile.close ();
-  stdInFile.close ();
-  cgiProc.terminateProcess ();
-  chain.clearAllFilters ();
-
-  cgiProc.terminateProcess ();
-
-  /* Delete the file only if it was created by the CGI module.  */
-  if (!td->inputData.getHandle ())
-    FilesUtility::deleteFile (td->inputDataPath.c_str ());
+    }
 
-  return ret;
+  return HttpDataHandler::RET_OK;
 }
 
 /*

-----------------------------------------------------------------------

Summary of changes:
 myserver/src/base/socket/socket.cpp                |   20 +-
 myserver/src/http_handler/cgi/cgi.cpp              |  392 +++++++-------
 myserver/src/http_handler/fastcgi/fastcgi.cpp      |  465 +++++++---------
 myserver/src/http_handler/isapi/isapi.cpp          |  569 ++++++++++----------
 myserver/src/http_handler/mscgi/mscgi.cpp          |  141 +++---
 myserver/src/http_handler/proxy/proxy.cpp          |  223 ++++-----
 myserver/src/http_handler/scgi/scgi.cpp            |  338 ++++++------
 myserver/src/http_handler/wincgi/wincgi.cpp        |  511 ++++++++----------
 myserver/src/protocol/control/control_protocol.cpp |  502 +++++++-----------
 myserver/src/protocol/ftp/ftp.cpp                  |   21 +-
 10 files changed, 1443 insertions(+), 1739 deletions(-)


hooks/post-receive
-- 
GNU MyServer




reply via email to

[Prev in Thread] Current Thread [Next in Thread]