You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by pg...@sweng.stortek.com on 1999/12/07 00:03:31 UTC

[PATCH] (Was: Re: OS/390 Translation)

In a recent note, Jim Jagielski said:

> Date: Sat, 4 Dec 1999 16:55:55 -0500 (EST)
> 
> pg@sweng.stortek.com wrote:
> > 
> > In a recent note, Jim Jagielski said:
> > 
> > > Date: Sat, 4 Dec 1999 08:49:14 -0500 (EST)
> > > 
> > > Martin Kraemer wrote:
> > > > On Fri, Dec 03, 1999 at 03:55:23PM -0700, pg@sweng.stortek.com wrote:
> > > > > How about something like the attached (submitted for discussion,
> > > > > -                ap_rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
> > > > > +                ap_rvputs(r, CRLF"--", r->boundary, "--"CRLF, NULL);
> > > > 
> > > > Not bad. I like the idea.
> > > Me too :)
> > > 
> > What's the likely impact on non-ANSI compilers that lack compile-time
> > string abutment, but otherwise support Apache httpd?
> > 
> 
> Compiling Apache requires an ANSI compiler. Not necessarily ANSI functions,
> but an actual ANSI compiler. As such, it must support string cats.
> 
There seems to be considerable interest in this.  Here's a patch
relative to:

    http://dev.apache.org/from-cvs/apache-1.3/apache-1.3_19991206171242.tar.gz

This replaces most instances of '\012' and '\015' with macros. 
With this done, I can add a "#define os_toascii_strictly os_toascii",
and make the os_toascii table the same as the former
os_toascii_strictly.  So the behavior of ebcdic2ascii()
becomes identical to the prior behavior of ebcdic2ascii_strictly().

I haven't undertaken to replace calls to ebcdic2ascii_strictly()
with ebcdic2ascii() (yet).

Basic function works on OS/390 with the tables so coalesced.
I haven't tested proxy function.  I haven't tested or addressed
any changes in os/tpf or os/bs2000.

I added the new macro definitions to an existing "#ifdef" in
httpd.h (actually moved some from mod_proxy.h).  Are there
any opinions whether these macros should remain in httpd.h, or
is there a more suitable place, such as ap_config.h?

I must relinquish any claim to originality -- apparently someone
else had started this entire scheme in mod_proxy.h and proxy_ftp.c,
but not followed through with it.

-- gil
-- 
StorageTek
INFORMATION made POWERFUL
===========================================================================
diff -bru orig/apache-1.3/src/include/httpd.h apache-1.3/src/include/httpd.h
--- orig/apache-1.3/src/include/httpd.h	Thu Oct 21 19:14:41 1999
+++ apache-1.3/src/include/httpd.h	Mon Dec  6 14:01:33 1999
@@ -599,6 +599,8 @@
 #ifndef CHARSET_EBCDIC
 #define LF 10
 #define CR 13
+#define CRLF "\015\012"
+#define OS_TOASCII(c) (c)
 #else /* CHARSET_EBCDIC */
 #include "ebcdic.h"
 /* OSD_POSIX uses the EBCDIC charset. The transition ASCII->EBCDIC is done in
@@ -610,6 +612,8 @@
  */
 #define CR '\r'
 #define LF '\n'
+#define CRLF "\r\n"
+#define OS_TOASCII(c) (os_toascii[c])
 #endif /* CHARSET_EBCDIC */
 
 /* Possible values for request_rec.read_body (set by handling module):
diff -bru orig/apache-1.3/src/main/buff.c apache-1.3/src/main/buff.c
--- orig/apache-1.3/src/main/buff.c	Wed Dec  1 16:17:46 1999
+++ apache-1.3/src/main/buff.c	Mon Dec  6 14:01:33 1999
@@ -541,16 +541,16 @@
 	*strp++ = ' ';
 	++i;
     }
-    *strp++ = '\015';
-    *strp = '\012';
+    *strp++ = CR;
+    *strp = LF;
 #ifdef CHARSET_EBCDIC
     /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII */
     ebcdic2ascii(&fb->outbase[fb->outchunk], &fb->outbase[fb->outchunk], CHUNK_HEADER_SIZE);
 #endif /*CHARSET_EBCDIC*/
 
     /* tack on the trailing CRLF, we've reserved room for this */
