/** Send HTTP/S request to another host; Forward headers received (if QUIET variable is FALSE) and return content; Respect HTTP 30x redirects if last argument is TRUE @return mixed @param $_pattern string @param $_query string @param $_reqhdrs array @param $_follow boolean @public **/ public static function http($_pattern, $_query = '', $_reqhdrs = array(), $_follow = TRUE) { // Check if valid route pattern list($_method, $_route) = F3::checkRoute($_pattern); // Valid URI pattern $_url = parse_url($_route); if (!$_url['path']) { // Set to Web root $_url['path'] = '/'; } if ($_method != 'GET') { if ($_url['query']) { // Non-GET method; Query is distinct from URI $_query = $_url['query']; $_url['query'] = ''; } } else { if ($_query) { // GET method; Query is integral part of URI $_url['query'] = $_query; $_query = ''; } } // Set up host name and TCP port for socket connection if (preg_match('/https/', $_url['scheme'])) { if (!$_url['port']) { $_url['port'] = 443; } $_target = 'ssl://' . $_url['host'] . ':' . $_url['port']; } else { if (!$_url['port']) { $_url['port'] = 80; } $_target = $_url['host'] . ':' . $_url['port']; } $_socket = @fsockopen($_target, $_url['port'], $_errno, $_text); if (!$_socket) { // Can't establish connection trigger_error($_text); return FALSE; } // Send HTTP request fputs($_socket, $_method . ' ' . $_url['path'] . ($_url['query'] ? '?' . $_url['query'] : '') . ' ' . 'HTTP/1.0' . self::EOL . F3::HTTP_Host . ': ' . $_url['host'] . self::EOL . F3::HTTP_Agent . ': Mozilla/5.0 (' . 'compatible;' . F3::TEXT_Version . ')' . self::EOL . ($_reqhdrs ? implode(self::EOL, $_reqhdrs) . self::EOL : '') . ($_method != 'GET' ? 'Content-Type: ' . 'application/x-www-form-urlencoded' . self::EOL . 'Content-Length: ' . strlen($_query) . self::EOL : '') . F3::HTTP_AcceptEnc . ': deflate' . self::EOL . F3::HTTP_Connect . ': close' . self::EOL . self::EOL . $_query . self::EOL . self::EOL); $_found = FALSE; // Set connection timeout parameters stream_set_blocking($_socket, TRUE); stream_set_timeout($_socket, ini_get('default_socket_timeout')); $_info = stream_get_meta_data($_socket); // Get response while (!feof($_socket) && !$_info['timed_out']) { $_response .= fgets($_socket, 4096); // MDFK97 $_info = stream_get_meta_data($_socket); if (!$_found) { $_rcvhdrs = strstr($_response, self::EOL . self::EOL, TRUE); if ($_rcvhdrs) { $_found = TRUE; // Split content from HTTP response headers $_response = substr(strstr($_response, self::EOL . self::EOL), 4); } } } fclose($_socket); if ($_info['timed_out']) { trigger_error(self::TEXT_Timeout); return FALSE; } if ($_follow && preg_match('/HTTP\\/1\\.\\d\\s30\\d/', $_rcvhdrs)) { // Redirection preg_match('/' . F3::HTTP_Location . ':\\s(.+?)\\r\\n/', $_rcvhdrs, $_location); return self::http($_method . ' ' . $_location[1], $_query, $_reqhdrs); } if (PHP_SAPI != 'cli' && !headers_sent()) { // Forward HTTP response headers foreach (explode(self::EOL, $_rcvhdrs) as $_header) { F3::$global['HEADERS'][] = $_header; if (!F3::$global['QUIET'] && preg_match('/' . F3::HTTP_Content . '/', $_header)) { header($_header); } elseif (preg_match('/' . F3::HTTP_Encoding . '.+deflate/', $_header)) { $_response = gzuncompress($_response); } } } // Return content return $_response; }
/** Send HTTP/S request to another host; Forward headers received (if QUIET variable is FALSE) and return content; Respect HTTP 30x redirects if last argument is TRUE @return mixed @param $_pattern string @param $_query string @param $_reqhdrs array @param $_follow boolean @public **/ public static function http($_pattern, $_query = '', $_reqhdrs = array(), $_follow = TRUE) { // Check if valid route pattern list($_method, $_route) = F3::checkRoute($_pattern); // Content divider $_div = chr(0); // Determine if page is in cache $_hash = 'url.' . F3::hashCode($_pattern); $_cached = Cache::cached($_hash); if ($_cached) { // Retrieve from cache $_buffer = Cache::fetch($_hash); $_rcvhdrs = strstr($_buffer, $_div, TRUE); $_response = substr(strstr($_buffer, $_div), 1); // Find out if cache is stale $_expires = NULL; foreach (explode(self::EOL, $_rcvhdrs) as $_hdr) { if (preg_match('/^' . F3::HTTP_Expires . ':(.+)/', $_hdr, $_match)) { $_expires = strtotime($_match[1]); break; } } if (!is_null($_expires) && time() < $_expires) { // Cached page is still fresh foreach (explode(self::EOL, $_rcvhdrs) as $_hdr) { F3::$global['HEADERS'][] = $_hdr; if (preg_match('/' . F3::HTTP_Content . '/', $_hdr)) { // Forward HTTP header header($_hdr); } } return $_response; } } $_url = parse_url($_route); if (!$_url['path']) { // Set to Web root $_url['path'] = '/'; } if ($_method != 'GET') { if ($_url['query']) { // Non-GET method; Query is distinct from URI $_query = $_url['query']; $_url['query'] = ''; } } else { if ($_query) { // GET method; Query is integral part of URI $_url['query'] = $_query; $_query = ''; } } // Set up host name and TCP port for socket connection if (preg_match('/https/', $_url['scheme'])) { if (!$_url['port']) { $_url['port'] = 443; } $_target = 'ssl://' . $_url['host'] . ':' . $_url['port']; } else { if (!$_url['port']) { $_url['port'] = 80; } $_target = $_url['host'] . ':' . $_url['port']; } $_socket = @fsockopen($_target, $_url['port'], $_errno, $_text); if (!$_socket) { // Can't establish connection trigger_error($_text); return FALSE; } // Send HTTP request fputs($_socket, $_method . ' ' . $_url['path'] . ($_url['query'] ? '?' . $_url['query'] : '') . ' ' . 'HTTP/1.0' . self::EOL . F3::HTTP_Host . ': ' . $_url['host'] . self::EOL . F3::HTTP_Agent . ': Mozilla/5.0 (' . 'compatible;' . F3::TEXT_AppName . ' ' . F3::TEXT_Version . ')' . self::EOL . ($_reqhdrs ? implode(self::EOL, $_reqhdrs) . self::EOL : '') . ($_method != 'GET' ? 'Content-Type: ' . 'application/x-www-form-urlencoded' . self::EOL . 'Content-Length: ' . strlen($_query) . self::EOL : '') . F3::HTTP_AcceptEnc . ': gzip' . self::EOL . ($_cached ? F3::HTTP_Cache . ': max-age=86400' . self::EOL : '') . F3::HTTP_Connect . ': close' . self::EOL . self::EOL . $_query . self::EOL . self::EOL); $_found = FALSE; $_expires = FALSE; $_gzip = FALSE; // Set connection timeout parameters stream_set_blocking($_socket, TRUE); stream_set_timeout($_socket, ini_get('default_socket_timeout')); $_info = stream_get_meta_data($_socket); // Get headers and response while (!feof($_socket) && !$_info['timed_out']) { $_response .= fgets($_socket, 4096); // MDFK97 $_info = stream_get_meta_data($_socket); if (!$_found) { $_rcvhdrs = strstr($_response, self::EOL . self::EOL, TRUE); if ($_rcvhdrs) { $_found = TRUE; if (PHP_SAPI != 'cli' && !headers_sent()) { ob_start(); if ($_follow && preg_match('/HTTP\\/1\\.\\d\\s30\\d/', $_rcvhdrs)) { // Redirection preg_match('/' . F3::HTTP_Location . ':\\s*(.+?)/', $_rcvhdrs, $_loc); return self::http($_method . ' ' . $_loc[1], $_query, $_reqhdrs); } foreach (explode(self::EOL, $_rcvhdrs) as $_hdr) { F3::$global['HEADERS'][] = $_hdr; if (!F3::$global['QUIET'] && preg_match('/' . F3::HTTP_Content . '/', $_hdr)) { // Forward HTTP header header($_hdr); } elseif (preg_match('/^' . F3::HTTP_Encoding . ':\\s*.*gzip/', $_hdr)) { // Uncompress content $_gzip = TRUE; } elseif (preg_match('/^' . F3::HTTP_Expires . ':\\s*.+/', $_hdr)) { // Cache this page $_expires = TRUE; } } ob_end_flush(); if ($_flag) { Cache::store($_hash, $_rcvhdrs . $_div . $_response); } } // Split content from HTTP response headers $_response = substr(strstr($_response, self::EOL . self::EOL), 4); } } } fclose($_socket); if ($_info['timed_out']) { trigger_error(self::TEXT_Timeout); return FALSE; } if (PHP_SAPI != 'cli' && !headers_sent()) { if ($_gzip) { $_response = gzinflate(substr($_response, 10)); } if ($_expires) { Cache::store($_hash, $_rcvhdrs . $_div . $_response); } } // Return content return $_response; }