martin      99/12/06 04:41:42

  Modified:    src      CHANGES
               src/main http_protocol.c
  Log:
  EBCDIC: Fixed binary upload capability (plain and chunked) for
  all methods using the ap_*_client_block() functions, most notably
  POST and PUT. The functionality to switch input between protocol
  parts (chunks) and (possibly binary) data had been missing all
  the time, making chunked PUT impossible until now.
  
  Hello TPF developers: I think these five lines in os/tpf/os.c
  ought to be removed:
      else{
             if (r->method_number == M_PUT)
                 ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, 0);
                 /* don't translate non-text files to EBCDIC */
      }
  Also, your change to Vincent's mod_put should be undone.
  
  In a next step, I will try to make EBCDIC conversion completely
  configurable. Any volunteers for helping (designing/implementing)?
  
  Revision  Changes    Path
  1.1470    +7 -0      apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.1469
  retrieving revision 1.1470
  diff -u -r1.1469 -r1.1470
  --- CHANGES   1999/12/04 11:43:12     1.1469
  +++ CHANGES   1999/12/06 12:41:35     1.1470
  @@ -1,5 +1,12 @@
   Changes with Apache 1.3.10
   
  +  *) EBCDIC: Fixed binary upload capability (plain and chunked) for
  +     all methods using the ap_*_client_block() functions, most notably
  +     POST and PUT. The functionality to switch input between protocol
  +     parts (chunks) and (possibly binary) data had been missing all
  +     the time, making chunked PUT impossible until now.
  +     [Martin Kraemer]
  +
     *) Fixed a recently introduced off-by-one-character bug in 
        mod_rewrite's expansion of expression back-references.
        [Cliff Woolley <[EMAIL PROTECTED]>] PR#4766 PR#5389
  
  
  
  1.282     +78 -23    apache-1.3/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/main/http_protocol.c,v
  retrieving revision 1.281
  retrieving revision 1.282
  diff -u -r1.281 -r1.282
  --- http_protocol.c   1999/12/01 20:45:41     1.281
  +++ http_protocol.c   1999/12/06 12:41:39     1.282
  @@ -81,6 +81,27 @@
             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*/
   
   static int parse_byterange(char *range, long clength, long *start, long *end)
   {
  @@ -217,8 +238,7 @@
        * set to ON (protocol strings MUST be converted)
        * and reset to original setting before returning
        */
  -    int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
  -    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
  +    PUSH_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client, 1);
   #endif /*CHARSET_EBCDIC*/
   
       if (!**r_range) {
  @@ -229,8 +249,7 @@
                   *tlength += 4 + strlen(r->boundary) + 4;
           }
   #ifdef CHARSET_EBCDIC
  -     if (!convert)
  -         ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
  +        POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
   #endif /*CHARSET_EBCDIC*/
           return 0;
       }
  @@ -238,8 +257,7 @@
       range = ap_getword(r->pool, r_range, ',');
       if (!parse_byterange(range, r->clength, &range_start, &range_end)) {
   #ifdef CHARSET_EBCDIC
  -     if (!convert)
  -         ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
  +        POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
   #endif /*CHARSET_EBCDIC*/
           /* Skip this one */
           return internal_byterange(realreq, tlength, r, r_range, offset,
  @@ -269,8 +287,7 @@
           *tlength += range_end - range_start + 1;
       }
   #ifdef CHARSET_EBCDIC
  -    if (!convert)
  -     ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
  +    POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
   #endif /*CHARSET_EBCDIC*/
       return 1;
   }
  @@ -685,14 +702,27 @@
       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;
   
       do {
           retval = ap_bgets(pos, n, in);     /* retval == -1 if error, 0 if 
EOF */
   
  -        if (retval <= 0)
  -            return ((retval < 0) && (total == 0)) ? -1 : total;
  +        if (retval <= 0) {
  +            total = ((retval < 0) && (total == 0)) ? -1 : total;
  +            break;
  +        }
   
           /* retval is the number of characters read, not including NUL      */
   
  @@ -717,7 +747,7 @@
               ++n;
           }
           else
  -            return total;       /* if not, input line exceeded buffer size */
  +            break;       /* if not, input line exceeded buffer size */
   
           /* Continue appending if line folding is desired and
            * the last line was not empty and we have room in the buffer and
  @@ -727,6 +757,11 @@
                     && (ap_blookc(&next, in) == 1)
                     && ((next == ' ') || (next == '\t')));
   
  +#ifdef CHARSET_EBCDIC
  +    /* restore ASCII->EBCDIC conversion state */
  +    POP_EBCDIC_INPUTCONVERSION_STATE(in);
  +#endif /*CHARSET_EBCDIC*/
  +
       return total;
   }
   
  @@ -1305,9 +1340,6 @@
   API_EXPORT(void) ap_basic_http_header(request_rec *r)
   {
       char *protocol;
  -#ifdef CHARSET_EBCDIC
  -    int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
  -#endif /*CHARSET_EBCDIC*/
   
       if (r->assbackwards)
           return;
  @@ -1329,7 +1361,7 @@
           protocol = 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 */
  @@ -1342,8 +1374,7 @@
       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*/
   }
   
  @@ -1550,9 +1581,6 @@
   {
       int i;
       const long int zero = 0L;
  -#ifdef CHARSET_EBCDIC
  -    int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
  -#endif /*CHARSET_EBCDIC*/
   
       if (r->assbackwards) {
           if (!r->main)
  @@ -1589,7 +1617,7 @@
       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);
  @@ -1644,8 +1672,7 @@
       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*/
   }
   
  @@ -1763,6 +1790,23 @@
           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;
   }
   
  @@ -1947,9 +1991,20 @@
       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;
  
  
  

Reply via email to