You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@locus.apache.org on 2000/03/25 16:00:10 UTC

cvs commit: apache-2.0/src/modules/standard mod_cgi.c mod_include.c

rbb         00/03/25 07:00:10

  Modified:    src      CHANGES
               src/include httpd.h
               src/main http_config.c http_core.c http_protocol.c
               src/modules/standard mod_cgi.c mod_include.c
  Log:
  Enabled layered I/O.  Docs are forthcoming.
  
  Revision  Changes    Path
  1.46      +4 -0      apache-2.0/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/CHANGES,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -r1.45 -r1.46
  --- CHANGES	2000/03/24 10:54:23	1.45
  +++ CHANGES	2000/03/25 15:00:08	1.46
  @@ -1,4 +1,8 @@
   Changes with Apache 2.0a2-dev
  +  *) Enabled layered I/O.  Docs can be found in the developers
  +     section of the manual.
  +     [Ryan Bloom]
  +
     *) Allow BeOS to survive restarts, log properly and a few
        small things it had problems with due to the way it setup
        users and groups. [David Reid]
  
  
  
  1.33      +11 -1     apache-2.0/src/include/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/httpd.h,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- httpd.h	2000/03/19 13:28:42	1.32
  +++ httpd.h	2000/03/25 15:00:08	1.33
  @@ -391,8 +391,11 @@
   				 *  - it's safe to die() with no more output
   				 */
   #define OK 0			/* Module has handled this stage. */
  +#define RERUN_HANDLERS 1        /* Module has handled this request, but
  +                                 * realizes others may also want to handle
  +                                 * it.
  +                                 */
   
  -
   /* ----------------------- HTTP Status Codes  ------------------------- */
   
   /* The size of the static array in http_protocol.c for storing
  @@ -579,6 +582,13 @@
       ap_context_t *pool;
       conn_rec *connection;
       server_rec *server;
  +
  +    BUFF *input;                /* Where to get the data (usually a pipe
  +                                 * or a file currently). 
  +                                 */
  +    BUFF *output;               /* Where to send the data (usually, a pipe
  +                                 * or the socket currently).
  +                                 */
   
       request_rec *next;		/* If we wind up getting redirected,
   				 * pointer to the request we redirected to.
  
  
  
  1.30      +43 -36    apache-2.0/src/main/http_config.c
  
  Index: http_config.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_config.c,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- http_config.c	2000/03/23 14:48:45	1.29
  +++ http_config.c	2000/03/25 15:00:09	1.30
  @@ -308,53 +308,60 @@
       const char *handler;
       char *p;
       size_t handler_len;
  -    int result = HTTP_INTERNAL_SERVER_ERROR;
  +    int result;
   
  -    if (r->handler) {
  -	handler = r->handler;
  -	handler_len = strlen(handler);
  -    }
  -    else {
  -	handler = r->content_type ? r->content_type : ap_default_type(r);
  -	if ((p = strchr(handler, ';')) != NULL) { /* MIME type arguments */
  -	    while (p > handler && p[-1] == ' ')
  -		--p;		/* strip trailing spaces */
  -	    handler_len = p - handler;
  -	}
  -	else {
  +    do {
  +        result = DECLINED;
  +        if (r->handler) {
  +    	    handler = r->handler;
   	    handler_len = strlen(handler);
  -	}
  -    }
  -
  -    /* Pass one --- direct matches */
  -
  -    for (handp = handlers; handp->hr.content_type; ++handp) {
  -	if (handler_len == handp->len
  -	    && !strncmp(handler, handp->hr.content_type, handler_len)) {
  -            result = (*handp->hr.handler) (r);
  +        }
  +        else {
  +	    handler = r->content_type ? r->content_type : ap_default_type(r);
  +	    if ((p = strchr(handler, ';')) != NULL) { /* MIME type arguments */
  +    	        while (p > handler && p[-1] == ' ')
  +		    --p;		/* strip trailing spaces */
  +	        handler_len = p - handler;
  +	    }
  +	    else {
  +	        handler_len = strlen(handler);
  +	    }
  +        }
   
  -            if (result != DECLINED)
  -                return result;
  +        /* Pass one --- direct matches */
  + 
  +        for (handp = handlers; handp->hr.content_type; ++handp) {
  +    	    if (handler_len == handp->len
  +	        && !strncmp(handler, handp->hr.content_type, handler_len)) {
  +                result = (*handp->hr.handler) (r);
  +
  +                if (result != DECLINED)
  +                    break;
  +            }
           }
  -    }
   
  -    /* Pass two --- wildcard matches */
  +        /* Pass two --- wildcard matches */
   
  -    for (handp = wildhandlers; handp->hr.content_type; ++handp) {
  -	if (handler_len >= handp->len
  -	    && !strncmp(handler, handp->hr.content_type, handp->len)) {
  -             result = (*handp->hr.handler) (r);
  -
  -             if (result != DECLINED)
  -                 return result;
  -         }
  -    }
  +        if (result == DECLINED) {
  +            for (handp = wildhandlers; handp->hr.content_type; ++handp) {
  +    	        if (handler_len >= handp->len
  +	            && !strncmp(handler, handp->hr.content_type, handp->len)) {
  +                    result = (*handp->hr.handler) (r);
  +
  +                    if (result != DECLINED)
  +                        break;
  +                 }
  +            }
  +        }
  +    } while (result == RERUN_HANDLERS);
   
       if (result == HTTP_INTERNAL_SERVER_ERROR && r->handler && r->filename) {
           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r,
               "handler \"%s\" not found for: %s", r->handler, r->filename);
  +        return HTTP_INTERNAL_SERVER_ERROR;
       }
  -    return HTTP_INTERNAL_SERVER_ERROR;
  + 
  +    return result;
   }
   
   int g_bDebugHooks;
  
  
  
  1.43      +6 -4      apache-2.0/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_core.c,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- http_core.c	2000/03/22 09:46:38	1.42
  +++ http_core.c	2000/03/25 15:00:09	1.43
  @@ -2530,12 +2530,15 @@
       if (r->method_number != M_GET) {
           return METHOD_NOT_ALLOWED;
       }
  -	
  +/*	
       if ((status = ap_open(&fd, r->filename, APR_READ | APR_BINARY, 0, r->pool)) != APR_SUCCESS) {
           ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
   		     "file permissions deny server access: %s", r->filename);
           return FORBIDDEN;
  -    }
  +    }*/
  +
  +    ap_setup_input(r);
  +
       ap_update_mtime(r, r->finfo.mtime);
       ap_set_last_modified(r);
       ap_set_etag(r);
  @@ -2583,7 +2586,7 @@
   	
   	if (!r->header_only) {
   	    if (!rangestatus) {
  -		ap_send_fd(fd, r);
  +		ap_send_fb(r->input, r);
   	    }
   	    else {
   		long     length;
  @@ -2634,7 +2637,6 @@
       }
   #endif
   
  -    ap_close(fd);
       return OK;
   }
   
  
  
  
  1.57      +72 -35    apache-2.0/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- http_protocol.c	2000/03/13 20:27:20	1.56
  +++ http_protocol.c	2000/03/25 15:00:09	1.57
  @@ -959,6 +959,30 @@
       ap_overlap_tables(r->headers_in, tmp_headers, AP_OVERLAP_TABLES_MERGE);
   }
   
  +ap_status_t ap_setup_input(request_rec *r)
  +{
  +    BUFF *temp = NULL;
  +    ap_iol *iol;
  +    ap_file_t *fd = NULL;
  +    ap_status_t status;
  +
  +    if (!r->input) {
  +        if ((status = ap_open(&fd, r->filename, APR_READ | APR_BINARY, 0, r->pool)) != APR_SUCCESS) {
  +            ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
  +                         "file permissions deny server access: %s", r->filename);
  +            return status;
  +        }
  +
  +        iol = ap_create_file_iol(fd);
  +        if (!iol)
  +            return APR_EBADF;
  +        temp = ap_bcreate(r->pool, B_RD);
  +        ap_bpush_iol(temp, iol);   
  +        r->input = temp;
  +    }
  +    return APR_SUCCESS;
  +}
  +
   request_rec *ap_read_request(conn_rec *conn)
   {
       request_rec *r;
  @@ -1860,10 +1884,13 @@
       long chunk_start = 0;
       unsigned long max_body;
       ap_status_t rv;
  +    BUFF *used_buff;
  +
  +    used_buff = r->input ? r->input : r->connection->client;
   
       if (!r->read_chunked) {     /* Content-length read */
           len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
  -        rv = ap_bread(r->connection->client, buffer, len_to_read, &len_read);
  +        rv = ap_bread(used_buff, buffer, len_to_read, &len_read);
           if (len_read == 0) {    /* error or eof */
               if (rv != APR_SUCCESS) {
                   r->connection->keepalive = -1;
  @@ -1902,7 +1929,7 @@
   
       if (r->remaining == 0) {    /* Start of new chunk */
   
  -        chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
  +        chunk_start = getline(buffer, bufsiz, used_buff, 0);
           if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
               || !ap_isxdigit(*buffer)) {
               r->connection->keepalive = -1;
  @@ -1943,7 +1970,7 @@
           len_read = chunk_start;
   
           while ((bufsiz > 1) && ((len_read =
  -                  getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {
  +                  getline(buffer, bufsiz, used_buff, 1)) > 0)) {
   
               if (len_read != (bufsiz - 1)) {
                   buffer[len_read++] = CR;        /* Restore footer line end  */
  @@ -1977,7 +2004,7 @@
   
       len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
   
  -    (void) ap_bread(r->connection->client, buffer, len_to_read, &len_read);
  +    (void) ap_bread(used_buff, buffer, len_to_read, &len_read);
       if (len_read == 0) {        /* error or eof */
           r->connection->keepalive = -1;
           return -1;
  @@ -1986,8 +2013,8 @@
       r->remaining -= len_read;
   
       if (r->remaining == 0) {    /* End of chunk, get trailing CRLF */
  -        if ((c = ap_bgetc(r->connection->client)) == CR) {
  -            c = ap_bgetc(r->connection->client);
  +        if ((c = ap_bgetc(used_buff)) == CR) {
  +            c = ap_bgetc(used_buff);
           }
           if (c != LF) {
               r->connection->keepalive = -1;
  @@ -2050,16 +2077,17 @@
    */
   API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r)
   {
  +    BUFF *used_buff = r->output ? r->output : r->connection->client;
       long len = r->finfo.size;
   #ifdef HAVE_SENDFILE
       if (!r->chunked) {
   	ap_status_t rv;
  -        ap_bsetopt(r->connection->client, BO_TIMEOUT,
  +        ap_bsetopt(used_buff, BO_TIMEOUT,
                      r->connection->keptalive
                      ? &r->server->keep_alive_timeout
                      : &r->server->timeout);
  -        ap_bflush(r->connection->client);
  -        rv = iol_sendfile(r->connection->client->iol, 
  +        ap_bflush(used_buff);
  +        rv = iol_sendfile(used_buff->iol, 
                             fd,     /* The file to send */
                             NULL,   /* header and trailer iovecs */
                             0,      /* Offset in file to begin sending from */
  @@ -2070,7 +2098,7 @@
                             "ap_send_fd: iol_sendfile failed.");
           }
           if (r->connection->keptalive) {
  -            ap_bsetopt(r->connection->client, BO_TIMEOUT, 
  +            ap_bsetopt(used_buff, BO_TIMEOUT, 
                          &r->server->timeout);
           }
       }
  @@ -2091,6 +2119,7 @@
       ap_ssize_t w;
       ap_ssize_t n;
       ap_status_t rv;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client;
   
       if (length == 0)
           return 0;
  @@ -2113,7 +2142,7 @@
           o = 0;
   
           while (n && !ap_is_aborted(r->connection)) {
  -            rv = ap_bwrite(r->connection->client, &buf[o], n, &w);
  +            rv = ap_bwrite(used_buff, &buf[o], n, &w);
               if (w > 0) {
                   total_bytes_sent += w;
                   n -= w;
  @@ -2123,7 +2152,7 @@
                   if (!ap_is_aborted(r->connection)) {
                       ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, r,
                        "client stopped connection before send body completed");
  -                    ap_bsetflag(r->connection->client, B_EOUT, 1);
  +                    ap_bsetflag(used_buff, B_EOUT, 1);
                       r->connection->aborted = 1;
                   }
                   break;
  @@ -2152,6 +2181,7 @@
       ap_ssize_t w;
       ap_ssize_t n;
       ap_status_t rv;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client;
   
       if (length == 0) {
           return 0;
  @@ -2193,7 +2223,7 @@
           
           o = 0;
           while (n && !ap_is_aborted(r->connection)) {
  -            rv = ap_bwrite(r->connection->client, &buf[o], n, &w);
  +            rv = ap_bwrite(used_buff, &buf[o], n, &w);
               if (w > 0) {
                   total_bytes_sent += w;
                   n -= w;
  @@ -2203,7 +2233,7 @@
                   if (!ap_is_aborted(r->connection)) {
                       ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, r,
                           "client stopped connection before rflush completed");
  -                    ap_bsetflag(r->connection->client, B_EOUT, 1);
  +                    ap_bsetflag(used_buff, B_EOUT, 1);
                       r->connection->aborted = 1;
                   }
                   break;
  @@ -2238,6 +2268,7 @@
       ap_ssize_t w;
       ap_status_t rv;
       char *addr;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client;
       
       if (length == 0)
           return 0;
  @@ -2254,7 +2285,7 @@
   
           while (n && !r->connection->aborted) {
               ap_mmap_offset((void**)&addr, mm, offset);
  -            rv = ap_bwrite(r->connection->client, addr, n, &w);
  +            rv = ap_bwrite(used_buff, addr, n, &w);
               if (w > 0) {
                   total_bytes_sent += w;
                   n -= w;
  @@ -2268,7 +2299,7 @@
                   else {
                       ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, r,
                        "client stopped connection before send mmap completed");
  -                    ap_bsetflag(r->connection->client, B_EOUT, 1);
  +                    ap_bsetflag(used_buff, B_EOUT, 1);
                       r->connection->aborted = 1;
                       break;
                   }
  @@ -2283,15 +2314,16 @@
   
   API_EXPORT(int) ap_rputc(int c, request_rec *r)
   {
  +    BUFF *used_buff = r->output ? r->output : r->connection->client;
       if (r->connection->aborted)
           return EOF;
   
  -    if (ap_bputc(c, r->connection->client) < 0) {
  +    if (ap_bputc(c, used_buff) < 0) {
           if (!r->connection->aborted) {
               ap_log_rerror(APLOG_MARK, APLOG_INFO,
  -                ap_berror(r->connection->client), r,
  +                ap_berror(used_buff), r,
                   "client stopped connection before rputc completed");
  -            ap_bsetflag(r->connection->client, B_EOUT, 1);
  +            ap_bsetflag(used_buff, B_EOUT, 1);
               r->connection->aborted = 1;
           }
           return EOF;
  @@ -2303,17 +2335,18 @@
   API_EXPORT(int) ap_rputs(const char *str, request_rec *r)
   {
       int rcode;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client; 
   
       if (r->connection->aborted)
           return EOF;
       
  -    rcode = ap_bputs(str, r->connection->client);
  +    rcode = ap_bputs(str, used_buff);
       if (rcode < 0) {
           if (!r->connection->aborted) {
               ap_log_rerror(APLOG_MARK, APLOG_INFO,
  -                ap_berror(r->connection->client), r,
  +                ap_berror(used_buff), r,
                   "client stopped connection before rputs completed");
  -            ap_bsetflag(r->connection->client, B_EOUT, 1);
  +            ap_bsetflag(used_buff, B_EOUT, 1);
               r->connection->aborted = 1;
           }
           return EOF;
  @@ -2326,16 +2359,17 @@
   {
       ap_ssize_t n;
       ap_status_t rv;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client; 
   
       if (r->connection->aborted)
           return EOF;
   
  -    rv = ap_bwrite(r->connection->client, buf, nbyte, &n);
  +    rv = ap_bwrite(used_buff, buf, nbyte, &n);
       if (n < 0) {
           if (!r->connection->aborted) {
               ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, r,
                   "client stopped connection before rwrite completed");
  -            ap_bsetflag(r->connection->client, B_EOUT, 1);
  +            ap_bsetflag(used_buff, B_EOUT, 1);
               r->connection->aborted = 1;
           }
           return EOF;
  @@ -2347,18 +2381,19 @@
   API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list ap)
   {
       int n;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client; 
   
       if (r->connection->aborted)
           return -1;
   
  -    n = ap_vbprintf(r->connection->client, fmt, ap);
  +    n = ap_vbprintf(used_buff, fmt, ap);
   
       if (n < 0) {
           if (!r->connection->aborted) {
               ap_log_rerror(APLOG_MARK, APLOG_INFO,
  -                ap_berror(r->connection->client), r,
  +                ap_berror(used_buff), r,
                   "client stopped connection before vrprintf completed");
  -            ap_bsetflag(r->connection->client, B_EOUT, 1);
  +            ap_bsetflag(used_buff, B_EOUT, 1);
               r->connection->aborted = 1;
           }
           return -1;
  @@ -2371,20 +2406,21 @@
   {
       va_list vlist;
       int n;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client; 
   
       if (r->connection->aborted)
           return -1;
   
       va_start(vlist, fmt);
  -    n = ap_vbprintf(r->connection->client, fmt, vlist);
  +    n = ap_vbprintf(used_buff, fmt, vlist);
       va_end(vlist);
   
       if (n < 0) {
           if (!r->connection->aborted) {
               ap_log_rerror(APLOG_MARK, APLOG_INFO,
  -                ap_berror(r->connection->client), r,
  +                ap_berror(used_buff), r,
                   "client stopped connection before rprintf completed");
  -            ap_bsetflag(r->connection->client, B_EOUT, 1);
  +            ap_bsetflag(used_buff, B_EOUT, 1);
               r->connection->aborted = 1;
           }
           return -1;
  @@ -2399,7 +2435,7 @@
       ap_ssize_t i;
       int j, k;
       const char *x;
  -    BUFF *fb = r->connection->client;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client; 
       ap_status_t rv;
   
       if (r->connection->aborted)
  @@ -2411,13 +2447,13 @@
           if (x == NULL)
               break;
           j = strlen(x);
  -        rv = ap_bwrite(fb, x, j, &i);
  +        rv = ap_bwrite(used_buff, x, j, &i);
           if (i != j) {
               va_end(args);
               if (!r->connection->aborted) {
                   ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, r,
                       "client stopped connection before rvputs completed");
  -                ap_bsetflag(r->connection->client, B_EOUT, 1);
  +                ap_bsetflag(used_buff, B_EOUT, 1);
                   r->connection->aborted = 1;
               }
               return EOF;
  @@ -2433,12 +2469,13 @@
   API_EXPORT(int) ap_rflush(request_rec *r)
   {
       ap_status_t rv;
  +    BUFF *used_buff = r->output ? r->output : r->connection->client; 
   
  -    if ((rv = ap_bflush(r->connection->client)) != APR_SUCCESS) {
  +    if ((rv = ap_bflush(used_buff)) != APR_SUCCESS) {
           if (!ap_is_aborted(r->connection)) {
               ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, r,
                   "client stopped connection before rflush completed");
  -            ap_bsetflag(r->connection->client, B_EOUT, 1);
  +            ap_bsetflag(used_buff, B_EOUT, 1);
               r->connection->aborted = 1;
           }
           return EOF;
  
  
  
  1.31      +11 -7     apache-2.0/src/modules/standard/mod_cgi.c
  
  Index: mod_cgi.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_cgi.c,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- mod_cgi.c	2000/03/10 00:07:11	1.30
  +++ mod_cgi.c	2000/03/25 15:00:10	1.31
  @@ -621,7 +621,9 @@
   	    ap_table_unset(r->headers_in, "Content-Length");
   
   	    ap_internal_redirect_handler(location, r);
  -	    return OK;
  +/*            r->content_type = NULL;*/
  +            r->handler = NULL;
  +	    return RERUN_HANDLERS;
   	}
   	else if (location && r->status == 200) {
   	    /* XX Note that if a script wants to produce its own Redirect
  @@ -630,12 +632,12 @@
   	    return REDIRECT;
   	}
   
  -	ap_send_http_header(r);
  +/*	ap_send_http_header(r);*/
   	if (!r->header_only) {
  -	    ap_send_fb(script_in, r);
  +            r->input = script_in;
   	}
  -	ap_bclose(script_in);
  -
  +/*	ap_bclose(script_in);
  +*/
   	while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) {
   	    continue;
   	}
  @@ -643,10 +645,12 @@
       }
   
       if (script_in && nph) {
  -	ap_send_fb(script_in, r);
  +        r->input = script_in;
       }
   
  -    return OK;			/* NOT r->status, even if it has changed. */
  +/*    r->content_type = NULL;*/
  +    r->handler = NULL;
  +    return RERUN_HANDLERS;	/* NOT r->status, even if it has changed. */
   }
   
   static const handler_rec cgi_handlers[] =
  
  
  
  1.24      +53 -8     apache-2.0/src/modules/standard/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_include.c,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- mod_include.c	2000/03/15 12:00:51	1.23
  +++ mod_include.c	2000/03/25 15:00:10	1.24
  @@ -2364,20 +2364,30 @@
       return NULL;
   }
   
  -static int send_parsed_file(request_rec *r)
  +struct {
  +    ap_thread_t *thread;
  +    request_rec *r;
  +} ssi_rec;
  +
  +void * API_THREAD_FUNC sub_send_parsed_file(void *rec)
   {
       ap_file_t *f = NULL;
  +    struct ssi_rec *dumb_rec = (struct ssi_rec *)rec;
  +    ap_thread_t *subthread = dumb_rec->thread
  +    request_rec *r = dumb_rec->r;
       enum xbithack *state =
       (enum xbithack *) ap_get_module_config(r->per_dir_config, &includes_module);
       int errstatus;
       request_rec *parent;
   
       if (!(ap_allow_options(r) & OPT_INCLUDES)) {
  -        return DECLINED;
  +        ap_thread_exit(0);
  +/*        return DECLINED;*/
       }
       r->allowed |= (1 << M_GET);
       if (r->method_number != M_GET) {
  -        return DECLINED;
  +        ap_thread_exit(0);
  +/*        return DECLINED;*/
       }
       if (r->finfo.protection == 0) {
           ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
  @@ -2385,7 +2395,8 @@
                       (r->path_info
                        ? ap_pstrcat(r->pool, r->filename, r->path_info, NULL)
                        : r->filename));
  -        return HTTP_NOT_FOUND;
  +        ap_thread_exit(0);
  +/*        return HTTP_NOT_FOUND;*/
       }
   
       errstatus = ap_open(&f, r->filename, APR_READ, 0, r->pool);
  @@ -2393,7 +2404,8 @@
       if (errstatus != APR_SUCCESS) {
           ap_log_rerror(APLOG_MARK, APLOG_ERR, errstatus, r,
                       "file permissions deny server access: %s", r->filename);
  -        return HTTP_FORBIDDEN;
  +        ap_thread_exit(0);
  +/*        return HTTP_FORBIDDEN;*/
       }
   
       if ((*state == xbithack_full)
  @@ -2406,14 +2418,16 @@
           ap_set_last_modified(r);
       }
       if ((errstatus = ap_meets_conditions(r)) != OK) {
  -        return errstatus;
  +        ap_thread_exit(0);
  +/*        return errstatus;*/
       }
   
       ap_send_http_header(r);
   
       if (r->header_only) {
           ap_close(f);
  -        return OK;
  +        ap_thread_exit(0);
  +/*        return OK;*/
       }
   
       if ((parent = ap_get_module_config(r->request_config, &includes_module))) {
  @@ -2453,8 +2467,39 @@
   	ap_set_module_config(r->request_config, &includes_module,
   	    NESTED_INCLUDE_MAGIC);
       }
  +    ap_thread_exit(0);
  +/*    return OK;*/
  +}
  +
  +int send_parsed_file(request_rec *r)
  +{
  +    struct ssi_rec dumb_rec;
  +    ap_thread_t *subthread = NULL;
  +    ap_file_t *pipein = NULL;
  +    ap_file_t *pipeout = NULL;
  +    ap_iol *iolin;
  +    ap_iol *iolout;
  +    BUFF *bpipeint = NULL;
  +    BUFF *bpipeout = NULL;
  +
  +    ap_create_pipe(&pipein, &pipeout, r->pool);
  +
  +    iolin = ap_create_file_iol(pipein);
  +    ap_bpush_iol(bpipein, iolin);
  +
  +    iolout = ap_create_file_iol(pipeout);
  +    ap_bpush_iol(bpipeout, iolout);
  +    r->output = bpipeout;
  +
  +    ap_setup_input(r);
  +
  +    dumb_rec->thread = subthread;
  +    dumb_rec->r = r;
  +    ap_create_thread(&subthread, NULL, sub_send_parsed_file, dumb_rec, r->pool);
  +    r->input = bpipein;
  +        
   
  -    return OK;
  +    return RERUN_HANDLERS;
   }
   
   static int send_shtml_file(request_rec *r)
  
  
  

Re: cvs commit: apache-2.0/src/modules/standard mod_cgi.c mod_include.c

Posted by rb...@apache.org.
This was really a minor code change, although I will admit it results in
some major changes for modules. (Although, I believe it was coded so that
current modules are not affected);.  If this is not the case, then there
is a bug I need to find and fix.

I was asked to commit my changes yesterday, or I would have tested a bit
more before the commit.

Ryan

On Sun, 26 Mar 2000, Manoj Kasichainula wrote:

> On Sun, Mar 26, 2000 at 11:28:26AM -0500, Ryan Bloom wrote:
> > This design was discussed off-line.  Like most commits here, code means
> > more than talk, so I implemented it, assuming people would comment and
> > change it as they saw fit.  I didn't doo all that much work, most of the
> > work was debugging, not coding.  :-)
> 
> The general policy that I know of is to at least discuss major changes
> on the list to get a feel from the group. Even if they don't like the
> idea, you know going in to your work that they don't, and when others
> see your patch, they can understand its design because you already
> posted. Then, major functional patches are posted to the list for
> discussion, and then committed if there isn't objection.
> 
> 


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: cvs commit: apache-2.0/src/modules/standard mod_cgi.c mod_include.c

Posted by Manoj Kasichainula <ma...@io.com>.
On Sun, Mar 26, 2000 at 11:28:26AM -0500, Ryan Bloom wrote:
> This design was discussed off-line.  Like most commits here, code means
> more than talk, so I implemented it, assuming people would comment and
> change it as they saw fit.  I didn't doo all that much work, most of the
> work was debugging, not coding.  :-)

The general policy that I know of is to at least discuss major changes
on the list to get a feel from the group. Even if they don't like the
idea, you know going in to your work that they don't, and when others
see your patch, they can understand its design because you already
posted. Then, major functional patches are posted to the list for
discussion, and then committed if there isn't objection.


Re: layered I/O (was: cvs commit: ...)

Posted by rb...@apache.org.
> Below, you talk about doing this without performance implications. Well,
> that loop is one that you've added. :-)

The loop is a minimal performance hit, because each handler (when
re-written) should be generating content and passing it on, not generating
ALL of the content before passing it on the the next handler.

> I don't believe that the content-generators need to be changed AT ALL.
> They would continue to call ap_rput*() as they do now.
> 
> The content-processors would need to change the following kind of loop:
> 
>   content-handler:
>     fd = open()
>     while 1:
>       data = read()
>       if not data:
>         break
>       process_data(data)
> 
>   process_data(data):
>     ...
>     ap_rputs(monkeyed_output)
>     ...
> 
> to:
> 
>   some-hook-function:
>     register_processor(process_data)
> 
>   process_data(next_layer, data):
>     ...
>     ap_layer_puts(next_layer, monkeyed_output)
>     ...
> 
> I don't see a big change in the content-processors either. They just
> remove their file-read loop and register their processing function. The
> end of the chain does whatever ap_rput*() does now. The default handler is
> going to be grabbing the file and doing an ap_rwrite(), which is then
> going to be capture by mod_include (rather than mod_include reading the
> file).

> I definitely didn't want to back it out until we got a chance to comment
> back and forth a bit. That would be grossly unfair to you.

I'm not doing any more work today, if you would like to back it out, go
ahead.  If not, I'll back it out tomorrow morning.

> My hope was that you would also agree that it could be done
> differently/better and back out the changes. I'll do the backing out if
> you wish, but I felt it would be best to give you the option.
> 
> Along its current path, I do not agree this should be finished.

I will say that I have tried to implement this differently.  It didn't
work.  I had three other people sitting in a room trying to figure out the
correct way to implement this cleanly, so that it would work.  This was
the solution we came up with.  I had an idea very similar to the one you
have posted, BTW.  That was my first thought, and my first attempt.  It
didn't work for various reasons.  The biggest reason, was the buffering
between the different modules.  

> I have already posted my idea: ap_rput*() implements a set of hooks that
> can be intercepted by registering a callback function. In concrete terms,
> we implement an ap_iol that calls the callback when methods->write is
> invoked. Each time a processor calls register_processor(), we push one of
> these new BUFFs/IOLs onto the stack.
> 
> Performance implications? None. If there are no processors, then the "top
> BUFF" is connection->client. If somebody inserts something into the chain,
> then yes... you have overhead (which is a given!).
> 
> Note that each intermediate BUFF will probably buffer the output. This
> will minimize the number of calls to the callback.

Ah, here's the problem.  How much of the data are you going to buffer?
All of it?  Do you plan to buffer each page as it is being generated?
What happens with something like mod_include?  Which needs to have the
whole tag before it can really do it's work?  What about instances, where
mucking with the data after a given module is a no-no.  Need examples for
that case, I've got two.  SSL, where the module needs to be the thing
writting to the network.  Compression, where trying to modify the output
(other than encryption) would be a big no-no.

> 
> The processors will need to change from ap_rput*() to ap_bput*(), using
> the BUFF that is passed to the callback.
> 
> Are there holes in this design? Will this not work? (you ask for complete;
> I think this is complete, short of coding)

The coding is the rub. well, that plus the two issues I pointed out above.
Are you going to ask each module implementor to now also define an IOL?
How much of the IOL do they need to define?

I have given my implementation.  If the patch isn't backed out tomorrow
morning, I'll do it then.  I'm not going to try to implement I/O Layering
again (not sour grapes, just more projects I have to do, and I've spent
too much time on this one already).  If somebody else wants to, go ahead.

Ryan


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: layered I/O (was: cvs commit: ...)

Posted by Dean Gaudet <dg...@arctic.org>.
On Sun, 26 Mar 2000, Greg Stein wrote:

> Below, you talk about doing this without performance implications. Well,
> that loop is one that you've added. :-)

it's very easy to optimize the loop further -- by hashing the strings
which run the direct matches.

it's really helpful to consider a simple example:

accessing foo.cgi, which generates "Content-Type: text/x-parsed-html"
which requires mod_include to run.

to run foo.cgi r->handler is set to "cgi-handler", which assuming we do
the hash right, is picked off immediately and run without looping.

then r->content_type is updated, and set to "text/x-parsed-html", and
again, if we've done the hash right, then it's picked off immediately
without looping.

Dean


Re: layered I/O (was: cvs commit: ...)

Posted by rb...@apache.org.
> then ryan's design wasn't the design we drew on the whiteboard on
> thursday, and i apologize.  there is obviously no requirement that
> processors (i.e. filters) run in a separate thread.

My code had no such requirement.  I was making mod_include run in a thread
for the time being, so I could make it work.  That file wasn't supposed to
be committed, but I copied when I was supposed to move.  :-{ 

Ryan
_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: layered I/O (was: cvs commit: ...)

Posted by Dean Gaudet <dg...@arctic.org>.
On Mon, 27 Mar 2000, Greg Stein wrote:

> On Mon, 27 Mar 2000, Dean Gaudet wrote:
> > On Sun, 26 Mar 2000, Greg Stein wrote:
> > > I don't believe that the content-generators need to be changed AT ALL.
> > > They would continue to call ap_rput*() as they do now.
> > 
> > then you haven't thought on it hard enough.
> 
> That is why I posted. I'd thought enough about it to know that the initial
> design wasn't as good as it could be, but I didn't have the full story
> either.
> 
> >... pseudo-code ...
> > that's a massive change to the content-processor!
> > 
> > you've just made it so that the content-processor *can't use the stack to
> > store any context*.  all the context has to be moved to a structure which
> > is used by each call to the process_data function.
> > 
> > go take a look at mod_include, and tell me you can do this with no change.  
> > if so then i'll be really impressed.
> 
> Dude. Read my statement closer, rather than being confrontational.
> 
> I said: no changes to the content-GENERATORS.

i've already posted an example that makes this false:  mod_cgi.

> Bite me. You're being totally confrontational here, and it isn't called
> for. You didn't read my statements. I said no change to generators, and
> definite changes to processors.

no it is called for.

this item has been on the bullet list for as long as apache-2.0 has been a
wet dream.

there's been a fuckload of hand waving over the years, and *no code*.  
code speaks reams more in my book than anything else.

so far all i'm seeing is more hand waving, and cries that this isn't the
wet dream folks thought it would be.

welcome to reality.  if you folks would stop waving your hands and
actually try to code it up you'd probably understand our proposed
solution.

> Ryan's initial design had a similar requirement on the processors, but
> also had changes to make against the generators.

then ryan's design wasn't the design we drew on the whiteboard on
thursday, and i apologize.  there is obviously no requirement that
processors (i.e. filters) run in a separate thread.

Dean


Re: layered I/O (was: cvs commit: ...)

Posted by Greg Stein <gs...@lyra.org>.
On Mon, 27 Mar 2000, Dean Gaudet wrote:
> On Sun, 26 Mar 2000, Greg Stein wrote:
> > I don't believe that the content-generators need to be changed AT ALL.
> > They would continue to call ap_rput*() as they do now.
> 
> then you haven't thought on it hard enough.

That is why I posted. I'd thought enough about it to know that the initial
design wasn't as good as it could be, but I didn't have the full story
either.

>... pseudo-code ...
> that's a massive change to the content-processor!
> 
> you've just made it so that the content-processor *can't use the stack to
> store any context*.  all the context has to be moved to a structure which
> is used by each call to the process_data function.
> 
> go take a look at mod_include, and tell me you can do this with no change.  
> if so then i'll be really impressed.

Dude. Read my statement closer, rather than being confrontational.

I said: no changes to the content-GENERATORS.

I said: changes would be necessary to the content-PROCESSORS.

Your point is valid -- the processor changes are larger than my note
implied. I did understand that processors would generally need some kind
of state machine to deal with symbols/whatever that cross callback
boundaries.

Looking at mod_include: yes, it would take a big change, *if* you used the
callback mechanism. Ryan's sub-thread mechanism changes mod_include very
little -- the sub-thread runs send_parsed_file() and blocks on a pipe,
while the parent stuffs the pipe with data from the callback.

To be most efficient, mod_include could be changed into a tokenizing
parser. As each complete token comes in (via the callback), it drives some
output or grammar element.

> gah, you know -1s coming from folks who haven't worked out this problem
> are totally annoying.

Bite me. You're being totally confrontational here, and it isn't called
for. You didn't read my statements. I said no change to generators, and
definite changes to processors.

I will take the very valid criticism that I did not make it clear just how
much processors would change. The sub-thread / pipe means they don't have
to change much, or it could be a lot if they directly use callbacks.

But to call me annoying is out of line. I know enough of what I'm talking
about to recognize that the initial design could be much better. I posted
my thoughts because I also knew that I didn't have a complete and proper
design either. IMO, that is how things should operate, and you shouldn't
be calling me anything.

> > > No, the sub-thread design is a hack just to get it to work.  The
> > real way > this should be done, is to re-write mod_include to deal
> > well with > streaming data coming from the BUFF structure.
> > 
> > We agree on this at least :-). This was the rest of my email comments.
> 
> wow, you agree that content-processors require massive changes... above
> you claimed no changes would be required.

No changes to generators. Go read it again.

Ryan's initial design had a similar requirement on the processors, but
also had changes to make against the generators.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/



Re: layered I/O (was: cvs commit: ...)

Posted by rb...@apache.org.
> > BTW, I worked it out earlier today, I can modify the currently working
> > layered I/O code to require only two changes to current modules.  1)  They
> > have to set the output BUFF correctly.  2)  Modules that write out to the
> > network have to return STOP_HANDLERS.  Note, this is a change from what I
> > committed.  
> 
> actually i didn't look at your code, i assumed the above was what you did
> the first time ;)

It's the obvious next step, but I wanted to get working code before I got
clean code, and I didn't take a mop to it before I committed it.  :-} 

> 
> but that doesn't mean that mod_include would work without using a pipe()
> or another thread or any number of tricks to make it perform asynchronous
> to another thread reading from its output BUFF.

No, I stated that this was a necessary change in a later e-mail.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: layered I/O (was: cvs commit: ...)

Posted by Dean Gaudet <dg...@arctic.org>.
On Mon, 27 Mar 2000 rbb@apache.org wrote:

> 
> > that's a massive change to the content-processor!
> > 
> > you've just made it so that the content-processor *can't use the stack to
> > store any context*.  all the context has to be moved to a structure which
> > is used by each call to the process_data function.
> > 
> > go take a look at mod_include, and tell me you can do this with no change.  
> > if so then i'll be really impressed.
> 
> BTW, I worked it out earlier today, I can modify the currently working
> layered I/O code to require only two changes to current modules.  1)  They
> have to set the output BUFF correctly.  2)  Modules that write out to the
> network have to return STOP_HANDLERS.  Note, this is a change from what I
> committed.  

actually i didn't look at your code, i assumed the above was what you did
the first time ;)

but that doesn't mean that mod_include would work without using a pipe()
or another thread or any number of tricks to make it perform asynchronous
to another thread reading from its output BUFF.

Dean


Re: layered I/O (was: cvs commit: ...)

Posted by Ben Laurie <be...@algroup.co.uk>.
Chuck Murcko wrote:
> 
> Ben Laurie wrote:
> >
> > Greg Stein wrote:
> > > > 2)  Modules that write out to the
> > > > network have to return STOP_HANDLERS.  Note, this is a change from what I
> > > > committed.
> > >
> > > This is in reference to processors, correct? Could we just add a new hook
> > > for them? Rather than using STOP_HANDLERS, the network-writer could just
> > > be HOOK_REALLY_LAST.
> >
> > This whole thing is puzzling me - an I/O layer isn't a handler at all,
> > IMO - the last I/O layer is last by virtue of, err, being last in the
> > chain. Writing to the network _by definition_ should stop further
> > layering, because the next layer doesn't get called.
> >
> Except in cases like remote methods, yes?

Well, OK, but that's really just chaining done over the network. Doesn't
really alter my point. I don't think.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

Re: layered I/O (was: cvs commit: ...)

Posted by Chuck Murcko <ch...@topsail.org>.
Ben Laurie wrote:
> 
> Greg Stein wrote:
> > > 2)  Modules that write out to the
> > > network have to return STOP_HANDLERS.  Note, this is a change from what I
> > > committed.
> >
> > This is in reference to processors, correct? Could we just add a new hook
> > for them? Rather than using STOP_HANDLERS, the network-writer could just
> > be HOOK_REALLY_LAST.
> 
> This whole thing is puzzling me - an I/O layer isn't a handler at all,
> IMO - the last I/O layer is last by virtue of, err, being last in the
> chain. Writing to the network _by definition_ should stop further
> layering, because the next layer doesn't get called.
> 
Except in cases like remote methods, yes?
-- 
Chuck
Chuck Murcko
Topsail Group
chuck@topsail.org

Re: layered I/O (was: cvs commit: ...)

Posted by rb...@apache.org.
After listening to everybody's comments about the last layered I/O commit,
I have decided to re-implement.  This time, I will post patches, and let
people review them first.  Hopefully this set of work will be done this
weekend.  :-)

Ryan

On Thu, 30 Mar 2000, Ben Laurie wrote:

> Greg Stein wrote:
> > > 2)  Modules that write out to the
> > > network have to return STOP_HANDLERS.  Note, this is a change from what I
> > > committed.
> > 
> > This is in reference to processors, correct? Could we just add a new hook
> > for them? Rather than using STOP_HANDLERS, the network-writer could just
> > be HOOK_REALLY_LAST.
> 
> This whole thing is puzzling me - an I/O layer isn't a handler at all,
> IMO - the last I/O layer is last by virtue of, err, being last in the
> chain. Writing to the network _by definition_ should stop further
> layering, because the next layer doesn't get called.
> 
> Cheers,
> 
> Ben.
> 
> --
> http://www.apache-ssl.org/ben.html
> 


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: layered I/O (was: cvs commit: ...)

Posted by Ben Laurie <be...@algroup.co.uk>.
Greg Stein wrote:
> > 2)  Modules that write out to the
> > network have to return STOP_HANDLERS.  Note, this is a change from what I
> > committed.
> 
> This is in reference to processors, correct? Could we just add a new hook
> for them? Rather than using STOP_HANDLERS, the network-writer could just
> be HOOK_REALLY_LAST.

This whole thing is puzzling me - an I/O layer isn't a handler at all,
IMO - the last I/O layer is last by virtue of, err, being last in the
chain. Writing to the network _by definition_ should stop further
layering, because the next layer doesn't get called.

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

Re: layered I/O (was: cvs commit: ...)

Posted by Dean Gaudet <dg...@arctic.org>.
On Tue, 28 Mar 2000, Greg Stein wrote:

> > r->output = BUFF.
> 
> Um. How do you create the layering? This seems to be a single layer.

here let me expand on the example i started in a message to roy.

	typedef struct iol_compress {
		ap_iol iol;
		ap_iol *source;
	} iol_compress;

	static ap_status_t compress_read(ap_iol *viol, const char *buf,
		ap_size_t size, ap_ssize_t *nbytes)
	{
		iol_compress *iol = (iol_compress *)viol;

		read bytes from iol->source;
		compress them into buf;
	}

	ap_iol *compress_new(ap_iol *source)
	{
		iol_compress *iol;

		iol = malloc(sizeof(iol_compress));
		iol->iol.methods = &compress_methods;
		iol->source = source;
		return (ap_iol *)iol;
	}

that is to say, the layer is created by writing an iol which actually
expects an iol, or a BUFF as one of its initializers.  take a peek at
iol_socket.c, it's almost like this, except it expects an ap_socket_t *...
which is really just another layer.

as far as i can tell this implicit linkage is really bothering people --
they want explicit *next, *prev pointers in the stack of handlers.  i
don't see the point honestly -- they both achieve the same thing.

Dean


Re: layered I/O (was: cvs commit: ...)

Posted by Greg Stein <gs...@lyra.org>.
On Mon, 27 Mar 2000 rbb@apache.org wrote:
> > > > go take a look at mod_include, and tell me you can do this with no change.  
> > > > if so then i'll be really impressed.
> > > 
> > > BTW, I worked it out earlier today, I can modify the currently working
> > > layered I/O code to require only two changes to current modules.
> > 
> > Do generators need to be changed? Or do just the processors need these
> > modifications?
> 
> Generators and processors need to set the output BUFF, and some processors
> need to return STOP_HANDLERS.  Note, not all processors need modification
> (this doesn't include changes like the mod_include changes), only the
> processors that actually want to write to the network need to change.
> This should be http_core, and mod_ssl, AFAICT.

Hrm. Okay... not sure that I get this yet, but the code will explain it
quite well :-)

>...
> > > 1)  They
> > > have to set the output BUFF correctly.
> > 
> > Would it be possible to have a function for this (to properly bundle up
> > the aspects of a layer), rather than direct manipulation?
> 
> Sure, but it's a stupid thing to put behind a function, IMHO.  The
> function would basically take a request_rec and a BUFF *, and do:
> 
> r->output = BUFF.

Um. How do you create the layering? This seems to be a single layer.

For example, I could see a situation where we wanted SSI to run, then PHP.
Let's just assume the source comes from a file. Files are handled by the
core, so the core handler is called and starts reading the file. It writes
the contents of the file using ap_rwrite(). The buffer is passed to the
SSI module. It does some various munging and passes its output to PHP. PHP
munges some more and its output goes to the client.

Note that SSI and PHP execute "asynchronously" to use Dean's term.
Otherwise, you would need a temp file or a big-ass memory buffer.

The call stack looks kind of like:

  http_core:default_handler
  http_protocol:ap_rwrite
  mod_include:whatever
  ...:ap_layer_write   (maybe this is just ap_bwrite)
  mod_php:whatever
  ...:ap_layer_write
  http_protocol:ap_bwrite

>From another note, it seems like you're defining r->input to be the source
("generator"), and one layer sets itself to be r->output. But it appears
each layer must remember the previous r->output, rather than having Apache
deal with the chain. I suggested the function because it seems Apache
would be handling the layering under the covers; the function hides the
magic that Apache is using (hooking into ap_rwrite and linking the layers
together).

Also, to use the r->input scheme, this means certain content generators
(such as mod_dav) need to be rewritten to be callback-based.

I think there is a disconnect here somewhere... I'm seeing the
source/generator as driving the layers and the eventual network output. In
other words, the handler is called *once* and when it returns, the output
has been fully generated *and* processed.

It appears that in your model, the generator must create a BUFF (called
r->input). The processors can set r->output, but I'm not sure how they
layer. Then some code (where?) loops to read r->input and shoves that into
r->output. Is that right?

> > > 2)  Modules that write out to the
> > > network have to return STOP_HANDLERS.  Note, this is a change from what I
> > > committed.  
> > 
> > This is in reference to processors, correct? Could we just add a new hook
> > for them? Rather than using STOP_HANDLERS, the network-writer could just
> > be HOOK_REALLY_LAST.
> 
> No, because which one is HOOK_REALLY_LAST?  http_core.c or mod_ssl?  One
> of these has to write out to the network, and if the data needs to be
> encrypted, it can't be http_core.  But if the data isn't encrypted, it has
> to be http_core.  See the problem with using HOOK_REALLY_LAST?  Depending
> on the request different hooks get HOOK_REALLY_LAST.

Fair enough. I retracted the hook idea anyhow because of the need to have
the layers occur in a more controlled/predictable fashion.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/


Re: layered I/O (was: cvs commit: ...)

Posted by rb...@apache.org.
> > > go take a look at mod_include, and tell me you can do this with no change.  
> > > if so then i'll be really impressed.
> > 
> > BTW, I worked it out earlier today, I can modify the currently working
> > layered I/O code to require only two changes to current modules.
> 
> Do generators need to be changed? Or do just the processors need these
> modifications?

Generators and processors need to set the output BUFF, and some processors
need to return STOP_HANDLERS.  Note, not all processors need modification
(this doesn't include changes like the mod_include changes), only the
processors that actually want to write to the network need to change.
This should be http_core, and mod_ssl, AFAICT.

> 
> btw, it seemed from one of Ryan's posts that my differentiation wasn't
> clear. A "generator" is probably best described as a "source". The
> generator pulls the content off the disk, out of a database, via a CGI,
> etc. Next, processors are applied. These are the "layers". For example,
> mod_include processes the input and spits out something to the next layer
> (or the network if no layers).

This is done behind the scenes now.

> > 1)  They
> > have to set the output BUFF correctly.
> 
> Would it be possible to have a function for this (to properly bundle up
> the aspects of a layer), rather than direct manipulation?

Sure, but it's a stupid thing to put behind a function, IMHO.  The
function would basically take a request_rec and a BUFF *, and do:

r->output = BUFF.

> > 2)  Modules that write out to the
> > network have to return STOP_HANDLERS.  Note, this is a change from what I
> > committed.  
> 
> This is in reference to processors, correct? Could we just add a new hook
> for them? Rather than using STOP_HANDLERS, the network-writer could just
> be HOOK_REALLY_LAST.

No, because which one is HOOK_REALLY_LAST?  http_core.c or mod_ssl?  One
of these has to write out to the network, and if the data needs to be
encrypted, it can't be http_core.  But if the data isn't encrypted, it has
to be http_core.  See the problem with using HOOK_REALLY_LAST?  Depending
on the request different hooks get HOOK_REALLY_LAST.

> Thanks for the renewed look at this stuff, Ryan!
Always willing to work to get my patches in.  :-)

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------



Re: layered I/O (was: cvs commit: ...)

Posted by Greg Stein <gs...@lyra.org>.
On Mon, 27 Mar 2000 rbb@apache.org wrote:
> > that's a massive change to the content-processor!
> > 
> > you've just made it so that the content-processor *can't use the stack to
> > store any context*.  all the context has to be moved to a structure which
> > is used by each call to the process_data function.
> > 
> > go take a look at mod_include, and tell me you can do this with no change.  
> > if so then i'll be really impressed.
> 
> BTW, I worked it out earlier today, I can modify the currently working
> layered I/O code to require only two changes to current modules.

Do generators need to be changed? Or do just the processors need these
modifications?

btw, it seemed from one of Ryan's posts that my differentiation wasn't
clear. A "generator" is probably best described as a "source". The
generator pulls the content off the disk, out of a database, via a CGI,
etc. Next, processors are applied. These are the "layers". For example,
mod_include processes the input and spits out something to the next layer
(or the network if no layers).

> 1)  They
> have to set the output BUFF correctly.

Would it be possible to have a function for this (to properly bundle up
the aspects of a layer), rather than direct manipulation?

> 2)  Modules that write out to the
> network have to return STOP_HANDLERS.  Note, this is a change from what I
> committed.  

This is in reference to processors, correct? Could we just add a new hook
for them? Rather than using STOP_HANDLERS, the network-writer could just
be HOOK_REALLY_LAST.

Thanks for the renewed look at this stuff, Ryan!

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/


Re: layered I/O (was: cvs commit: ...)

Posted by rb...@apache.org.
> that's a massive change to the content-processor!
> 
> you've just made it so that the content-processor *can't use the stack to
> store any context*.  all the context has to be moved to a structure which
> is used by each call to the process_data function.
> 
> go take a look at mod_include, and tell me you can do this with no change.  
> if so then i'll be really impressed.

BTW, I worked it out earlier today, I can modify the currently working
layered I/O code to require only two changes to current modules.  1)  They
have to set the output BUFF correctly.  2)  Modules that write out to the
network have to return STOP_HANDLERS.  Note, this is a change from what I
committed.  

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: layered I/O (was: cvs commit: ...)

Posted by Dean Gaudet <dg...@arctic.org>.
On Sun, 26 Mar 2000, Greg Stein wrote:

> I don't believe that the content-generators need to be changed AT ALL.
> They would continue to call ap_rput*() as they do now.

then you haven't thought on it hard enough.

> The content-processors would need to change the following kind of loop:
> 
>   content-handler:
>     fd = open()
>     while 1:
>       data = read()
>       if not data:
>         break
>       process_data(data)
> 
>   process_data(data):
>     ...
>     ap_rputs(monkeyed_output)
>     ...
> 
> to:
> 
>   some-hook-function:
>     register_processor(process_data)
> 
>   process_data(next_layer, data):
>     ...
>     ap_layer_puts(next_layer, monkeyed_output)
>     ...
> 
> I don't see a big change in the content-processors either.

that's a massive change to the content-processor!

you've just made it so that the content-processor *can't use the stack to
store any context*.  all the context has to be moved to a structure which
is used by each call to the process_data function.

go take a look at mod_include, and tell me you can do this with no change.  
if so then i'll be really impressed.

gah, you know -1s coming from folks who haven't worked out this problem
are totally annoying.

> > No, the sub-thread design is a hack just to get it to work.  The
> real way > this should be done, is to re-write mod_include to deal
> well with > streaming data coming from the BUFF structure.
> 
> We agree on this at least :-). This was the rest of my email comments.

wow, you agree that content-processors require massive changes... above
you claimed no changes would be required.

Dean


Re: layered I/O (was: cvs commit: ...)

Posted by Greg Stein <gs...@lyra.org>.
On Sun, 26 Mar 2000, Greg Stein wrote:
> On Sun, 26 Mar 2000 rbb@apache.org wrote:
>...
> > > Your sub-thread design for mod_include seems fine, but note that all
> > > processors would need something similar. That general logic probably
> > > belongs in src/main, with a registered callback to process blocks of data:
> > 
> > No, the sub-thread design is a hack just to get it to work.  The real way
> > this should be done, is to re-write mod_include to deal well with
> > streaming data coming from the BUFF structure.
> 
> We agree on this at least :-). This was the rest of my email comments.

But after a bit more thinking, it is good to clarify something here. It
seems there are two forms that processors could use:

1) A callback with chunks of data; the callback will typically use a
   state machine to process elements of the content

