myserver-commit
[Top][All Lists]
Advanced

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

[myserver-commit] [3097] The HTTP Proxy is now HTTP/1.1 compliant.


From: Giuseppe Scrivano
Subject: [myserver-commit] [3097] The HTTP Proxy is now HTTP/1.1 compliant.
Date: Sun, 24 May 2009 11:22:45 +0000

Revision: 3097
          http://svn.sv.gnu.org/viewvc/?view=rev&root=myserver&revision=3097
Author:   gscrivano
Date:     2009-05-24 11:22:44 +0000 (Sun, 24 May 2009)
Log Message:
-----------
The HTTP Proxy is now HTTP/1.1 compliant.

Modified Paths:
--------------
    trunk/myserver/AUTHORS
    trunk/myserver/include/http_handler/proxy/proxy.h
    trunk/myserver/include/protocol/http/http_data_read.h
    trunk/myserver/src/http_handler/proxy/proxy.cpp
    trunk/myserver/src/protocol/http/http_data_read.cpp

Modified: trunk/myserver/AUTHORS
===================================================================
--- trunk/myserver/AUTHORS      2009-05-24 08:18:18 UTC (rev 3096)
+++ trunk/myserver/AUTHORS      2009-05-24 11:22:44 UTC (rev 3097)
@@ -1,7 +1,8 @@
 People who contributed significantly to GNU MyServer:
 ==================================================
+
 Georgy Berdyshev <address@hidden>
-Hacked everywhere in the code.
+Long term contributor.
 
 Russ Bohnhoff <address@hidden>
 Original port to POSIX.
@@ -10,6 +11,7 @@
 Alexandru Iancu <address@hidden>
 Implemented the IPv6 protocol.
 Implemented the FTP protocol.
+Many improvements all around.
 
 Daniele Perrone <address@hidden>
 Redesign of the plugins management system.

Modified: trunk/myserver/include/http_handler/proxy/proxy.h
===================================================================
--- trunk/myserver/include/http_handler/proxy/proxy.h   2009-05-24 08:18:18 UTC 
(rev 3096)
+++ trunk/myserver/include/http_handler/proxy/proxy.h   2009-05-24 11:22:44 UTC 
(rev 3097)
@@ -25,6 +25,7 @@
 #include <include/protocol/http/http_data_handler.h>
 
 class FiltersChain;
+class Socket;
 
 class Proxy : public HttpDataHandler
 {
@@ -38,6 +39,16 @@
 protected:
   int flushToClient (HttpThreadContext* td, Socket& client,
                      FiltersChain &out, int onlyHeader);
+  int readPayLoad (HttpThreadContext* td,
+                   HttpResponseHeader* res,
+                   FiltersChain *out,
+                   Socket *client,
+                   const char *initBuffer,
+                   u_long initBufferSize,
+                   int timeout,
+                   bool useChunks = false,
+                   bool keepalive = false);
+
   static int timeout;
 };
 #endif

Modified: trunk/myserver/include/protocol/http/http_data_read.h
===================================================================
--- trunk/myserver/include/protocol/http/http_data_read.h       2009-05-24 
08:18:18 UTC (rev 3096)
+++ trunk/myserver/include/protocol/http/http_data_read.h       2009-05-24 
11:22:44 UTC (rev 3097)
@@ -1,7 +1,7 @@
 /* -*- mode: c++ -*- */
 /*
 MyServer
-Copyright (C) 2002-2008 Free Software Foundation, Inc.
+Copyright (C) 2002-2009 Free Software Foundation, Inc.
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
@@ -43,7 +43,7 @@
 public:
   static int readPostData(HttpThreadContext* td, int* ret);
 
-  static int readContiguousPrimitivePostData(char* inBuffer,
+  static int readContiguousPrimitivePostData(const char* inBuffer,
                                              u_long *inBufferPos,
                                              u_long inBufferSize,
                                              Socket *inSocket,
@@ -51,7 +51,7 @@
                                              u_long outBufferSize,
                                              u_long* nbr,
                                              u_long timeout);
-  static int readChunkedPostData(char* inBuffer,
+  static int readChunkedPostData(const char* inBuffer,
                                  u_long *inBufferPos,
                                  u_long inBufferSize,
                                  Socket *inSocket,
@@ -59,7 +59,8 @@
                                  u_long outBufferSize,
                                  u_long* nbr,
                                  u_long timeout,
-                                 File* out);
+                                 Stream* out,
+                                 long maxChunks);
   
 };
 

Modified: trunk/myserver/src/http_handler/proxy/proxy.cpp
===================================================================
--- trunk/myserver/src/http_handler/proxy/proxy.cpp     2009-05-24 08:18:18 UTC 
(rev 3096)
+++ trunk/myserver/src/http_handler/proxy/proxy.cpp     2009-05-24 11:22:44 UTC 
(rev 3097)
@@ -23,6 +23,8 @@
 #include <include/protocol/url.h>
 #include <include/base/socket/socket.h>
 #include <include/protocol/http/http_request.h>
+#include <include/protocol/http/http_response.h>
+#include <include/protocol/http/http_data_read.h>
 #include <include/protocol/http/http_data_handler.h>
 #include <include/protocol/http/http_headers.h>
 #include <include/filter/filters_chain.h>
@@ -61,17 +63,16 @@
       req.setValue (e->name->c_str (), e->value->c_str ());
     }
 
-  if (destUrl.getProtocol ().compare ("HTTP"))
+  if (destUrl.getProtocol ().compare ("http") && destUrl.getProtocol 
().compare ("HTTP"))
     {
       ostringstream msg;
-      msg << "Proxy: " << destUrl.getProtocol () << " is not known.";
+      msg << "Proxy: " << destUrl.getProtocol () << " is not a known 
protocol.";
       td->connection->host->warningsLogWrite (msg.str ().c_str ());
       return 0;
     }
 
-  /*Use HTTP/1.0 until we accept chunks from clients.  */
-  req.ver.assign ("HTTP/1.0");
-  req.cmd.assign ("GET");
+  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);
@@ -120,9 +121,9 @@
 
   int ret = flushToClient (td, sock, chain, onlyHeader);
 
