diff --git a/src/httpget.c b/src/httpget.c index 9aea70e..e504ec7 100644 --- a/src/httpget.c +++ b/src/httpget.c @@ -108,25 +108,10 @@ httpget(HTTPC *httpc) } } - /* chunked transfer encoding only for HTTP/1.1 clients */ - { - int use_chunked = 0; - if (!httpc->content_length_set) { - UCHAR *ver = http_get_env(httpc, "REQUEST_VERSION"); - if (ver && http_cmp(ver, "HTTP/1.1") == 0) { - rc = http_printf(httpc, "Transfer-Encoding: chunked\r\n"); - if (rc) goto die; - use_chunked = 1; - } - /* HTTP/1.0: no chunked, body delimited by Connection: close */ - } - - rc = http_printf(httpc, "\r\n"); - if (rc) goto die; - - /* enable chunk framing AFTER header-ending CRLF is sent */ - httpc->chunked = use_chunked; - } + /* end of headers — httpprtv auto-injects Transfer-Encoding: chunked + for HTTP/1.1 clients when Content-Length was not set */ + rc = http_printf(httpc, "\r\n"); + if (rc) goto die; /* indicate type of document being sent */ if (mime->binary) { diff --git a/src/httpprtv.c b/src/httpprtv.c index e7da54c..efd3710 100644 --- a/src/httpprtv.c +++ b/src/httpprtv.c @@ -18,28 +18,50 @@ httpprtv(HTTPC *httpc, const char *fmt, va_list args) rc = -1; } else { -#if 0 /* debugging */ - wtof("httpprtv:"); - for(pos=0; pos < len; pos+=80) { - int j = len - pos; - if (j > 80) j = 80; - wtof("%-*.*s", j, j, &buf[pos]); + /* auto-detect Content-Length header from any caller */ + if (len >= 15 && http_cmpn(buf, "Content-Length:", 15) == 0) + httpc->content_length_set = 1; + + /* auto-detect header terminator (blank line = "\r\n" only) + and inject Transfer-Encoding: chunked for HTTP/1.1 if needed */ + if (len == 2 && buf[0] == '\r' && buf[1] == '\n' + && httpc->resp > 0 && !httpc->rdw) { + httpc->rdw = 1; /* headers ended — don't re-trigger */ + + if (!httpc->content_length_set && !httpc->chunked) { + UCHAR *ver = http_get_env(httpc, "REQUEST_VERSION"); + if (ver && http_cmp(ver, "HTTP/1.1") == 0) { + /* inject Transfer-Encoding header before blank line */ + UCHAR te[] = "Transfer-Encoding: chunked\r\n"; + int te_len = sizeof(te) - 1; + http_etoa(te, te_len); + for (pos = 0; pos < te_len; pos += rc) { + rc = http_send(httpc, &te[pos], te_len - pos); + if (rc < 0) goto quit; + } + /* send the blank line (header terminator) */ + http_etoa(buf, len); + for (pos = 0; pos < len; pos += rc) { + rc = http_send(httpc, &buf[pos], len - pos); + if (rc < 0) goto quit; + } + /* enable chunk framing for subsequent body data */ + httpc->chunked = 1; + rc = 0; + goto quit; + } + } } -#endif + + /* normal path: convert EBCDIC → ASCII and send */ http_etoa(buf, len); for(pos=0; pos < len; pos+=rc) { rc = http_send(httpc, &buf[pos], len-pos); -#if 0 - wtof("http_send() rc=%d", rc); -#endif if (rc<0) goto quit; } rc = 0; } quit: -#if 0 - wtof("httpprtv() rc=%d", rc); -#endif return rc; } diff --git a/src/httprese.c b/src/httprese.c index c4981f2..d67741b 100644 --- a/src/httprese.c +++ b/src/httprese.c @@ -33,6 +33,7 @@ httprese(HTTPC *httpc) httpc->substate = 0; httpc->chunked = 0; httpc->content_length_set = 0; + httpc->rdw = 0; memset(httpc->buf, 0, CBUFSIZE); /* clear ACEE on UFS session between requests */