2) A sub-thread mechanism where the module will now read from a pipe
   instead of a file

Option 2 has less impact on today's modules. Option 1 is (maybe?) less
resource intensive since you won't have sub-threads.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/


layered I/O (was: cvs commit: ...)

Posted by Greg Stein <gs...@lyra.org>.
On Sun, 26 Mar 2000 rbb@apache.org wrote:
> > -1
> > 
> > Per my previous mail, this design imposes too much knowledge on the module
> > writer. Also, the handler changing thing before returning RERUN_HANDLERS
> > seems a bit hacky.
> 
> I don't understand why this design imposes too much knowledge on module
> writers, as per my response to your last mail.  There are 2 changes that
> must be made, (well three if you include returning RERUN_HANDLERS).

As Ralf said, what is going to happen is that ALL content-generating
modules will have to return that code. They will ALL have to monkey with
r->handler before returning. Since they will always return RERUN_HANDLERS,
then Apache is going to LOOP until it doesn't find other handlers.

Below, you talk about doing this without performance implications. Well,
that loop is one that you've added. :-)

> > Sorry, but if this design was discussed at some point, then I missed it. I
> > would have like to comment before you did all this work :-(
> 
> This design was discussed off-line.  Like most commits here, code means
> more than talk, so I implemented it, assuming people would comment and
> change it as they saw fit.  I didn't doo all that much work, most of the
> work was debugging, not coding.  :-)