-    fb->outbase[fb->outcnt++] = '\015';
-    fb->outbase[fb->outcnt++] = '\012';
+    fb->outbase[fb->outcnt++] = CR;
+    fb->outbase[fb->outcnt++] = LF;
 
     fb->outchunk = -1;
 }
@@ -875,27 +875,15 @@
 	}
 
 	ch = fb->inptr[i++];
-#ifndef CHARSET_EBCDIC
-	if (ch == '\012') {	/* got LF */
-	    if (ct == 0)
-		buff[ct++] = '\n';
-/* if just preceeded by CR, replace CR with LF */
-	    else if (buff[ct - 1] == '\015')
-		buff[ct - 1] = '\n';
-	    else if (ct < n - 1)
-		buff[ct++] = '\n';
-	    else
-		i--;		/* no room for LF */
-	    break;
-	}
-#else /* an EBCDIC machine: do the same, but convert to EBCDIC on the fly: */
+#ifdef CHARSET_EBCDIC
 	if (fb->flags & B_ASCII2EBCDIC)
 	    ch = os_toebcdic[(unsigned char)ch];
-	if (ch == os_toebcdic['\012']) {  /* got LF */
+#endif
+	if (ch == LF) {  /* got LF */
 	    if (ct == 0)
 		buff[ct++] = '\n';
 /* if just preceeded by CR, replace CR with LF */
-	    else if (buff[ct - 1] == os_toebcdic['\015'])
+	    else if (buff[ct - 1] == CR)
 		buff[ct - 1] = '\n';
 	    else if (ct < n - 1)
 		buff[ct++] = '\n';
@@ -903,7 +891,6 @@
 		i--;		/* no room for LF */
 	    break;
 	}
-#endif
 	if (ct == n - 1) {
 	    i--;		/* push back ch */
 	    break;
@@ -1160,7 +1147,7 @@
 #ifdef NO_WRITEV
     /* without writev() this has poor performance, too bad */
 
-    ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012", nbyte);
+    ap_snprintf(chunksize, sizeof(chunksize), "%x" CRLF, nbyte);
 #ifdef CHARSET_EBCDIC
     /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII */
     ebcdic2ascii(chunksize, chunksize, strlen(chunksize));
@@ -1169,12 +1156,12 @@
 	return -1;
     if (write_it_all(fb, buf, nbyte) == -1)
 	return -1;
-    if (write_it_all(fb, "\015\012", 2) == -1)
+    if (write_it_all(fb, CRLF, 2) == -1)
 	return -1;
     return nbyte;
 #else
     vec[0].iov_base = chunksize;
-    vec[0].iov_len = ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012",
+    vec[0].iov_len = ap_snprintf(chunksize, sizeof(chunksize), "%x" CRLF,
 				 nbyte);
 #ifdef CHARSET_EBCDIC
     /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII */
@@ -1182,7 +1169,7 @@
 #endif /*CHARSET_EBCDIC*/
     vec[1].iov_base = (void *) buf;	/* cast is to avoid const warning */
     vec[1].iov_len = nbyte;
-    vec[2].iov_base = "\015\012";
+    vec[2].iov_base = CRLF;
     vec[2].iov_len = 2;
 
     return writev_it_all(fb, vec, (sizeof(vec) / sizeof(vec[0]))) ? -1 : nbyte;
@@ -1214,7 +1201,7 @@
     if (fb->flags & B_CHUNK) {
 	vec[nvec].iov_base = chunksize;
 	vec[nvec].iov_len = ap_snprintf(chunksize, sizeof(chunksize),
-					"%x\015\012", nbyte);
+					"%x" CRLF, nbyte);
 #ifdef CHARSET_EBCDIC
     /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII */
 	ebcdic2ascii(chunksize, chunksize, strlen(chunksize));
@@ -1223,7 +1210,7 @@
 	vec[nvec].iov_base = (void *) buf;
 	vec[nvec].iov_len = nbyte;
 	++nvec;
-	vec[nvec].iov_base = "\015\012";
+	vec[nvec].iov_base = CRLF;
 	vec[nvec].iov_len = 2;
 	++nvec;
     }
diff -bru orig/apache-1.3/src/main/http_protocol.c apache-1.3/src/main/http_protocol.c
--- orig/apache-1.3/src/main/http_protocol.c	Mon Dec  6 10:13:29 1999
+++ apache-1.3/src/main/http_protocol.c	Mon Dec  6 14:01:34 1999
@@ -244,7 +244,7 @@
     if (!**r_range) {
         if (r->byterange > 1) {
             if (realreq)
-                ap_rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
+                ap_rvputs(r, CRLF"--", r->boundary, "--"CRLF, NULL);
             else
                 *tlength += 4 + strlen(r->boundary) + 4;
         }
@@ -271,8 +271,8 @@
         ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
                     r->clength);
         if (realreq)
-            ap_rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ",
-                   ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012",
+            ap_rvputs(r, CRLF"--", r->boundary, CRLF"Content-type: ",
+                   ct, CRLF"Content-range: bytes ", ts, CRLF""CRLF,
                    NULL);
         else
             *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 +
@@ -1334,7 +1334,7 @@
 API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r,
     const char *fieldname, const char *fieldval)
 {
-    return (0 < ap_rvputs(r, fieldname, ": ", fieldval, "\015\012", NULL));
+    return (0 < ap_rvputs(r, fieldname, ": ", fieldval, CRLF, NULL));
 }
 
 API_EXPORT(void) ap_basic_http_header(request_rec *r)
