You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Alexei Kosut <ak...@nueva.pvt.k12.ca.us> on 1996/10/08 06:18:47 UTC

patch for 100 Continue and other things

Following is a patch that makes Apache send, as per the HTTP/1.1 spec,
100 responses for POST and PUT requests. It also adds commenting to
the new *_client_block routines, so people know what they mean, and
renames read_client_block to get_client_block, so older modules will
not compile and link (since they break HTTP/1.1 compatibility and
don't work anyway, I believe they should be forced to rewrite them -
it's easy, anyhow).

BTW, someone has to fix mod_fastcgi.c to use
setup/should/get_client_block. I looked at it, and it just confused
me, but unless someone does, I will veto any public release of Apache
with this version of mod_fastcgi in it.

Here's the patch:

Index: http_config.h
===================================================================
RCS file: /export/home/cvs/apache/src/http_config.h,v
retrieving revision 1.12
diff -c -r1.12 http_config.h
*** http_config.h	1996/10/06 02:25:02	1.12
--- http_config.h	1996/10/08 04:07:16
***************
*** 215,221 ****
   * handle it back-compatibly, or at least signal an error).
   */
  
! #define MODULE_MAGIC_NUMBER 19960806
  #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, 0, __FILE__, NULL
  
  /* Generic accessors for other modules to get at their own module-specific
--- 215,221 ----
   * handle it back-compatibly, or at least signal an error).
   */
  
! #define MODULE_MAGIC_NUMBER 19961007
  #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, 0, __FILE__, NULL
  
  /* Generic accessors for other modules to get at their own module-specific
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.51
diff -c -r1.51 http_protocol.c
*** http_protocol.c	1996/09/30 05:56:25	1.51
--- http_protocol.c	1996/10/08 04:07:30
***************
*** 1051,1056 ****
--- 1051,1085 ----
  
  }
  
+ /* Here we deal with getting input from the client. This can be in the
+  * form of POST or PUT (other methods can be added later), and may be
+  * transmitted in either a fixed content-length or via chunked
+  * transfer-coding.
+  *
+  * Note that this is more complicated than it was in Apache 1.1 and prior
+  * versions, because chunked support means that the module does less.
+  *
+  * The proper procedure is this:
+  * 1. Call setup_client_block() near the beginning of the request
+  *    handler. This will set up all the neccessary properties, and
+  *    will return either OK, or an error code. If the latter,
+  *    the module should return that error code.
+  *
+  * 2. When you are ready to possibly accept input, call should_client_block().
+  *    This will tell the module whether or not to read input. If it is 0,
+  *    the module should assume that the input is of a non-entity type
+  *    (e.g. a GET request). This step also sends a 100 Continue response
+  *    to HTTP/1.1 clients, so should not be called until the module
+  *    is *defenitely* ready to read content. (otherwise, the point of the
+  *    100 response is defeated). Never call this function more than once.
+  *
+  * 3. Finally, call get_client_block in a loop. Pass it a buffer and its
+  *    size. It will put data into the buffer (not neccessarily the full
+  *    buffer, in the case of chunked inputs), and return the length of
+  *    the input block. When it is done reading, it will return 0.
+  *
+  */
+ 
  int setup_client_block (request_rec *r)
  {
      char *tenc = table_get (r->headers_in, "Transfer-Encoding");
***************
*** 1078,1084 ****
  }
  
  int should_client_block (request_rec *r) {
!     return (r->method_number == M_POST || r->method_number == M_PUT);
  }
  
  static int rd_chunk_size (BUFF *b) {
--- 1107,1122 ----
  }
  
  int should_client_block (request_rec *r) {
!    if (r->method_number != M_POST && r->method_number != M_PUT)
!        return 0;
! 
!    if (r->proto_num >= 1001) {
!        bvputs(r->connection->client,
! 	      SERVER_PROTOCOL, " 100 Continue\015\012\015\012", NULL);
!        bflush(r->connection->client);
!    }
! 
!    return 1;
  }
  
  static int rd_chunk_size (BUFF *b) {
***************
*** 1103,1109 ****
      return (c == EOF) ? -1 : chunksize;
  }
  
! long read_client_block (request_rec *r, char *buffer, int bufsiz)
  {
      long c, len_read, len_to_read = r->remaining;
  
--- 1141,1147 ----
      return (c == EOF) ? -1 : chunksize;
  }
  