IMO, no code is better than code that follows a suboptimal design. If you
wanted comments, then posting a patch would be sufficient.
(just like Manoj explained)

> > It would seem that mod_include should hook the output chain in one of the
> > request processing hooks (which? dunno... post-translation so that it can
> > determine whether include processing is enabled, surely). The hook occurs
> > underneath ap_rput*(). No module would need to change to get the benefits
> > of mod_include.
> 
> But any module that wants to do what mod_include is doing would need to be
> seriously hacked instead.  That's a trade off.  I would MUCH rather see
> modules that are adding/modifying content not have to change too much,
> because these are much more common than modules that are generating
> content.

I don't believe that the content-generators need to be changed AT ALL.
They would continue to call ap_rput*() as they do now.

The content-processors would need to change the following kind of loop:

  content-handler:
    fd = open()
    while 1:
      data = read()
      if not data:
        break
      process_data(data)

  process_data(data):
    ...
    ap_rputs(monkeyed_output)
    ...

to:

  some-hook-function:
    register_processor(process_data)

  process_data(next_layer, data):
    ...
    ap_layer_puts(next_layer, monkeyed_output)
    ...

I don't see a big change in the content-processors either. They just
remove their file-read loop and register their processing function. The
end of the chain does whatever ap_rput*() does now. The default handler is
going to be grabbing the file and doing an ap_rwrite(), which is then
going to be capture by mod_include (rather than mod_include reading the
file).