@@ -1366,7 +1366,7 @@
 
     /* Output the HTTP/1.x Status-Line and the Date and Server fields */
 
-    ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL);
+    ap_rvputs(r, protocol, " ", r->status_line, CRLF, NULL);
 
     ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time));
     ap_send_header_field(r, "Server", ap_get_server_version());
@@ -1401,9 +1401,9 @@
 
     ap_bgetopt(client, BO_BYTECT, &bs);
     if (bs >= 255 && bs <= 257)
-        ap_bputs("X-Pad: avoid browser bug\015\012", client);
+        ap_bputs("X-Pad: avoid browser bug"CRLF, client);
 
-    ap_bputs("\015\012", client);  /* Send the terminating empty line */
+    ap_bputs(CRLF, client);  /* Send the terminating empty line */
 }
 
 /* Build the Allow field-value from the request handler method mask.
@@ -1448,11 +1448,11 @@
 
     /* Now we recreate the request, and echo it back */
 
-    ap_rvputs(r, r->the_request, "\015\012", NULL);
+    ap_rvputs(r, r->the_request, CRLF, NULL);
 
     ap_table_do((int (*) (void *, const char *, const char *))
                 ap_send_header_field, (void *) r, r->headers_in, NULL);
-    ap_rputs("\015\012", r);
+    ap_rputs(CRLF, r);
 
     ap_kill_timeout(r);
     return OK;
@@ -1691,9 +1691,9 @@
         ap_bsetflag(r->connection->client, B_CHUNK, 0);
 
         ap_soft_timeout("send ending chunk", r);
-        ap_rputs("0\015\012", r);
+        ap_rputs("0"CRLF, r);
         /* If we had footer "headers", we'd send them now */
-        ap_rputs("\015\012", r);
+        ap_rputs(CRLF, r);
         ap_kill_timeout(r);
     }
 }
@@ -1819,7 +1819,7 @@
 
     if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) {
         /* sending 100 Continue interim response */
-        ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012",
+        ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], CRLF""CRLF,
                   NULL);
         ap_rflush(r);
     }
@@ -2694,8 +2694,8 @@
 	    }
 	    break;
 	case BAD_GATEWAY:
-	    ap_rputs("The proxy server received an invalid\015\012"
-	             "response from an upstream server.<P>\015\012", r);
+	    ap_rputs("The proxy server received an invalid"CRLF
+	             "response from an upstream server.<P>"CRLF, r);
 	    if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
 		ap_rvputs(r, error_notes, "<P>\n", NULL);
 	    }
