]> granicus.if.org Git - apache/commitdiff
Pick up various EBCDIC fixes from 1.3 (from Martin Kraemer and Oliver
authorJeff Trawick <trawick@apache.org>
Wed, 10 May 2000 19:07:43 +0000 (19:07 +0000)
committerJeff Trawick <trawick@apache.org>
Wed, 10 May 2000 19:07:43 +0000 (19:07 +0000)
Reh originally according to the change log).

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85176 13f79535-47bb-0310-9956-ffa450edef68

modules/http/http_protocol.c
server/util.c

index aaca570fbbc18064f85356a74a3ae0cac736521b..335f249801f8dd7ad58da8ae6129049d871ad7f3 100644 (file)
@@ -90,6 +90,27 @@ AP_HOOK_STRUCT(
           ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \
   } while (0)
 
+#ifdef CHARSET_EBCDIC
+/* Save & Restore the current conversion settings
+ * "input"  means: ASCII -> EBCDIC (when reading MIME Headers and PUT/POST data)
+ * "output" means: EBCDIC -> ASCII (when sending MIME Headers and Chunks)
+ */
+
+#define PUSH_EBCDIC_INPUTCONVERSION_STATE(_buff, _onoff) \
+        int _convert_in = ap_bgetflag(_buff, B_ASCII2EBCDIC); \
+        ap_bsetflag(_buff, B_ASCII2EBCDIC, _onoff);
+
+#define POP_EBCDIC_INPUTCONVERSION_STATE(_buff) \
+        ap_bsetflag(_buff, B_ASCII2EBCDIC, _convert_in);
+
+#define PUSH_EBCDIC_OUTPUTCONVERSION_STATE(_buff, _onoff) \
+        int _convert_out = ap_bgetflag(_buff, B_EBCDIC2ASCII); \
+        ap_bsetflag(_buff, B_EBCDIC2ASCII, _onoff);
+
+#define POP_EBCDIC_OUTPUTCONVERSION_STATE(_buff) \
+        ap_bsetflag(_buff, B_EBCDIC2ASCII, _convert_out);
+
+#endif /*CHARSET_EBCDIC*/
 
 /*
  * Builds the content-type that should be sent to the client from the
@@ -260,6 +281,13 @@ static int internal_byterange(int realreq, long *tlength, request_rec *r,
 {
     long range_start, range_end;
     char *range;
+#ifdef CHARSET_EBCDIC
+    /* determine current setting of conversion flag,
+     * set to ON (protocol strings MUST be converted)
+     * and reset to original setting before returning
+     */
+    PUSH_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client, 1);
+#endif /*CHARSET_EBCDIC*/
 
     if (!**r_range) {
         if (r->byterange > 1) {
@@ -268,11 +296,17 @@ static int internal_byterange(int realreq, long *tlength, request_rec *r,
             else
                 *tlength += 4 + strlen(r->boundary) + 4;
         }
+#ifdef CHARSET_EBCDIC
+        POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
+#endif /*CHARSET_EBCDIC*/
         return 0;
     }
 
     range = ap_getword(r->pool, r_range, ',');
     if (!parse_byterange(range, r->clength, &range_start, &range_end))
+#ifdef CHARSET_EBCDIC
+        POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
+#endif /*CHARSET_EBCDIC*/
         /* Skip this one */
         return internal_byterange(realreq, tlength, r, r_range, offset,
                                   length);
@@ -299,6 +333,9 @@ static int internal_byterange(int realreq, long *tlength, request_rec *r,
     else {
         *tlength += range_end - range_start + 1;
     }
+#ifdef CHARSET_EBCDIC
+    POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
+#endif /*CHARSET_EBCDIC*/
     return 1;
 }
 
@@ -713,6 +750,17 @@ static int getline(char *s, int n, BUFF *in, int fold)
     char *pos, next;
     int retval;
     int total = 0;
+#ifdef CHARSET_EBCDIC
+    /* When getline() is called, the HTTP protocol is in a state
+     * where we MUST be reading "plain text" protocol stuff,
+     * (Request line, MIME headers, Chunk sizes) regardless of
+     * the MIME type and conversion setting of the document itself.
+     * Save the current setting of the ASCII-EBCDIC conversion flag
+     * for uploads, then temporarily set it to ON
+     * (and restore it before returning).
+     */
+    PUSH_EBCDIC_INPUTCONVERSION_STATE(in, 1);
+#endif /*CHARSET_EBCDIC*/
 
     pos = s;
 
@@ -756,6 +804,11 @@ static int getline(char *s, int n, BUFF *in, int fold)
                   && (next = ap_blookc(in))
                   && ((next == ' ') || (next == '\t')));
 
+#ifdef CHARSET_EBCDIC
+    /* restore ASCII->EBCDIC conversion state */
+    POP_EBCDIC_INPUTCONVERSION_STATE(in);
+#endif /*CHARSET_EBCDIC*/
+
     return total;
 }
 
