gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r5038 - in libmicrohttpd: . src/daemon


From: gnunet
Subject: [GNUnet-SVN] r5038 - in libmicrohttpd: . src/daemon
Date: Wed, 13 Jun 2007 15:57:37 -0600 (MDT)

Author: grothoff
Date: 2007-06-13 15:57:36 -0600 (Wed, 13 Jun 2007)
New Revision: 5038

Modified:
   libmicrohttpd/README
   libmicrohttpd/src/daemon/daemon.c
   libmicrohttpd/src/daemon/session.c
   libmicrohttpd/src/daemon/session.h
Log:
essentials implemented

Modified: libmicrohttpd/README
===================================================================
--- libmicrohttpd/README        2007-06-13 17:57:08 UTC (rev 5037)
+++ libmicrohttpd/README        2007-06-13 21:57:36 UTC (rev 5038)
@@ -5,11 +5,6 @@
 before certain features can be used at all:
 
 
-For ANYTHING:
-=============
-session.c:
-- MHD_session_get_fdset (essentially not implemented)
-
 For GET args:
 =============
 session.c:
@@ -26,6 +21,13 @@
 session.c:
 - MHD_parse_session_headers: take cookie header apart
 
+For http-compliance:
+====================
+session.c:
+- send proper error code back if headers are too long
+  (investigate what we should do with those headers,
+   read?  give user control?)
+
 For IPv6:
 =========
 daemon.c:

Modified: libmicrohttpd/src/daemon/daemon.c
===================================================================
--- libmicrohttpd/src/daemon/daemon.c   2007-06-13 17:57:08 UTC (rev 5037)
+++ libmicrohttpd/src/daemon/daemon.c   2007-06-13 21:57:36 UTC (rev 5038)
@@ -163,7 +163,8 @@
   
   if (con == NULL)
     abort();
-  while (! con->daemon->shutdown) {    
+  while ( (! con->daemon->shutdown) &&
+         (con->socket_fd != -1) ) {    
     FD_ZERO(&rs);
     FD_ZERO(&ws);    
     FD_ZERO(&es);    
@@ -189,8 +190,10 @@
           (MHD_YES != MHD_session_handle_write(con)) ) )
       break;
   } 
-  close(con->socket_fd);
-  con->socket_fd = -1;
+  if (con->socket_fd != -1) {
+    close(con->socket_fd);
+    con->socket_fd = -1;
+  }
   return NULL;
 }
 
@@ -260,6 +263,11 @@
  * Free resources associated with all closed sessions.
  * (destroy responses, free buffers, etc.).  A session
  * is known to be closed if the socket_fd is -1.
+ *
+ * Also performs session actions that need to be run
+ * even if the session is not selectable (such as
+ * calling the application again with upload data when
+ * the upload data buffer is full).
  */
 static void 
 MHD_cleanup_sessions(struct MHD_Daemon * daemon) {
@@ -295,6 +303,13 @@
        MHD_destroy_response(pos->response);
       free(pos);
     }
+    
+    if ( (pos->headersReceived == 1) &&
+        (pos->read_buffer_size == pos->readLoc) &&
+        (pos->readLoc > 0) )
+      MHD_call_session_handler(pos);
+
+
     prev = pos;
     pos = pos->next;
   }

Modified: libmicrohttpd/src/daemon/session.c
===================================================================
--- libmicrohttpd/src/daemon/session.c  2007-06-13 17:57:08 UTC (rev 5037)
+++ libmicrohttpd/src/daemon/session.c  2007-06-13 21:57:36 UTC (rev 5038)
@@ -109,7 +109,9 @@
                   struct MHD_Response * response) {
   if ( (session == NULL) || 
        (response == NULL) ||
-       (session->response != NULL) )
+       (session->response != NULL) ||
+       (session->bodyReceived == 0) ||
+       (session->headers_received == 0) )
     return MHD_NO;     
   MHD_increment_response_rc(response);
   session->response = response;