> > Your sub-thread design for mod_include seems fine, but note that all
> > processors would need something similar. That general logic probably
> > belongs in src/main, with a registered callback to process blocks of data:
> 
> No, the sub-thread design is a hack just to get it to work.  The real way
> this should be done, is to re-write mod_include to deal well with
> streaming data coming from the BUFF structure.

We agree on this at least :-). This was the rest of my email comments.

> > Well... back to the -1. Should this change be backed out? Some portions of
> > it?
> 
> Please don't back any of it out until you have read my response to your
> criticisms, and some more people have looked over the code. I would also
> like the opportunity to finish the work, so people could look it over in
> it's entirety.

I definitely didn't want to back it out until we got a chance to comment
back and forth a bit. That would be grossly unfair to you.

My hope was that you would also agree that it could be done
differently/better and back out the changes. I'll do the backing out if
you wish, but I felt it would be best to give you the option.

Along its current path, I do not agree this should be finished.

> One of the reasons this change was committed, was to get people working on
> this problem.  Please, if you are going to back out this change, post a
> complete design for something else that works.

I have already posted my idea: ap_rput*() implements a set of hooks that
can be intercepted by registering a callback function. In concrete terms,
we implement an ap_iol that calls the callback when methods->write is
invoked. Each time a processor calls register_processor(), we push one of
these new BUFFs/IOLs onto the stack.

