]> granicus.if.org Git - php/commitdiff
MFB: Fixed #45540 (stream_context_create creates bad http request)
authorArnaud Le Blanc <lbarnaud@php.net>
Thu, 14 May 2009 16:15:38 +0000 (16:15 +0000)
committerArnaud Le Blanc <lbarnaud@php.net>
Thu, 14 May 2009 16:15:38 +0000 (16:15 +0000)
ext/standard/http_fopen_wrapper.c

index e501c5887af89f93d003ad9c67cedfeefe6a2169..2d75f0ed522ce39d5a55c3a2edae2b6d5cfe5403 100644 (file)
 #define HTTP_HEADER_CONTENT_LENGTH     16
 #define HTTP_HEADER_TYPE                       32
 
-php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max, int header_init STREAMS_DC TSRMLS_DC) /* {{{ */
+#define HTTP_WRAPPER_HEADER_INIT    1
+#define HTTP_WRAPPER_REDIRECTED     2
+
+php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */
 {
        php_stream *stream = NULL;
        php_url *resource = NULL;
@@ -106,6 +109,8 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
        int protocol_version_len = 3; /* Default: "1.0" */
        struct timeval timeout;
        char *user_headers = NULL;
+       int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0);
+       int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0);
 
        tmp_line[0] = '\0';
 
@@ -251,10 +256,17 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
 
        if (context && php_stream_context_get_option(context, "http", "method", &tmpzval) == SUCCESS) {
                if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) {
-                       scratch_len = strlen(path) + 29 + Z_STRLEN_PP(tmpzval);
-                       scratch = emalloc(scratch_len);
-                       strlcpy(scratch, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) + 1);
-                       strcat(scratch, " ");
+                       /* As per the RFC, automatically redirected requests MUST NOT use other methods than
+                        * GET and HEAD unless it can be confirmed by the user */
+                       if (!redirected
+                               || (Z_STRLEN_PP(tmpzval) == 3 && memcmp("GET", Z_STRVAL_PP(tmpzval), 3) == 0)
+                               || (Z_STRLEN_PP(tmpzval) == 4 && memcmp("HEAD",Z_STRVAL_PP(tmpzval), 4) == 0)
+                       ) {
+                               scratch_len = strlen(path) + 29 + Z_STRLEN_PP(tmpzval);
+                               scratch = emalloc(scratch_len);
+                               strlcpy(scratch, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) + 1);
+                               strcat(scratch, " ");
+                       }
                }
        }
  
@@ -701,7 +713,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
                                CHECK_FOR_CNTRL_CHARS(resource->pass)
                                CHECK_FOR_CNTRL_CHARS(resource->path)
                        }
-                       stream = php_stream_url_wrap_http_ex(wrapper, new_path, mode, options, opened_path, context, --redirect_max, 0 STREAMS_CC TSRMLS_CC);
+                       stream = php_stream_url_wrap_http_ex(wrapper, new_path, mode, options, opened_path, context, --redirect_max, HTTP_WRAPPER_REDIRECTED STREAMS_CC TSRMLS_CC);
                } else {
                        php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed! %s", tmp_line);
                }
@@ -748,7 +760,7 @@ out:
 
 php_stream *php_stream_url_wrap_http(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */
 {
-       return php_stream_url_wrap_http_ex(wrapper, path, mode, options, opened_path, context, PHP_URL_REDIRECT_MAX, 1 STREAMS_CC TSRMLS_CC);
+       return php_stream_url_wrap_http_ex(wrapper, path, mode, options, opened_path, context, PHP_URL_REDIRECT_MAX, HTTP_WRAPPER_HEADER_INIT STREAMS_CC TSRMLS_CC);
 }
 /* }}} */