-
   chain.clearAllFilters();
   sock.close ();
+  req.free ();
 
   return ret;
 }
@@ -160,7 +161,12 @@
 
   checkDataChunks (td, &keepalive, &useChunks);
 
+  td->response.setValue ("Via", Server::getInstance()->getServerName());
 
+  if (useChunks)
+    td->response.setValue ("Transfer-Encoding", "chunked");
+
+
   HttpHeaders::buildHTTPResponseHeader (td->buffer->getBuffer (),
                                         &td->response);
 
@@ -172,49 +178,21 @@
   if (onlyHeader)
     return keepalive;
 
-  if (read - headerLength)
-    {
-      if (HttpDataHandler::appendDataToHTTPChannel(td,
-                                                   
td->secondaryBuffer->getBuffer() +
-                                                     headerLength,
-                                                   read - headerLength,
-                                                   &(td->outputData),
-                                                   &out,
-                                                   td->appendOutputs,
-                                                   useChunks))
-        return 0;
 
-      td->sentData += read - headerLength;
-    }
+  ret = readPayLoad (td,
+                     &td->response,
+                     &out,
+                     &client,
+                     td->secondaryBuffer->getBuffer() + headerLength,
+                     read - headerLength,
+                     timeout,
+                     useChunks,
+                     keepalive);
 