@@ -129,13 +131,15 @@
                      fd_set * write_fd_set,
                      fd_set * except_fd_set,
                      int * max_fd) {
-  /* FIXME: need to be VERY careful here
-     determining when the socket is ready for
-     reading/writing; plenty of cases to handle!
-     (the current code is one big bug) */
-  FD_SET(session->socket_fd, read_fd_set);
-  FD_SET(session->socket_fd, write_fd_set);
-  if (session->socket_fd > *max_fd)
+  if ( (session->headers_received == 0) ||
+       (session->readLoc < session->read_buffer_size) )
+    FD_SET(session->socket_fd, read_fd_set);
+  if (session->response != NULL) 
+    FD_SET(session->socket_fd, write_fd_set);
+  if ( (session->socket_fd > *max_fd) &&
+       ( (session->headers_received == 0) ||
+        (session->readLoc < session->read_buffer_size) ||
+        (session->response != NULL) ) )
     *max_fd = session->socket_fd;
   return MHD_YES;
 }
@@ -233,6 +237,7 @@
       httpType = strstr(uri, " ");
       if (httpType != NULL)
        httpType[0] = '\0';
+      /* FIXME: parse URI some more here */
       session->url = strdup(uri);
       /* do we want to do anything with httpType? */
       free(line);
@@ -267,9 +272,9 @@
     hdr->kind = MHD_HEADER_KIND;
     session->headers_received = hdr;
   }
+  /* FIXME: here: find cookie header and parse that! */
   if (session->bodyReceived == 0)
     return;
-  /* FIXME: here: find cookie header and parse that! */
   return;
  DIE:
   close(session->socket_fd);
@@ -295,6 +300,48 @@
 }
 
 /**
+ * Call the handler of the application for this
+ * session. 
+ */
+void
+MHD_call_session_handler(struct MHD_Session * session) {
+  struct MHD_Access_Handler * ah;
+  unsigned int processed;
+
+  if (session->headers_received == 0)
+    abort(); /* bad timing... */
+  ah = MHD_find_access_handler(session);
+  processed = session->readLoc;
+  if (MHD_NO == ah->dh(ah->dh_cls,
+                      session,
+                      session->url,
+                      session->method,
+                      session->read_buffer,
+                      &processed)) {
+    /* serios internal error, close connection */
+    MHD_DLOG(session->daemon,
+            "Internal application error, closing connection.");
+    close(session->socket_fd);
+    session->socket_fd = -1;
+    return;
+  }
+  /* dh left "processed" bytes in buffer for next time... */
+  memmove(session->read_buffer,
+         &session->read_buffer[session->readLoc - processed],
+         processed);
+  session->readLoc = processed;
+  session->uploadSize -= processed;
+  if (session->uploadSize == 0) {
+    session->bodyReceived = 1;
+    session->readLoc = 0;
+    session->read_buffer_size = 0;
+    free(session->read_buffer);
+    session->read_buffer = NULL;
+  }
+}
+
+
+/**
  * This function handles a particular connection when it has been
  * determined that there is data to be read off a socket. All implementations
  * (multithreaded, external select, internal select) call this function
@@ -304,16 +351,10 @@
 MHD_session_handle_read(struct MHD_Session * session) {
   int bytes_read;
   void * tmp;
-  struct MHD_Access_Handler * ah;
-  unsigned int processed;
+ 
 
-  if (session->bodyReceived) {
-    MHD_DLOG(session->daemon,
-            "Unexpected call to %s.\n",
-            __FUNCTION__);
-    return MHD_NO; 
-  }
-  if (session->readLoc >= session->read_buffer_size) {
+  if ( (session->readLoc >= session->read_buffer_size) &&
+       (session->headers_received == 0) ) {
     /* need to grow read buffer */
     tmp = malloc(session->read_buffer_size * 2 + MHD_MAX_BUF_SIZE);
     memcpy(tmp,
@@ -321,6 +362,12 @@
           session->read_buffer_size);
     session->read_buffer_size = session->read_buffer_size * 2 + 
MHD_MAX_BUF_SIZE;
   }