! long get_client_block (request_rec *r, char *buffer, int bufsiz)
  {
      long c, len_read, len_to_read = r->remaining;
  
Index: http_protocol.h
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.h,v
retrieving revision 1.8
diff -c -r1.8 http_protocol.h
*** http_protocol.h	1996/08/20 11:50:50	1.8
--- http_protocol.h	1996/10/08 04:07:36
***************
*** 133,139 ****
       
  int setup_client_block (request_rec *r);
  int should_client_block (request_rec *r);
! long read_client_block (request_rec *r, char *buffer, int bufsiz);
  
  /* Sending a byterange */
  
--- 133,139 ----
       
  int setup_client_block (request_rec *r);
  int should_client_block (request_rec *r);
! long get_client_block (request_rec *r, char *buffer, int bufsiz);
  
  /* Sending a byterange */
  
Index: mod_cgi.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
retrieving revision 1.18
diff -c -r1.18 mod_cgi.c
*** mod_cgi.c	1996/08/23 18:19:13	1.18
--- mod_cgi.c	1996/10/08 04:07:43
***************
*** 424,430 ****
          hard_timeout ("copy script args", r);
          handler = signal (SIGPIPE, SIG_IGN);
      
! 	while ((len_read = read_client_block (r, argsbuffer, HUGE_STRING_LEN)))
  	{
  	    if (fwrite (argsbuffer, 1, len_read, script_out) == 0)
  		break;
--- 424,430 ----
          hard_timeout ("copy script args", r);
          handler = signal (SIGPIPE, SIG_IGN);
      
! 	while ((len_read = get_client_block (r, argsbuffer, HUGE_STRING_LEN)))
  	{
  	    if (fwrite (argsbuffer, 1, len_read, script_out) == 0)
  		break;


-- 
________________________________________________________________________
Alexei Kosut <ak...@nueva.pvt.k12.ca.us>      The Apache HTTP Server
URL: http://www.nueva.pvt.k12.ca.us/~akosut/   http://www.apache.org/



Re: patch for 100 Continue and other things

Posted by ra...@bellglobal.com.
> Following is a patch that makes Apache send, as per the HTTP/1.1 spec,
> 100 responses for POST and PUT requests. It also adds commenting to
> the new *_client_block routines, so people know what they mean, and
> renames read_client_block to get_client_block, so older modules will
> not compile and link (since they break HTTP/1.1 compatibility and
> don't work anyway, I believe they should be forced to rewrite them -
> it's easy, anyhow).

You are giving me grey hairs Alexei..  Thanks for the comments though.
I shall fix mod_php right away to use this mechanism instead.

-Rasmus

Re: patch for 100 Continue and other things

Posted by ra...@bellglobal.com.
> Eek.  That's rough.  Is it mandated?  What's the logic behind such an
> incompatible change?  Does it suggest an increase in the API magic number?

Any change which affects the API, no matter how small, should cause the
module magic number to be bumped.  What I would really like to see is a
separate documentation file which lists the module magic number and then
the change(s) that caused the number to get bumped.  Without this it is
completely impossible to write a complex module which will work effectively
with all versions of Apache.

-Rasmus

Re: patch for 100 Continue and other things

Posted by Brian Behlendorf <br...@organic.com>.
On Mon, 7 Oct 1996, Alexei Kosut wrote:
> > Eek.  That's rough.  Is it mandated?  What's the logic behind such an
> > incompatible change?  Does it suggest an increase in the API magic number?
> 
> It's neccessary, yes. The reason is that, in the past, modules have handled
> reading client input by, basically, handling the protocol details
> themselves, and just calling an API function to read from the
> socket. This should never have been done in the first place, IMHO. All
> protocol stuff should be handled by functions in http_protocol.c. This
> is a perfect example why: HTTP/1.1 servers are required to handle
> chunked input and to send 100 responses. The way the modules were
> coded in the past, there was simply no way to do this without
> rewriting all the modules. So I did. It's that simple.
> 
> And, yes, the patch does increase the API magic number.

Okay, cool by me.  

	Brian

--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
brian@organic.com  www.apache.org  hyperreal.com  http://www.organic.com/JOBS


Re: patch for 100 Continue and other things

Posted by Alexei Kosut <ak...@nueva.pvt.k12.ca.us>.
On Mon, 7 Oct 1996, Brian Behlendorf wrote:

> On Mon, 7 Oct 1996, Alexei Kosut wrote:
> > Following is a patch that makes Apache send, as per the HTTP/1.1 spec,
> > 100 responses for POST and PUT requests. It also adds commenting to
> > the new *_client_block routines, so people know what they mean, and
> > renames read_client_block to get_client_block, so older modules will
> > not compile and link (since they break HTTP/1.1 compatibility and
> > don't work anyway, I believe they should be forced to rewrite them -
> > it's easy, anyhow).
> 
> Eek.  That's rough.  Is it mandated?  What's the logic behind such an
> incompatible change?  Does it suggest an increase in the API magic number?

It's neccessary, yes. The reason is that, in the past, modules have handled
reading client input by, basically, handling the protocol details
themselves, and just calling an API function to read from the
socket. This should never have been done in the first place, IMHO. All
protocol stuff should be handled by functions in http_protocol.c. This
is a perfect example why: HTTP/1.1 servers are required to handle
chunked input and to send 100 responses. The way the modules were
coded in the past, there was simply no way to do this without
rewriting all the modules. So I did. It's that simple.

And, yes, the patch does increase the API magic number.

-- 
________________________________________________________________________
Alexei Kosut <ak...@nueva.pvt.k12.ca.us>      The Apache HTTP Server
URL: http://www.nueva.pvt.k12.ca.us/~akosut/   http://www.apache.org/


Re: patch for 100 Continue and other things

Posted by Brian Behlendorf <br...@organic.com>.
On Mon, 7 Oct 1996, Alexei Kosut wrote:
> Following is a patch that makes Apache send, as per the HTTP/1.1 spec,
> 100 responses for POST and PUT requests. It also adds commenting to
> the new *_client_block routines, so people know what they mean, and
> renames read_client_block to get_client_block, so older modules will
> not compile and link (since they break HTTP/1.1 compatibility and
> don't work anyway, I believe they should be forced to rewrite them -
> it's easy, anyhow).

Eek.  That's rough.  Is it mandated?  What's the logic behind such an
incompatible change?  Does it suggest an increase in the API magic number?

	Brian

--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
brian@organic.com  www.apache.org  hyperreal.com  http://www.organic.com/JOBS