Performance implications? None. If there are no processors, then the "top
BUFF" is connection->client. If somebody inserts something into the chain,
then yes... you have overhead (which is a given!).

Note that each intermediate BUFF will probably buffer the output. This
will minimize the number of calls to the callback.

The processors will need to change from ap_rput*() to ap_bput*(), using
the BUFF that is passed to the callback.

Are there holes in this design? Will this not work? (you ask for complete;
I think this is complete, short of coding)

Thx,
-g

-- 
Greg Stein, http://www.lyra.org/



Re: cvs commit: apache-2.0/src/modules/standard mod_cgi.c mod_include.c

Posted by rb...@apache.org.

> -1
> 
> Per my previous mail, this design imposes too much knowledge on the module
> writer. Also, the handler changing thing before returning RERUN_HANDLERS
> seems a bit hacky.

I don't understand why this design imposes too much knowledge on module
writers, as per my response to your last mail.  There are 2 changes that
must be made, (well three if you include returning RERUN_HANDLERS).

> 
> Sorry, but if this design was discussed at some point, then I missed it. I
> would have like to comment before you did all this work :-(

This design was discussed off-line.  Like most commits here, code means
more than talk, so I implemented it, assuming people would comment and
change it as they saw fit.  I didn't doo all that much work, most of the
work was debugging, not coding.  :-)