diff -bru orig/apache-1.3/src/main/rfc1413.c apache-1.3/src/main/rfc1413.c
--- orig/apache-1.3/src/main/rfc1413.c	Wed Sep  1 01:12:32 1999
+++ apache-1.3/src/main/rfc1413.c	Mon Dec  6 14:01:34 1999
@@ -179,7 +179,7 @@
     i = 0;
     memset(buffer, '\0', sizeof(buffer));
     /*
-     * Note that the strchr function below checks for 10 instead of '\n'
+     * Note that the strchr function below checks for \012 instead of '\n'
      * this allows it to work on both ASCII and EBCDIC machines.
      */
     while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) {
diff -bru orig/apache-1.3/src/main/util_script.c apache-1.3/src/main/util_script.c
--- orig/apache-1.3/src/main/util_script.c	Sat Nov 27 10:12:37 1999
+++ apache-1.3/src/main/util_script.c	Mon Dec  6 14:01:34 1999
@@ -486,8 +486,12 @@
 	/* Delete terminal (CR?)LF */
 
 	p = strlen(w);
+        /* Indeed, the host's '\n':
+           '\012' for UNIX; '\015' for MacOS; '\025' for OS/390
+           -- whatever the script generates.
+        */
 	if (p > 0 && w[p - 1] == '\n') {
-	    if (p > 1 && w[p - 2] == '\015') {
+	    if (p > 1 && w[p - 2] == CR) {
 		w[p - 2] = '\0';
 	    }
 	    else {
diff -bru orig/apache-1.3/src/modules/proxy/mod_proxy.h apache-1.3/src/modules/proxy/mod_proxy.h
--- orig/apache-1.3/src/modules/proxy/mod_proxy.h	Mon Oct 11 19:13:48 1999
+++ apache-1.3/src/modules/proxy/mod_proxy.h	Mon Dec  6 14:01:35 1999
@@ -128,13 +128,6 @@
 /* maximum  'CacheDirLevels*CacheDirLength' value */
 #define CACHEFILE_LEN 20	/* must be less than HASH_LEN/2 */
 
-#ifdef CHARSET_EBCDIC
-#define CRLF   "\r\n"
-#else /*CHARSET_EBCDIC*/
-#define CRLF   "\015\012"
-#endif /*CHARSET_EBCDIC*/
-
-
 #define	SEC_ONE_DAY		86400	/* one day, in seconds */
 #define	SEC_ONE_HR		3600	/* one hour, in seconds */
 
diff -bru orig/apache-1.3/src/modules/proxy/proxy_ftp.c apache-1.3/src/modules/proxy/proxy_ftp.c
--- orig/apache-1.3/src/modules/proxy/proxy_ftp.c	Sat Aug 14 07:12:37 1999
+++ apache-1.3/src/modules/proxy/proxy_ftp.c	Mon Dec  6 14:01:35 1999
@@ -102,11 +102,7 @@
 	    ch = ap_proxy_hex2c(&x[i + 1]);
 	    i += 2;
 	}
-#ifndef CHARSET_EBCDIC
-	if (ch == '\015' || ch == '\012' || (ch & 0x80))
-#else /*CHARSET_EBCDIC*/
-	if (ch == '\r' || ch == '\n' || (os_toascii[ch] & 0x80))
-#endif /*CHARSET_EBCDIC*/
+	if (ch == CR || ch == LF || (OS_TOASCII(ch) & 0x80))
 	    return 0;
     }
     return 1;
@@ -778,7 +774,7 @@
 
     if (parms[0] != 'a') {
 	/* set type to image */
-	/* TM - Added \015\012 to the end of TYPE I, otherwise it hangs the
+	/* TM - Added CRLF to the end of TYPE I, otherwise it hangs the
 	   connection */
 	ap_bputs("TYPE I" CRLF, f);
 	ap_bflush(f);

Re: [PATCH] (Was: Re: OS/390 Translation)

Posted by Rodent of Unusual Size <Ke...@Golux.Com>.
Martin Kraemer wrote:
> 
> BTW: Do you prefer
>     CRLF"--"
> over
>     CRLF "--"

The latter is the way we've done it in Apache, ISTR.
-- 
#ken    P-)}

Ken Coar                    <http://Web.Golux.Com/coar/>
Apache Software Foundation  <http://www.apache.org/>
"Apache Server for Dummies" <http://ASFD.MeepZor.Com/>

Re: [PATCH] (Was: Re: OS/390 Translation)

Posted by Martin Kraemer <Ma...@mch.sni.de>.
On Mon, Dec 06, 1999 at 04:03:31PM -0700, pg@sweng.stortek.com wrote:
> There seems to be considerable interest in this.  Here's a patch
> relative to:
> 
>     http://dev.apache.org/from-cvs/apache-1.3/apache-1.3_19991206171242.tar.gz
> 
> This replaces most instances of '\012' and '\015' with macros. 

Yep, and it compiles and runs cleanly on my machine. +1!

BTW: Do you prefer
    CRLF"--"
over
    CRLF "--"
? The compiler (MY compiler, that is) eats both. I'm not 100% sure
that "abc""def" is tolerated by all compilers. "abc" "def" is.

    Martin
-- 
<Ma...@MchP.Siemens.De>             |    Fujitsu Siemens
Fon: +49-89-636-46021, FAX: +49-89-636-41143 | 81730  Munich,  Germany

Re: [PATCH] (Was: Re: OS/390 Translation)

Posted by Martin Kraemer <Ma...@mch.sni.de>.
On Mon, Dec 06, 1999 at 07:55:13PM -0700, pg@sweng.stortek.com wrote:
> I changed the '\015' to
> CR largely to cut the grep noise down and to add a comment explaining
> the rogue '\n'; I might have left it untouched.

I didn't want to say you made an error, I was trying to say there was an
error in apache!  Sorry if this wasn't clear enough.

    Martin
-- 
<Ma...@MchP.Siemens.De>             |    Fujitsu Siemens
Fon: +49-89-636-46021, FAX: +49-89-636-41143 | 81730  Munich,  Germany

Re: [PATCH] (Was: Re: OS/390 Translation)

Posted by Martin Kraemer <Ma...@mch.sni.de>.
On Mon, Dec 06, 1999 at 04:03:31PM -0700, pg@sweng.stortek.com wrote:
> Basic function works on OS/390 with the tables so coalesced.
> I haven't tested proxy function.  I haven't tested or addressed
> any changes in os/tpf or os/bs2000.

Uuh! I'm astonished that there were so few places wit \012's!

> I added the new macro definitions to an existing "#ifdef" in
> httpd.h (actually moved some from mod_proxy.h).  Are there
> any opinions whether these macros should remain in httpd.h, or
> is there a more suitable place, such as ap_config.h?

Maybe the AP_OS_TOASCII() could even be abbreviated as AP_ASC(ch)?
Personally, I'd leave them in httpd.h What do the others think?

> I must relinquish any claim to originality -- apparently someone
> else had started this entire scheme in mod_proxy.h and proxy_ftp.c,
> but not followed through with it.

I didn't dare ;-) When I'm making changes / doing cleanup in the proxy
I'm free to do many things which I could not do as global changes.
Or at least I would have to fight for a consensus much more.

> diff -bru orig/apache-1.3/src/main/util_script.c apache-1.3/src/main/util_script.c
> --- orig/apache-1.3/src/main/util_script.c	Sat Nov 27 10:12:37 1999
> +++ apache-1.3/src/main/util_script.c	Mon Dec  6 14:01:34 1999
> @@ -486,8 +486,12 @@
>  	/* Delete terminal (CR?)LF */
>  
>  	p = strlen(w);
> +        /* Indeed, the host's '\n':
> +           '\012' for UNIX; '\015' for MacOS; '\025' for OS/390
> +           -- whatever the script generates.
> +        */
>  	if (p > 0 && w[p - 1] == '\n') {
> -	    if (p > 1 && w[p - 2] == '\015') {
> +	    if (p > 1 && w[p - 2] == CR) {

Hmmm. Is this correct for MacOS? We have an ASCII based OS, so
CR == '\015', but the '\n' one line above is *also* '\015'.

Otherwise: untested +1 (maybe I'll find the time to compile it tomorrow).

    Martin
-- 
<Ma...@MchP.Siemens.De>             |    Fujitsu Siemens
Fon: +49-89-636-46021, FAX: +49-89-636-41143 | 81730  Munich,  Germany