-  while (ret = client.recv (td->secondaryBuffer->getBuffer (),
-                            td->secondaryBuffer->getRealLength (),
-                            0,
-                            timeout))
-    {
+  if (ret != -1)
+    td->sentData += ret;
 
-      if (ret == -1)
-        break;
-
-      if (HttpDataHandler::appendDataToHTTPChannel(td,
-                                                   
td->secondaryBuffer->getBuffer(),
-                                                   ret,
-                                                   &(td->outputData),
-                                                   &out,
-                                                   td->appendOutputs,
-                                                   useChunks))
-        return 0;
-
-      td->sentData += ret;
-    }
-
-
-  if(useChunks && out.write ("0\r\n\r\n", 5, &nbw))
-    {
-      return 0;
-    }
-
-  return keepalive;
+  return ret == -1 ? 0 : keepalive;
 }
 
 /*!
@@ -233,3 +211,134 @@
 {
   return timeout;
 }
+
+
+/*!
+ *Forward the message payload to the client.
+ *
+ *\param td The current HTTP thread context.
+ *\param res Response obtained by the server.
+ *\param out The client chain.
+ *\param initBuffer Initial read data.
+ *\param initBufferSize Size of initial data.
+ *\param timeout Connection timeout.
+ *\param useChunks Use chunked transfer encoding
+ *with the client.
+ *\param keepalive The connection is keep-alive.
+ *
+ *\return -1 on error.
+ *\return Otherwise the number of bytes transmitted.
+ */
+int Proxy::readPayLoad (HttpThreadContext* td,
+                        HttpResponseHeader* res,
+                        FiltersChain *out,
+                        Socket *client,
+                        const char *initBuffer,
+                        u_long initBufferSize,
+                        int timeout,
+                        bool useChunks,
+                        bool keepalive)
+{
+  u_long contentLength = -1;
+
+  u_long nbr = 0, nbw = 0, length = 0, inPos = 0;
+  u_long bufferDataSize = 0;
+  u_long written = 0;
+
+  HttpResponseHeader::Entry *encoding = res->other.get ("Transfer-Encoding");
+
+  /* Only the chunked transfer encoding is supported.  */
+  if(encoding && !encoding->value->compare("chunked"))
+    return -1;
+
+  if (res->contentLength.length ())
+    {
+      contentLength = atol (res->contentLength.c_str ());
+      if (contentLength < 0)
+        return -1;
+    }
+
+  length = contentLength;
+
+  bufferDataSize = (td->nBytesToRead < td->buffer->getRealLength() - 1
+                    ? td->nBytesToRead
+                    : td->buffer->getRealLength() - 1 ) - td->nHeaderChars;
+
+  /* If it is specified a transfer encoding read data using it.  */
+  if(encoding)
+  {
+    if(!encoding->value->compare("chunked"))
+    {
+      for (;;)
+        {
+          if (HttpDataRead::readChunkedPostData (initBuffer,
+                                                 &inPos,
+                                                 initBufferSize,
+                                                 client,
+                                                 td->buffer->getBuffer(),
+                                                 td->buffer->getRealLength() - 
1,
+                                                 &nbr,
+                                                 timeout,
+                                                 NULL,
+                                                 1))
+            return -1;
+
+          if (nbr == 0)
+            break;
+
+          if (HttpDataHandler::appendDataToHTTPChannel (td,
+                                                        
td->buffer->getBuffer(),
+                                                        nbr,
+                                                        &(td->outputData),
+                                                        out,
+                                                        td->appendOutputs,
+                                                        useChunks))
+            return -1;
+
+          written += nbr;
+        }
+    }
+  }
+  /* If it is not specified an encoding, read the data as it is.  */
+  else for(;;)
+  {
+
+    if(HttpDataRead::readContiguousPrimitivePostData (initBuffer,
+                                                      &inPos,
+                                                      initBufferSize,
+                                                      client,
+                                                      td->buffer->getBuffer(),
+                                                      
td->buffer->getRealLength() - 1,
+                                                      &nbr,
+                                                      timeout))
+    {
+      return -1;
+    }
+
+    if(nbr <= length)
+      length -= nbr;
+    else
+    {
+      return -1;
+    }
+
+    if (nbr && HttpDataHandler::appendDataToHTTPChannel (td,
+                                                         td->buffer->getBuffer 
(),
+                                                         nbr,
+                                                         &(td->outputData),
+                                                         out,
+                                                         td->appendOutputs,
+                                                         useChunks))
+      return -1;
+
+    written += nbr;
+
+    if(!length)
+      break;
+  }
+
+  if(useChunks && out->getStream ()->write ("0\r\n\r\n", 5, &nbw))
+    return -1;
+
+  return written;
+}

Modified: trunk/myserver/src/protocol/http/http_data_read.cpp
===================================================================
--- trunk/myserver/src/protocol/http/http_data_read.cpp 2009-05-24 08:18:18 UTC 
(rev 3096)
+++ trunk/myserver/src/protocol/http/http_data_read.cpp 2009-05-24 11:22:44 UTC 
(rev 3097)
@@ -58,7 +58,7 @@
  *\param timeout Timeout value to use on the socket.
  *\return Return 0 on success.
  */
-int HttpDataRead::readContiguousPrimitivePostData(char* inBuffer,
+int HttpDataRead::readContiguousPrimitivePostData(const char* inBuffer,
                                                   u_long *inBufferPos,
                                                   u_long inBufferSize,
                                                   Socket *inSocket,
@@ -111,12 +111,13 @@
  *\param outBufferSize outBuffer size.
  *\param outNbr Number of bytes read.
  *\param timeout Timeout value to use on the socket.
- *\param out Output file.
+ *\param out Output file, may be  a NULL pointer.
+ *\param maxChunks The maximum number of chunks to read.
  *\return Return 0 on success.
  *\return -1 on internal error.
  *\return Any other value is the HTTP error code.
  */
-int HttpDataRead::readChunkedPostData(char* inBuffer,
+int HttpDataRead::readChunkedPostData(const char* inBuffer,
                                       u_long *inBufferPos,
                                       u_long inBufferSize,
                                       Socket *inSocket,
@@ -124,12 +125,13 @@
                                       u_long outBufferSize,
                                       u_long* outNbr,
                                       u_long timeout,
-                                      File* out)
+                                      Stream* out,
+                                      long maxChunks)
 {
   u_long nbr;
   *outNbr = 0;
 
-  for(;;)
+  for (int n = 0; maxChunks == 0 || n < maxChunks; n++)
   {
     u_long chunkNbr;
     u_long dataToRead;
@@ -203,10 +205,8 @@
 
       chunkNbr += nbr;
 
-      if(out->writeToFile(outBuffer, nbr, &nbw))
-      {
+      if (out && out->write (outBuffer, nbr, &nbw))
         return -1;
-      }
 
       if(nbw != nbr)
         return -1;
@@ -337,7 +337,8 @@
                                     td->secondaryBuffer->getRealLength() - 1,
                                     &nbr,
                                     timeout,
-                                    &(td->inputData));
+                                    &(td->inputData),
+                                    0);
 
       if(ret == -1)
       {





reply via email to

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