> It would seem that mod_include should hook the output chain in one of the
> request processing hooks (which? dunno... post-translation so that it can
> determine whether include processing is enabled, surely). The hook occurs
> underneath ap_rput*(). No module would need to change to get the benefits
> of mod_include.

But any module that wants to do what mod_include is doing would need to be
seriously hacked instead.  That's a trade off.  I would MUCH rather see
modules that are adding/modifying content not have to change too much,
because these are much more common than modules that are generating
content.

> Your sub-thread design for mod_include seems fine, but note that all
> processors would need something similar. That general logic probably
> belongs in src/main, with a registered callback to process blocks of data:

No, the sub-thread design is a hack just to get it to work.  The real way
this should be done, is to re-write mod_include to deal well with
streaming data coming from the BUFF structure.

> Well... back to the -1. Should this change be backed out? Some portions of
> it?

Please don't back any of it out until you have read my response to your
criticisms, and some more people have looked over the code.  I would also
like the opportunity to finish the work, so people could look it over in
it's entirety.

One of the reasons this change was committed, was to get people working on
this problem.  Please, if you are going to back out this change, post a
complete design for something else that works.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: SSL as a layer? Ordering layers? (was: cvs commit: ...)

Posted by Dean Gaudet <dg...@arctic.org>.

On Tue, 28 Mar 2000, Greg Stein wrote:

