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
{
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) {
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);
else {
*tlength += range_end - range_start + 1;
}
+#ifdef CHARSET_EBCDIC
+ POP_EBCDIC_OUTPUTCONVERSION_STATE(r->connection->client);
+#endif /*CHARSET_EBCDIC*/
return 1;
}
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;
&& (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;
}
{
char *protocol;
char *date = NULL;
-#ifdef CHARSET_EBCDIC
- int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
-#endif /*CHARSET_EBCDIC*/
if (r->assbackwards)
return;
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 */
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*/
}
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)
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);
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*/
}
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.
*/
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*/
}
}
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;
}
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;