implement restrictions on TE
authorMichael Wallner <mike@php.net>
Thu, 5 Feb 2015 12:03:02 +0000 (13:03 +0100)
committerMichael Wallner <mike@php.net>
Thu, 5 Feb 2015 12:03:02 +0000 (13:03 +0100)
php_http_env_response.c
tests/envresponse017.phpt [new file with mode: 0644]

index 04c8a98..a4431b6 100644 (file)
@@ -883,6 +883,7 @@ typedef struct php_http_env_response_stream_ctx {
        long status_code;
 
        php_stream *stream;
+       php_http_message_t *request;
 
        unsigned started:1;
        unsigned finished:1;
@@ -905,6 +906,12 @@ static STATUS php_http_env_response_stream_init(php_http_env_response_t *r, void
        php_http_version_init(&ctx->version, 1, 1 TSRMLS_CC);
        ctx->status_code = 200;
        ctx->chunked = 1;
+       ctx->request = get_request(r->options TSRMLS_CC);
+
+       /* there are some limitations regarding TE:chunked, see https://tools.ietf.org/html/rfc7230#section-3.3.1 */
+       if (ctx->request && ctx->request->http.version.major == 1 && ctx->request->http.version.minor == 0) {
+               ctx->version.minor = 0;
+       }
 
        r->ctx = ctx;
 
@@ -950,14 +957,26 @@ static STATUS php_http_env_response_stream_start(php_http_env_response_stream_ct
        }
 
        php_stream_printf(ctx->stream TSRMLS_CC, "HTTP/%u.%u %ld %s" PHP_HTTP_CRLF, ctx->version.major, ctx->version.minor, ctx->status_code, php_http_env_get_response_status_for_code(ctx->status_code));
+
+       /* there are some limitations regarding TE:chunked, see https://tools.ietf.org/html/rfc7230#section-3.3.1 */
+       if (ctx->version.major == 1 && ctx->version.minor == 0) {
+               ctx->chunked = 0;
+       } else if (ctx->status_code == 204 || ctx->status_code/100 == 1) {
+               ctx->chunked = 0;
+       } else if (ctx->request && ctx->status_code/100 == 2 && !strcasecmp(ctx->request->http.info.request.method, "CONNECT")) {
+               ctx->chunked = 0;
+       }
+
        php_http_env_response_stream_header(ctx, &ctx->header TSRMLS_CC);
+
        /* enable chunked transfer encoding */
        if (ctx->chunked) {
-               php_stream_write_string(ctx->stream, "Transfer-Encoding: chunked" PHP_HTTP_CRLF PHP_HTTP_CRLF);
-       } else {
-               php_stream_write_string(ctx->stream, PHP_HTTP_CRLF);
+               php_stream_write_string(ctx->stream, "Transfer-Encoding: chunked" PHP_HTTP_CRLF);
        }
+       php_stream_write_string(ctx->stream, PHP_HTTP_CRLF);
+
        ctx->started = 1;
+
        return SUCCESS;
 }
 static long php_http_env_response_stream_get_status(php_http_env_response_t *r)
diff --git a/tests/envresponse017.phpt b/tests/envresponse017.phpt
new file mode 100644 (file)
index 0000000..ffa40cb
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+env response stream: no chunked transfer encoding for CONNECTs
+--SKIPIF--
+<?php 
+include "skipif.inc";
+?>
+--FILE--
+<?php 
+echo "Test\n";
+
+$req = new http\Env\Request;
+$req->setRequestMethod("CONNECT");
+$req->setRequestUrl(["host"=>"www.example.com", "port"=>80]);
+
+echo $req;
+
+$res = new http\Env\Response;
+$res->setEnvRequest($req);
+$res->send(STDOUT);
+
+?>
+===DONE===
+--EXPECTF--
+Test
+CONNECT www.example.com:80 HTTP/1.1
+HTTP/1.1 200 OK
+
+===DONE===