+  if (session->readLoc >= session->read_buffer_size) {
+    MHD_DLOG(session->daemon,
+            "Unexpected call to %s.\n",
+            __FUNCTION__);
+    return MHD_NO; 
+  }
   bytes_read = recv(session->socket_fd,
                    &session->read_buffer[session->readLoc],
                    session->read_buffer_size - session->readLoc,
@@ -331,39 +378,24 @@
     MHD_DLOG(session->daemon,
             "Failed to receive data: %s\n",
             strerror(errno));
-    return MHD_NO;
+    close(session->socket_fd);
+    session->socket_fd = -1;
+    return MHD_YES;
   }
   if (bytes_read == 0) {
     /* other side closed connection */
+    /* FIXME: proper handling of end of upload!
+       If we were receiving an unbounded upload,
+       we should finish up nicely now! */
     close(session->socket_fd);
     session->socket_fd = -1;
-    return MHD_NO;
+    return MHD_YES;
   }
   session->readLoc += bytes_read;
   if (session->headersReceived == 0) 
     MHD_parse_session_headers(session);
-  if (session->headersReceived == 1) {
-    ah = MHD_find_access_handler(session);
-    processed = session->readLoc;
-    if (MHD_NO == ah->dh(ah->dh_cls,
-                        session,
-                        session->url,
-                        session->method,
-                        session->read_buffer,
-                        &processed)) {
-      /* serios error, close connection */
-      close(session->socket_fd);
-      session->socket_fd = -1;
-      return MHD_NO;
-    }
-    /* dh left "processed" bytes in buffer for next time... */
-    memmove(session->read_buffer,
-           &session->read_buffer[session->readLoc - processed],
-           processed);
-    session->readLoc = processed;
-    session->uploadSize -= processed;
-    /* FIXME: proper handling of end of upload! */
-  }
+  if (session->headersReceived == 1) 
+    MHD_call_session_handler(session);
   return MHD_YES;
 }
 
@@ -447,7 +479,7 @@
               strerror(errno));
       close(session->socket_fd);
       session->socket_fd = -1;
-      return MHD_NO;
+      return MHD_YES;
     }
     session->writeLoc += ret;
     if (session->writeLoc == session->write_buffer_size) {
@@ -489,7 +521,7 @@
     response->data_start = session->messagePos;
     response->data_size = ret;
     if (ret == 0)
-      return MHD_YES; /* or NO? */
+      return MHD_YES; 
   }
   
   /* transmit */
@@ -499,17 +531,23 @@
             0);
   if (response->crc != NULL)
     pthread_mutex_unlock(&response->mutex);    
-  if (ret == -1) {
+  if (ret < 0) {
     if (errno == EINTR)
       return MHD_YES;
     MHD_DLOG(session->daemon,
             "Failed to send data: %s\n",
             strerror(errno));
-    return MHD_NO;
+    close(session->socket_fd);
+    session->socket_fd = -1;
+    return MHD_YES;
   }
   session->messagePos += ret;
+  if (session->messagePos > response->data_size) 
+    abort(); /* internal error */
   if (session->messagePos == response->data_size) {
-    /* reset session, wait for next request! */
+    if ( (session->bodyReceived == 0) ||
+        (session->headers_received == 0) )
+      abort(); /* internal error */
     MHD_destroy_response(response);
     session->responseCode = 0;
     session->response = NULL;

Modified: libmicrohttpd/src/daemon/session.h
===================================================================
--- libmicrohttpd/src/daemon/session.h  2007-06-13 17:57:08 UTC (rev 5037)
+++ libmicrohttpd/src/daemon/session.h  2007-06-13 21:57:36 UTC (rev 5038)
@@ -44,6 +44,13 @@
 
 
 /**
+ * Call the handler of the application for this
+ * session. 
+ */
+void
+MHD_call_session_handler(struct MHD_Session * session);
+
+/**
  * This function handles a particular connection when it has been
  * determined that there is data to be read off a socket. All implementations
  * (multithreaded, external select, internal select) call this function





reply via email to

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