summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2011-01-28 10:33:47 +0000
committerDmitry Stogov <dmitry@php.net>2011-01-28 10:33:47 +0000
commit6464b4ef9faf573157ccaf9a2d014bf654700e03 (patch)
tree735352f42ea63aa30aa6f4cdf281d3a22207cdb8
parentb85380f7d02d811c67fc64eb67bdc3da1d095d9b (diff)
downloadphp-git-6464b4ef9faf573157ccaf9a2d014bf654700e03.tar.gz
Added ability to connect to HTTPS sites through proxy with basic authentication using stream_context/http/header/Proxy-Authorization
-rw-r--r--NEWS3
-rw-r--r--ext/standard/http_fopen_wrapper.c116
2 files changed, 111 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index 523ffa04b8..4f74455417 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 5.2.18
+- Added ability to connect to HTTPS sites through proxy with basic
+ authentication using stream_context/http/header/Proxy-Authorization (Dmitry)
+
- Fixed bug #53682 (Fix compile on the VAX). (Rasmus, jklos)
- Fixed bug #53568 (swapped memset arguments in struct initialization).
(crrodriguez at opensuse dot org)
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 6ba48bef9d..6d5f24a7ff 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -200,7 +200,70 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
smart_str_appends(&header, resource->host);
smart_str_appendc(&header, ':');
smart_str_append_unsigned(&header, resource->port);
- smart_str_appendl(&header, " HTTP/1.0\r\n\r\n", sizeof(" HTTP/1.0\r\n\r\n")-1);
+ smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1);
+
+ /* check if we have Proxy-Authorization header */
+ if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) {
+ char *s, *p;
+
+ if (Z_TYPE_PP(tmpzval) == IS_ARRAY) {
+ HashPosition pos;
+ zval **tmpheader = NULL;
+
+ for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos);
+ SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos);
+ zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos)) {
+ if (Z_TYPE_PP(tmpheader) == IS_STRING) {
+ s = Z_STRVAL_PP(tmpheader);
+ do {
+ while (*s == ' ' || *s == '\t') s++;
+ p = s;
+ while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++;
+ if (*p == ':') {
+ p++;
+ if (p - s == sizeof("Proxy-Authorization:") - 1 &&
+ zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1,
+ "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) {
+ while (*p != 0 && *p != '\r' && *p !='\n') p++;
+ smart_str_appendl(&header, s, p - s);
+ smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
+ goto finish;
+ } else {
+ while (*p != 0 && *p != '\r' && *p !='\n') p++;
+ }
+ }
+ s = p;
+ while (*s == '\r' || *s == '\n') s++;
+ } while (*s != 0);
+ }
+ }
+ } else if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
+ s = Z_STRVAL_PP(tmpzval);
+ do {
+ while (*s == ' ' || *s == '\t') s++;
+ p = s;
+ while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++;
+ if (*p == ':') {
+ p++;
+ if (p - s == sizeof("Proxy-Authorization:") - 1 &&
+ zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1,
+ "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) {
+ while (*p != 0 && *p != '\r' && *p !='\n') p++;
+ smart_str_appendl(&header, s, p - s);
+ smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
+ goto finish;
+ } else {
+ while (*p != 0 && *p != '\r' && *p !='\n') p++;
+ }
+ }
+ s = p;
+ while (*s == '\r' || *s == '\n') s++;
+ } while (*s != 0);
+ }
+ }
+finish:
+ smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
+
if (php_stream_write(stream, header.c, header.len) != header.len) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy");
php_stream_close(stream);
@@ -357,9 +420,11 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
tmp = php_trim(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), NULL, 0, NULL, 3 TSRMLS_CC);
}
if (tmp && strlen(tmp) > 0) {
+ char *s;
+
if (!header_init) { /* Remove post headers for redirects */
int l = strlen(tmp);
- char *s, *s2, *tmp_c = estrdup(tmp);
+ char *s2, *tmp_c = estrdup(tmp);
php_strtolower(tmp_c, l);
if ((s = strstr(tmp_c, "content-length:"))) {
@@ -380,6 +445,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
tmp[s - tmp_c] = '\0';
}
}
+
efree(tmp_c);
tmp_c = php_trim(tmp, strlen(tmp), NULL, 0, NULL, 3 TSRMLS_CC);
efree(tmp);
@@ -390,24 +456,58 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
/* Make lowercase for easy comparison against 'standard' headers */
php_strtolower(tmp, strlen(tmp));
- if (strstr(tmp, "user-agent:")) {
+ if ((s = strstr(tmp, "user-agent:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ *(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_USER_AGENT;
}
- if (strstr(tmp, "host:")) {
+ if ((s = strstr(tmp, "host:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ *(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_HOST;
}
- if (strstr(tmp, "from:")) {
+ if ((s = strstr(tmp, "from:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ *(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_FROM;
}
- if (strstr(tmp, "authorization:")) {
+ if ((s = strstr(tmp, "authorization:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ *(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_AUTH;
}
- if (strstr(tmp, "content-length:")) {
+ if ((s = strstr(tmp, "content-length:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ *(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_CONTENT_LENGTH;
}
- if (strstr(tmp, "content-type:")) {
+ if ((s = strstr(tmp, "content-type:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ *(s-1) == '\t' || *(s-1) == ' ')) {
have_header |= HTTP_HEADER_TYPE;
}
+ /* remove Proxy-Authorization header */
+ if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) &&
+ (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' ||
+ *(s-1) == '\t' || *(s-1) == ' ')) {
+ char *p = s + sizeof("proxy-authorization:") - 1;
+
+ while (s > tmp && (*(s-1) == ' ' || *(s-1) == '\t')) s--;
+ while (*p != 0 && *p != '\r' && *p != '\n') p++;
+ while (*p == '\r' || *p == '\n') p++;
+ if (*p == 0) {
+ if (s == tmp) {
+ efree(user_headers);
+ user_headers = NULL;
+ } else {
+ while (s > tmp && (*(s-1) == '\r' || *(s-1) == '\n')) s--;
+ user_headers[s - tmp] = 0;
+ }
+ } else {
+ memmove(user_headers + (s - tmp), user_headers + (p - tmp), strlen(p) + 1);
+ }
+ }
+
}
if (tmp) {
efree(tmp);