> On Mon, 27 Mar 2000, Dean Gaudet wrote:
> > On Mon, 27 Mar 2000, Greg Stein wrote:
> > > <Location /greg>
> > >   # my PHP pages output SSI code
> > >   Processors PHP SSI
> > > </Location>
> > > <Location /ryan>
> > >   # my SSI pages yank in PHP chunks
> > >   Processors SSI PHP
> > > </Location>
> > 
> > this example doesn't consider the true complexity that has been asked for:  
> > the case where we don't know the resulting content-types/TE/etc. until we
> > run the handler.
> > 
> > i.e. mod_cgi, java, php, ...
> 
> A valid design choice: do the processors/filters run based on
> content-type, or do they always run?
> 
> You presume the former (more flexible), and I presumed the latter.

i presumed the former because one of the common cases asked for is
mod_include+mod_cgi.

Dean


Re: SSL as a layer? Ordering layers? (was: cvs commit: ...)

Posted by Greg Stein <gs...@lyra.org>.
On Mon, 27 Mar 2000, Dean Gaudet wrote:
> On Mon, 27 Mar 2000, Greg Stein wrote:
> > <Location /greg>
> >   # my PHP pages output SSI code
> >   Processors PHP SSI
> > </Location>
> > <Location /ryan>
> >   # my SSI pages yank in PHP chunks
> >   Processors SSI PHP
> > </Location>
> 
> this example doesn't consider the true complexity that has been asked for:  
> the case where we don't know the resulting content-types/TE/etc. until we
> run the handler.
> 
> i.e. mod_cgi, java, php, ...

A valid design choice: do the processors/filters run based on
content-type, or do they always run?

You presume the former (more flexible), and I presumed the latter.

It boils down to who has the knowledge about the filter chain. Do the
upstream source/filter know the magic mime types to invoke another filter?
Or is the filter just configured to run for certain directories, files,
etc?

I agree that a dynamic mechanism makes it more difficult.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/


Re: SSL as a layer? Ordering layers? (was: cvs commit: ...)

Posted by Dean Gaudet <dg...@arctic.org>.

On Mon, 27 Mar 2000, Greg Stein wrote:

> <Location /greg>
>   # my PHP pages output SSI code
>   Processors PHP SSI
> </Location>
> <Location /ryan>
>   # my SSI pages yank in PHP chunks
>   Processors SSI PHP
> </Location>

this example doesn't consider the true complexity that has been asked for:  
the case where we don't know the resulting content-types/TE/etc. until we
run the handler.

i.e. mod_cgi, java, php, ...

Dean


Re: SSL as a layer?

Posted by Ben Laurie <be...@algroup.co.uk>.
Dean Gaudet wrote:
> 
> On Mon, 27 Mar 2000 mark@mjwilcox.com wrote:
> 
> > My question is (and this maybe dumb, but it's never stopped me
> > before ;), how do things like client certificates get passed to other
> > modules. Will the SSL layer simply add to a generic environmental
> > structure?
> 
> this is how we do it currently isn't it?  i don't think we need to
> change...

Actually there is a change needed, though it may be only a philosophical
one: currently the environment variables tend to get added at the wrong
moment, because traditionally only CGIs needed them. This caused
problems both with KeyNote and JServ support for SSL.

It might be neater to add a hook that can be called to get environment
vars added (so its only done when actually needed). Or even one to ask
for a specific "environment variable's" value. Or both!

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

Re: SSL as a layer?

Posted by Dean Gaudet <dg...@arctic.org>.

On Mon, 27 Mar 2000 mark@mjwilcox.com wrote:

> My question is (and this maybe dumb, but it's never stopped me 
> before ;), how do things like client certificates get passed to other 
> modules. Will the SSL layer simply add to a generic environmental 
> structure? 

this is how we do it currently isn't it?  i don't think we need to
change...

Dean


Re: SSL as a layer?

Posted by ma...@mjwilcox.com.
On 27 Mar 00, at 17:01, Greg Stein wrote:

> On Mon, 27 Mar 2000 rbb@apache.org wrote:
> > I wrote:
> > > Do you mean that the SSL needs to write to the socket file descriptor Or
> > > simply that it must be the "last layer"? (by arranging to be last or
> > > hooking at the r->connection->client level?)
> > 
> > SSL must be the layer to actually write out to the network.  
> 
> To clarify: it must be the *last* layer. i.e. when it does something like
> ap_layer_write(), the contents spill out the socket.
> 
> Or do you mean the SSL layer must do send(fd, buf, len) ?
> 
> If the former, then I believe we simply ensure SSL is the last layer. If
> the latter, then how does it hook in today? Replace conn->client->iol? If
> so, then we aren't obviating that with any of the suggested designs.
> 
> > That's one of the reasons this model doesn't work, and why modules must
> > know if they have other modules to operate on the data.
> 
> I don't see how this follows. A processing module writes its "output" to
> the "next layer". That next layer is truly a layer, or it is
> connection->client. But the processor doesn't have to know that...
> 
I agree with Greg and Ryan. SSL  in Apache should be like it is 
with the SSL libraries in Perl or Java. You simply write to the 
socket (or layer in this case) and be done with it. 