@@ -1349,9 +1402,6 @@ API_EXPORT(void) ap_basic_http_header(request_rec *r)
 {
     char *protocol;
     char *date = NULL;
-#ifdef CHARSET_EBCDIC
-    int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
-#endif /*CHARSET_EBCDIC*/
 
     if (r->assbackwards)
         return;
@@ -1373,7 +1423,7 @@ API_EXPORT(void) ap_basic_http_header(request_rec *r)
         protocol = AP_SERVER_PROTOCOL;
 
 #ifdef CHARSET_EBCDIC
-    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
+    { PUSH_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client, 1);
 #endif /*CHARSET_EBCDIC*/
 
     /* Output the HTTP/1.x Status-Line and the Date and Server fields */
@@ -1388,8 +1438,7 @@ API_EXPORT(void) ap_basic_http_header(request_rec *r)
     ap_table_unset(r->headers_out, "Date");        /* Avoid bogosity */
     ap_table_unset(r->headers_out, "Server");
 #ifdef CHARSET_EBCDIC
-    if (!convert)
-        ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
+    POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client); }
 #endif /*CHARSET_EBCDIC*/
 }
 
@@ -1591,9 +1640,6 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
     int i;
     const long int zero = 0L;
     char *date = NULL;
-#ifdef CHARSET_EBCDIC
-    int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
-#endif /*CHARSET_EBCDIC*/
 
     if (r->assbackwards) {
         if (!r->main)
@@ -1628,7 +1674,7 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
     ap_basic_http_header(r);
 
 #ifdef CHARSET_EBCDIC
-    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
+    { PUSH_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client, 1);
 #endif /*CHARSET_EBCDIC*/
 
     ap_set_keepalive(r);
@@ -1682,8 +1728,7 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
     if (r->chunked)
         ap_bsetflag(r->connection->client, B_CHUNK, 1);
 #ifdef CHARSET_EBCDIC
-    if (!convert)
-        ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
+    POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client); }
 #endif /*CHARSET_EBCDIC*/
 }
 
@@ -1695,6 +1740,9 @@ API_EXPORT(void) ap_send_http_header(request_rec *r)
 API_EXPORT(void) ap_finalize_request_protocol(request_rec *r)
 {
     if (r->chunked && !r->connection->aborted) {
+#ifdef CHARSET_EBCDIC
+       PUSH_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client, 1);
+#endif
         /*
          * Turn off chunked encoding --- we can only do this once.
          */
@@ -1704,6 +1752,10 @@ API_EXPORT(void) ap_finalize_request_protocol(request_rec *r)
         ap_rputs("0" CRLF, r);
         /* If we had footer "headers", we'd send them now */
         ap_rputs(CRLF, r);
+
+#ifdef CHARSET_EBCDIC
+       POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
+#endif /*CHARSET_EBCDIC*/
     }
 }
 
@@ -1799,6 +1851,23 @@ API_EXPORT(int) ap_setup_client_block(request_rec *r, int read_policy)
         return HTTP_REQUEST_ENTITY_TOO_LARGE;
     }
 
+#ifdef CHARSET_EBCDIC
+    {
+        /* @@@ Temporary kludge for guessing the conversion @@@
+         * from looking at the MIME header. 
+         * If no Content-Type header is found, text conversion is assumed.
+         */
+        const char *typep = ap_table_get(r->headers_in, "Content-Type");
+        int convert_in = (typep == NULL ||
+                          strncasecmp(typep, "text/", 5) == 0 ||
+                          strncasecmp(typep, "message/", 8) == 0 ||
+                          strncasecmp(typep, "multipart/", 10) == 0 ||
+                          strcasecmp (typep, "application/x-www-form-urlencoded") == 0
+                         );
+        ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, convert_in);
+    }
+#endif
+
     return OK;
 }
 
@@ -1987,9 +2056,20 @@ API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
     r->remaining -= len_read;
 
     if (r->remaining == 0) {    /* End of chunk, get trailing CRLF */
+#ifdef CHARSET_EBCDIC
+        /* Chunk end is Protocol stuff! Set conversion = 1 to read CR LF: */
+        PUSH_EBCDIC_INPUTCONVERSION_STATE(r->connection->client, 1);
+#endif /*CHARSET_EBCDIC*/
+
         if ((c = ap_bgetc(r->connection->client)) == CR) {
             c = ap_bgetc(r->connection->client);
         }
+
+#ifdef CHARSET_EBCDIC
+        /* restore ASCII->EBCDIC conversion state */
+        POP_EBCDIC_INPUTCONVERSION_STATE(r->connection->client);
+#endif /*CHARSET_EBCDIC*/
+
         if (c != LF) {
             r->connection->keepalive = -1;
             return -1;
index 5f6db30393778ac9178c25cefcc9a16bd21ac41b..b5d06c8067cf680cd5da8bf4f0e09ae8f19ea108 100644 (file)
@@ -1516,7 +1516,7 @@ API_EXPORT(char *) ap_construct_server(ap_pool_t *p, const char *hostname,
 
 /* c2x takes an unsigned, and expects the caller has guaranteed that
  * 0 <= what < 256... which usually means that you have to cast to
- * unsigned char first, because (unsigned)(char)(x) fist goes through
+ * unsigned char first, because (unsigned)(char)(x) first goes through
  * signed extension to an int before the unsigned cast.
  *
  * The reason for this assumption is to assist gcc code generation --
@@ -1528,6 +1528,9 @@ static const char c2x_table[] = "0123456789abcdef";
 
 static ap_inline unsigned char *c2x(unsigned what, unsigned char *where)
 {
+#ifdef CHARSET_EBCDIC
+    what = os_toascii[what];
+#endif /*CHARSET_EBCDIC*/
     *where++ = '%';
     *where++ = c2x_table[what >> 4];
     *where++ = c2x_table[what & 0xf];