My question is (and this maybe dumb, but it's never stopped me 
before ;), how do things like client certificates get passed to other 
modules. Will the SSL layer simply add to a generic environmental 
structure? 

Mark




Re: SSL as a layer?

Posted by rb...@apache.org.
> > > Or do you mean the SSL layer must do send(fd, buf, len) ?
> > 
> > The SSL library must make the send call.  At least that's the way it is
> > with the SSL library I know.  The SSL library doesn't take a string and
> > return the encrypted string, it takes a string and writes it to the
> > network.
> 
> I assume the SSL library you know is OpenSSL. If so, you are wrong.
> OpenSSL has its own layering scheme (called BIOs).

No, I know a proprietary SSL module.  I keep meaning to look at OpenSSL,
but I haven't had time recently.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: SSL as a layer?

Posted by Ben Laurie <be...@algroup.co.uk>.
rbb@apache.org wrote:
> 
> > > > simply that it must be the "last layer"? (by arranging to be last or
> > > > hooking at the r->connection->client level?)
> > >
> > > SSL must be the layer to actually write out to the network.
> >
> > To clarify: it must be the *last* layer. i.e. when it does something like
> > ap_layer_write(), the contents spill out the socket.
> >
> > Or do you mean the SSL layer must do send(fd, buf, len) ?
> 
> The SSL library must make the send call.  At least that's the way it is
> with the SSL library I know.  The SSL library doesn't take a string and
> return the encrypted string, it takes a string and writes it to the
> network.

I assume the SSL library you know is OpenSSL. If so, you are wrong.
OpenSSL has its own layering scheme (called BIOs).

Cheers,

Ben.

--
http://www.apache-ssl.org/ben.html

Re: SSL as a layer?

Posted by rb...@apache.org.
> > > simply that it must be the "last layer"? (by arranging to be last or
> > > hooking at the r->connection->client level?)
> > 
> > SSL must be the layer to actually write out to the network.  
> 
> To clarify: it must be the *last* layer. i.e. when it does something like
> ap_layer_write(), the contents spill out the socket.
> 
> Or do you mean the SSL layer must do send(fd, buf, len) ?

The SSL library must make the send call.  At least that's the way it is
with the SSL library I know.  The SSL library doesn't take a string and
return the encrypted string, it takes a string and writes it to the
network.

> If the former, then I believe we simply ensure SSL is the last layer. If
> the latter, then how does it hook in today? Replace conn->client->iol? If
> so, then we aren't obviating that with any of the suggested designs.

That's the problem.  One of the goals of layered I/O, is to get rid of the
core changes required to implement SSL.

> I don't see how this follows. A processing module writes its "output" to
> the "next layer". That next layer is truly a layer, or it is
> connection->client. But the processor doesn't have to know that...

No, the processor doesn't need to know that, but the next layer does need
to know what happened in the layer above it, or there will be an error
condition in the logs.  I am 99% sure that if the default handler is
called with an empty file, that's going to cause an error.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: SSL as a layer?

Posted by Greg Stein <gs...@lyra.org>.
On Mon, 27 Mar 2000 rbb@apache.org wrote:
> I wrote:
> > Do you mean that the SSL needs to write to the socket file descriptor Or
> > simply that it must be the "last layer"? (by arranging to be last or
> > hooking at the r->connection->client level?)
> 
> SSL must be the layer to actually write out to the network.  

To clarify: it must be the *last* layer. i.e. when it does something like
ap_layer_write(), the contents spill out the socket.

Or do you mean the SSL layer must do send(fd, buf, len) ?

If the former, then I believe we simply ensure SSL is the last layer. If
the latter, then how does it hook in today? Replace conn->client->iol? If
so, then we aren't obviating that with any of the suggested designs.

> That's one of the reasons this model doesn't work, and why modules must
> know if they have other modules to operate on the data.

I don't see how this follows. A processing module writes its "output" to
the "next layer". That next layer is truly a layer, or it is
connection->client. But the processor doesn't have to know that...

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/


Re: SSL as a layer? Ordering layers? (was: cvs commit: ...)

Posted by rb...@apache.org.
> Do you mean that the SSL needs to write to the socket file descriptor Or
> simply that it must be the "last layer"? (by arranging to be last or
> hooking at the r->connection->client level?)
> 

SSL must be the layer to actually write out to the network.  

That's one of the reasons this model doesn't work, and why modules must
know if they have other modules to operate on the data.

Ryan

> Last layer could be arranged, and it doesn't seem that we'd be changing
> the conn->client stuff (thus providing the same hook point).
> 
> Imagine if we inserted a hook right before the content-handler. Call it
> something like "register-processors". SSL could hook that call as
> HOOK_REALLY_LAST. mod_include would be HOOK_MIDDLE.
> 
> Personally, I think a bunch of stuff vying for HOOK_MIDDLE is rather
> non-deterministic to the page author. A directive to state the ordering is
> necessary:
> 
> <Location /greg>
>   # my PHP pages output SSI code
>   Processors PHP SSI
> </Location>
> <Location /ryan>
>   # my SSI pages yank in PHP chunks
>   Processors SSI PHP
> </Location>
> 
> SSL would probably just insert its layer without regard to the directive.
> 
> Disclaimer: I have no idea/design on how to get to the above directive
> suggestion. Just food for thought...
> 
> Cheers,
> -g
> 
> -- 
> Greg Stein, http://www.lyra.org/
> 
> 


_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------



SSL as a layer? Ordering layers? (was: cvs commit: ...)

Posted by Greg Stein <gs...@lyra.org>.
On Sun, 26 Mar 2000 rbb@apache.org wrote:
> > It would seem that mod_include should hook the output chain in one of the
> > request processing hooks (which? dunno... post-translation so that it can
> > determine whether include processing is enabled, surely). The hook occurs
> > underneath ap_rput*(). No module would need to change to get the benefits
> > of mod_include.
> 
> BTW, this design doesn't work.  At least one SSL library that I know of,
> absolutley must use it's own routines to write to the network.  with this

Do you mean that the SSL needs to write to the socket file descriptor? Or
simply that it must be the "last layer"? (by arranging to be last or
hooking at the r->connection->client level?)

Last layer could be arranged, and it doesn't seem that we'd be changing
the conn->client stuff (thus providing the same hook point).

Imagine if we inserted a hook right before the content-handler. Call it
something like "register-processors". SSL could hook that call as
HOOK_REALLY_LAST. mod_include would be HOOK_MIDDLE.

Personally, I think a bunch of stuff vying for HOOK_MIDDLE is rather
non-deterministic to the page author. A directive to state the ordering is
necessary:

<Location /greg>
  # my PHP pages output SSI code
  Processors PHP SSI
</Location>
<Location /ryan>
  # my SSI pages yank in PHP chunks
  Processors SSI PHP
</Location>

SSL would probably just insert its layer without regard to the directive.

Disclaimer: I have no idea/design on how to get to the above directive
suggestion. Just food for thought...

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/


Re: cvs commit: apache-2.0/src/modules/standard mod_cgi.c mod_include.c

Posted by rb...@apache.org.
> It would seem that mod_include should hook the output chain in one of the
> request processing hooks (which? dunno... post-translation so that it can
> determine whether include processing is enabled, surely). The hook occurs
> underneath ap_rput*(). No module would need to change to get the benefits
> of mod_include.

BTW, this design doesn't work.  At least one SSL library that I know of,
absolutley must use it's own routines to write to the network.  with this
design, the SSL module would be called to do the writing, and then the
data would be modified.  This would require core changes.

With the current design, mod_include does it's thing, and then the SSL
module gets to use it's own routines to actually write to the network.

I'll be modifying some of the layered I/O changes to address some of the
concerns brought up earlier today.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: cvs commit: apache-2.0/src/modules/standard mod_cgi.c mod_include.c

Posted by Greg Stein <gs...@lyra.org>.
On 25 Mar 2000 rbb@locus.apache.org wrote:
> rbb         00/03/25 07:00:10
> 
>   Modified:    src      CHANGES
>                src/include httpd.h
>                src/main http_config.c http_core.c http_protocol.c
>                src/modules/standard mod_cgi.c mod_include.c
>   Log:
>   Enabled layered I/O.  Docs are forthcoming.

-1

Per my previous mail, this design imposes too much knowledge on the module
writer. Also, the handler changing thing before returning RERUN_HANDLERS
seems a bit hacky.

Sorry, but if this design was discussed at some point, then I missed it. I
would have like to comment before you did all this work :-(

It would seem that mod_include should hook the output chain in one of the
request processing hooks (which? dunno... post-translation so that it can
determine whether include processing is enabled, surely). The hook occurs
underneath ap_rput*(). No module would need to change to get the benefits
of mod_include.

For input processing, the hook would be underneath ap_get_client_block()
and friends. Not exactly sure what an input hook would do, tho.

Your sub-thread design for mod_include seems fine, but note that all
processors would need something similar. That general logic probably
belongs in src/main, with a registered callback to process blocks of data:

  ap_status_t my_processor(void *ctx, void *buf, size_t len)

len==0 when the request is complete and the callback should also finish.

Note that the callback mechanism could be used from ap_rput*() rather than
a sub-thread.


Well... back to the -1. Should this change be backed out? Some portions of
it?

thx,
-g

-- 
Greg Stein, http://www.lyra.org/