Loading README.txt +9 −0 Changes for README.txt: 9 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -59,6 +59,15 @@ Settings page is located at: and not queue up the request. Note that background callbacks will automatically be disabled if the site is in maintenance mode. For use with a hostname that is using a self-signed certificate, to avoid the certificate validation errors add the following to the site's settings.php file: // httprl. // Disable SSL cert validation. $conf['drupal_ssl_context_options'] = array( 'verify_peer' => FALSE, ); API OVERVIEW ------------ Loading examples/httprl.examples.php +27 −27 Changes for examples/httprl.examples.php: 27 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -12,10 +12,10 @@ Request http://drupal.org/. // Queue up the request. httprl_request('http://drupal.org/'); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading @@ -25,11 +25,11 @@ Request http://drupal.org/robots.txt and save it to tmp folder. // Queue up the request. httprl_request('http://drupal.org/robots.txt'); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Save file if we got a 200 back. if ($response['http://drupal.org/robots.txt']->code == 200) { file_put_contents('/tmp/robots.txt', $response['http://drupal.org/robots.txt']->data); if ($request['http://drupal.org/robots.txt']->code == 200) { file_put_contents('/tmp/robots.txt', $request['http://drupal.org/robots.txt']->data); } ?> Loading @@ -51,17 +51,17 @@ $url_node = httprl_build_url_self('node'); httprl_request($url_front, $options); httprl_request($url_node, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> **Non Blocking HTTP Operations** Request 10 URLs in a non blocking manner on this server. Checkout watchdog as this should generate 10 404s and the $response object won't contain much info. this should generate 10 404s and the $request object won't contain much info. <?php // Set the blocking mode. Loading @@ -80,10 +80,10 @@ for ($i=1; $i <= $max; $i++) { httprl_request($url, $options); } // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading @@ -110,10 +110,10 @@ for ($i=1; $i <= $max; $i++) { // Queue up the requests. httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -143,10 +143,10 @@ for ($i=1; $i <= $max; $i++) { // Queue up the requests. httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -180,10 +180,10 @@ for ($i=1; $i <= $max; $i++) { // Queue up the requests. httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -214,7 +214,7 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo returned value from function callback. echo $x; Loading Loading @@ -247,7 +247,7 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo returned value from function callback. echo $x; Loading Loading @@ -285,7 +285,7 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo what was returned and printed from function callback. echo $x . "<br />\n"; Loading Loading @@ -318,10 +318,10 @@ $options = array( httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $requests = httprl_send_request(); // Print what was done. echo httprl_pr($response); echo httprl_pr($requests); function need_two_good_results($id, &$responses) { static $counter = 0; Loading Loading @@ -380,9 +380,9 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo what was returned. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -425,17 +425,17 @@ $options = array( httprl_request($urls, $options); // Execute request. echo round(timer_read('page')/1000, 3) . " - Time taken to get requests ready.<br> \n"; $response = httprl_send_request(); echo strtoupper(var_export($response, TRUE)) . " - Output from first httprl_send_request() call<br> \n"; $request = httprl_send_request(); echo strtoupper(var_export($request, TRUE)) . " - Output from first httprl_send_request() call<br> \n"; echo round(timer_read('page')/1000, 3) . " - Time taken to send out all fwrites().<br> \n"; sleep(2); echo round(timer_read('page')/1000, 3) . " - Time taken for sleep(2).<br> \n"; $response = httprl_send_request(); $request = httprl_send_request(); echo round(timer_read('page')/1000, 3) . " - Time taken for all freads().<br> \n"; echo "Output from second httprl_send_request() below:<br> \n<br> \n"; echo httprl_pr($response); echo httprl_pr($request); ?> Loading httprl.async.inc +5 −0 Changes for httprl.async.inc: 5 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ function httprl_async_page() { } } // If on 64bit system give php 3 GB of ram. if (PHP_INT_SIZE > 4) { ini_set('memory_limit', httprl_variable_get('httprl_async_mem_limit', HTTPRL_ASYNC_MEM_LIMIT)); } // Run the function. if (!empty($_POST['function'])) { $data = httprl_run_function($_POST['function'], $args); Loading httprl.module +148 −33 Changes for httprl.module: 148 added lines, 33 removed lines. Original line number Diff line number Diff line Loading @@ -147,6 +147,16 @@ define('HTTPRL_NON_BLOCKING_FCLOSE_DELAY', 0); */ define('HTTPRL_SERVER_PORT', ''); /** * Just for loopback 127.0.0.1; ignore SSL errors allowing the connection. */ define('HTTPRL_LOOPBACK_IGNORE_SSL_ERRORS', TRUE); /** * If on 64bit system give php 3 GB of ram for async callbacks. */ define('HTTPRL_ASYNC_MEM_LIMIT', '3G'); /** * Implements hook_url_inbound_alter(). */ Loading Loading @@ -259,7 +269,7 @@ function httprl_override_core($url, $options = array()) { // Execute request. $response = httprl_send_request(); // Send back results. return is_array($response) && is_string($url) && array_key_exists($url, $response) ? $response[$url] : is_array($response) ? array_pop($response) : $response; return (is_array($response) && is_string($url) && array_key_exists($url, $response)) ? $response[$url] : (is_array($response) ? array_pop($response) : $response); } /** Loading Loading @@ -537,6 +547,7 @@ function httprl_set_default_options(array &$options) { 'chunk_size_write' => 1024, 'async_connect' => TRUE, 'ping_db' => 20, 'ignore_empty_chunk' => FALSE, 'url_encoding' => array(), ); Loading @@ -556,6 +567,12 @@ function httprl_set_default_options(array &$options) { 'User-Agent' => 'Drupal (+http://drupal.org/)', 'Connection' => 'close', ); if (isset($options['headers']['User-Agent']) && $options['headers']['User-Agent'] === FALSE) { unset($options['headers']['User-Agent']); } if (isset($options['headers']['Connection']) && $options['headers']['Connection'] === FALSE) { unset($options['headers']['Connection']); } // Defaults for url encoding the url. // Use %20 for spaces in the path and in the query string. Loading @@ -571,6 +588,9 @@ function httprl_set_default_options(array &$options) { if (!isset($options['headers']['Referer']) && !empty($options['referrer'])) { if (function_exists('request_uri')) { $options['headers']['Referer'] = $base_root . request_uri(); if (strpos($options['headers']['Referer'], 'httprl_async_function_callback') === TRUE) { $options['headers']['Referer'] = $_SERVER['HTTP_REFERER']; } } } Loading Loading @@ -775,19 +795,11 @@ function httprl_handle_data(&$options) { $options['data'] = $data_stream; } // No files passed in, url-encode the data. elseif (empty($options['data']['files']) || !is_array($options['data']['files'])) { $options['data'] = http_build_query($options['data'], '', '&'); // Set the Content-Type to application/x-www-form-urlencoded if the data // is not empty, the Content-Type is not set, and the method is POST or // PUT. if (!empty($options['data']) && !isset($options['headers']['Content-Type']) && ($options['method'] == 'POST' || $options['method'] == 'PUT')) { $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; } } else { elseif (!empty($options['data']['file']) || !empty($options['data']['files'])) { $data_stream = ''; $data_array = $options['data']; // Add files to the request. if (isset($options['data']['files'])) { foreach ($options['data']['files'] as $field_name => $info) { $multi_field = '[]'; // Convert $info into an array if it's a string. Loading Loading @@ -816,8 +828,26 @@ function httprl_handle_data(&$options) { } } // Remove files from the data array as they have already been added. $data_array = $options['data']; unset($data_array['files']); } elseif (isset($options['data']['file'])) { $fullpath = $options['data']['file']; // Strip '@' from the start of the path (cURL requirement). if (substr($fullpath, 0, 1) == "@") { $fullpath = substr($fullpath, 1); } $filename = basename($fullpath); // TODO: mime detection. $mimetype = 'application/octet-stream'; // Build the data-stream for this file. $data_stream .= '--' . HTTPRL_MULTIPART_BOUNDARY . "\r\n"; $data_stream .= 'Content-Disposition: form-data; name="file"; filename="' . $filename . "\"\r\n"; $data_stream .= 'Content-Transfer-Encoding: binary' . "\r\n"; $data_stream .= 'Content-Type: ' . $mimetype . "\r\n\r\n"; $data_stream .= file_get_contents($fullpath) . "\r\n"; unset($data_array['file']); } // Add fields to the request too: $_POST['foo'] = 'bar'. httprl_multipart_encoder($data_stream, $data_array); Loading @@ -831,6 +861,17 @@ function httprl_handle_data(&$options) { $options['headers']['Content-Type'] = 'multipart/form-data; boundary=' . HTTPRL_MULTIPART_BOUNDARY; } } // No files passed in, url-encode the data. else { $options['data'] = http_build_query($options['data'], '', '&'); // Set the Content-Type to application/x-www-form-urlencoded if the data // is not empty, the Content-Type is not set, and the method is POST or // PUT. if (!empty($options['data']) && !isset($options['headers']['Content-Type']) && ($options['method'] == 'POST' || $options['method'] == 'PUT')) { $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; } } } // Only add Content-Length if we actually have any content or if it is a POST Loading Loading @@ -943,7 +984,7 @@ function httprl_stream_connection_error_formatter($errno, $errstr, &$result) { require_once DRUPAL_ROOT . '/includes/unicode.inc'; } else { require_once './includes/unicode.inc'; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/unicode.inc'; } // Convert error message to utf-8. Using ISO-8859-1 (Latin-1) as source Loading Loading @@ -1013,6 +1054,14 @@ function httprl_establish_stream_connection(&$result) { $timeout += $result->options['connect_timeout']; } // Check for timeout here in the connection loop. $now_time = microtime(TRUE); $running_time = $now_time - $start_time; if ($running_time > $timeout) { break; } ini_set('default_socket_timeout', $timeout); // Open the connection. if (empty($result->options['context'])) { $result->fp = @stream_socket_client($result->socket, $errno, $errstr, $timeout, $result->flags); Loading Loading @@ -1143,6 +1192,10 @@ function httprl_establish_stream_connection(&$result) { * - ping_db: After X amount of time, ping the DB with a simple query in order * to keep the connection alive. Default is every 20 seconds. Set to 0 to * disable. * - ignore_empty_chunk: an empty chunk returned from a stream will: * default FALSE - make the connection not 'alive' and stop reading; * TRUE - not stop a stream from being 'alive' and will continue to read * until EOF or timeout. * * @return array * Array where key is the URL and the value is the return value from Loading Loading @@ -1299,7 +1352,7 @@ function httprl_send_request($results = NULL) { continue; } if (!empty($result->cached)) { if (!empty($result->cached->url)) { // Used the cached data. $output[$result->cached->url] = $result->cached; unset($responses[$id]); Loading Loading @@ -1632,8 +1685,13 @@ function httprl_send_request($results = NULL) { // Get stream data. $info = stream_get_meta_data($r); $alive = !$info['eof'] && !feof($r) && !$info['timed_out'] && strlen($chunk); if (!$alive && $responses[$id]->status !== 'Request sent, waiting for response.') { $alive = !$info['eof'] && !feof($r) && !$info['timed_out']; // Determine if an empty chunk of data means the connection should // stop reading even though EOF or timeout has not occurred. if ($alive && !$responses[$id]->options['ignore_empty_chunk'] && !strlen($chunk)) { $alive = FALSE; } if (!$alive) { if ($responses[$id]->status == 'Connecting.') { $responses[$id]->error = $t('Connection refused by destination. TCP.'); $responses[$id]->code = HTTPRL_CONNECTION_REFUSED; Loading Loading @@ -1902,8 +1960,8 @@ function httprl_parse_data(&$result) { $original_location = @parse_url($result->url); // Assume request is to self if none of this was setup correctly. $location['scheme'] = !empty($location['scheme']) ? $location['scheme'] : $original_location['scheme']; $location['host'] = !empty($location['host']) ? $location['host'] : (!empty($original_location['host']) ? $original_location['host'] : $hostname); $location['port'] = !empty($location['port']) ? $location['port'] : (!empty($original_location['port']) ? $original_location['port'] : ''); $location['host'] = !empty($location['host']) ? $location['host'] : ((!empty($original_location['host']) ? $original_location['host'] : $hostname)); $location['port'] = !empty($location['port']) ? $location['port'] : ((!empty($original_location['port']) ? $original_location['port'] : '')); $location = httprl_glue_url($location); } else { Loading @@ -1923,8 +1981,30 @@ function httprl_parse_data(&$result) { $result->error = $t('Maximum allowed redirects exhausted.'); } else { // Prepare the received cookie values from the previous request and pass // them on to the next. $cookie_string = ''; $parsed_location = parse_url($location); if(isset($result->cookies)) { foreach ($result->cookies as $cookie) { // Only add the cookie values if the cookie domain matches. $cookie_domain = ltrim($cookie['domain'], '.'); if (strpos($parsed_location['host'], $cookie_domain) !== FALSE) { if (!empty($cookie_string)) { $cookie_string .= ';'; } $cookie_string .= $cookie['name'] . '=' . $cookie['value']; } } // If the cookie string is changed and thus not empty we want to set // it in the options array. if (!empty($cookie_string)) { $result->options['headers']['Cookie'] = $cookie_string; } } // Redirect to the new location. // TODO: Send cookies in the redirect request if domain/path match. $result->options['max_redirects']--; if (isset($result->options['headers']['Referer'])) { $result->options['headers']['Referer'] = $result->url; Loading Loading @@ -2022,6 +2102,7 @@ function httprl_post_processing($id, &$responses, &$output, $time_left = NULL) { } } @fclose($result->fp); unset($result->fp); } // Set timeout. Loading Loading @@ -2303,7 +2384,18 @@ function httprl_queue_background_callback(&$args, &$result = NULL) { ), 'blocking' => $mode, 'method' => 'POST', 'referrer' => 'TRUE', ); if (empty($callback_options['context']) && httprl_variable_get('httprl_loopback_ignore_ssl_errors', HTTPRL_LOOPBACK_IGNORE_SSL_ERRORS)) { // Set context for loopback 127.0.0.1 to ignore any SSL issues. $drupal_ssl_context_options = array( 'verify_peer' => FALSE, 'verify_peer_name' => FALSE, 'allow_self_signed' => TRUE, ); $options['context'] = stream_context_create(['ssl' => $drupal_ssl_context_options]); } if (isset($callback_options['printed'])) { $options['internal_states']['background_function_printed'] = &$callback_options['printed']; } Loading Loading @@ -2766,26 +2858,29 @@ function httprl_lock_release($name) { * @return mixed * $data */ function httprl_print_empty(&$data, $level = 0) { function httprl_print_empty(&$data, $level = 0, $output_plain_text) { $level++; if ($level < 5) { if (is_object($data)) { $new_object = new stdClass(); $new_object->__original_class_name__ = get_class($data); foreach ($data as $key => $values) { $new_object->{$key} = httprl_print_empty($values, $level); $new_object->{$key} = httprl_print_empty($values, $level, $output_plain_text); } $data = $new_object; } elseif (is_array($data)) { foreach ($data as &$values) { $values = httprl_print_empty($values, $level); $values = httprl_print_empty($values, $level, $output_plain_text); } } elseif (is_bool($data) || strlen((string) $data) == 0) { $data = strtoupper(var_export($data, TRUE)); } elseif (is_string($data) && strlen($data) > HTTPRL_PR_MAX_STRING_LENGTH) { elseif (!$output_plain_text && is_string($data) && strlen($data) > HTTPRL_PR_MAX_STRING_LENGTH ) { // Do not try to print a string longer than 256KB. // Some browsers have issues with very long documents. $data = substr($data, 0, HTTPRL_PR_MAX_STRING_LENGTH); Loading Loading @@ -2815,7 +2910,7 @@ function httprl_pr($input) { $input = func_get_args(); // If bool or strlen = 0 use var_export on that variable. $data = httprl_print_empty($input); $data = httprl_print_empty($input, 0, $output_plain_text); // Merge into base array if only one argument passed in. if (count($data) == 1) { Loading Loading @@ -3596,8 +3691,8 @@ function httprl_call_user_func_array_cache($callback, array $param_arr = array() else { $cid = __FUNCTION__ . ':' . drupal_hash_base64(serialize(array($callback, $param_arr))); } $cache = cache_get($cid, $options['bin']); // Don't use the cache if it's not there or the cached item is older than // the max cache lifetime. if (empty($options['return_null_cache_miss']) && (!isset($cache->data) || $cache->created < REQUEST_TIME - $options['cache_lifetime_max'])) { Loading Loading @@ -3633,13 +3728,24 @@ function httprl_call_user_func_array_cache($callback, array $param_arr = array() && lock_may_be_available($cid . ':run_function') && httprl_acquire_headless_lock($cid, $options['lock_timeout']) ) { // Set max to zero so this gets regenerated in the background. // Also do not skip on a cache miss. $options['cache_lifetime_max'] = 0; $options['return_null_cache_miss'] = FALSE; // Get all function arguments. $args = array($callback, $param_arr, $options); // Call this function again in another process with max lifetime set to // zero. if (!httprl_is_background_callback_capable()) { // Call this function again in a shutdown function. _httprl_run_functions_once_on_shutdown_array_cache($args); } else { // Call this function again in another process. httprl_call_user_func_array_async('httprl_call_user_func_array_cache', $args); } } } return isset($cache->data) ? $cache->data : NULL; } Loading @@ -3662,8 +3768,9 @@ function _httprl_run_functions_once_on_shutdown_array_cache($args = array()) { unset($args); $will_run = array(); $already_ran = array(); foreach ($run_list as $args) { foreach ($run_list as $key => $args) { if (empty($args)) { unset($run_list[$key]); continue; } if (is_string($args[0])) { Loading @@ -3678,8 +3785,10 @@ function _httprl_run_functions_once_on_shutdown_array_cache($args = array()) { } } if (!empty($will_run)) { // Last chance for async call; odds are this will be a sync call if here. httprl_call_user_func_array_async('_httprl_run_cache_functions', array($will_run)); } unset($run_list[$key]); } } Loading @@ -3690,11 +3799,17 @@ function _httprl_run_functions_once_on_shutdown_array_cache($args = array()) { * The callable to be called. */ function _httprl_run_cache_functions($functions_to_cache) { // Cut connection to browser. @ob_end_flush(); @ob_flush(); @flush(); sleep(1); if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } foreach ($functions_to_cache as $args) { // Set max to zero so this gets regenerated in the background. // Also do not skip on a cache miss. $args[2]['cache_lifetime_max'] = 0; $args[2]['return_null_cache_miss'] = FALSE; call_user_func_array('httprl_call_user_func_array_cache', $args); } } Loading Loading
README.txt +9 −0 Changes for README.txt: 9 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -59,6 +59,15 @@ Settings page is located at: and not queue up the request. Note that background callbacks will automatically be disabled if the site is in maintenance mode. For use with a hostname that is using a self-signed certificate, to avoid the certificate validation errors add the following to the site's settings.php file: // httprl. // Disable SSL cert validation. $conf['drupal_ssl_context_options'] = array( 'verify_peer' => FALSE, ); API OVERVIEW ------------ Loading
examples/httprl.examples.php +27 −27 Changes for examples/httprl.examples.php: 27 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -12,10 +12,10 @@ Request http://drupal.org/. // Queue up the request. httprl_request('http://drupal.org/'); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading @@ -25,11 +25,11 @@ Request http://drupal.org/robots.txt and save it to tmp folder. // Queue up the request. httprl_request('http://drupal.org/robots.txt'); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Save file if we got a 200 back. if ($response['http://drupal.org/robots.txt']->code == 200) { file_put_contents('/tmp/robots.txt', $response['http://drupal.org/robots.txt']->data); if ($request['http://drupal.org/robots.txt']->code == 200) { file_put_contents('/tmp/robots.txt', $request['http://drupal.org/robots.txt']->data); } ?> Loading @@ -51,17 +51,17 @@ $url_node = httprl_build_url_self('node'); httprl_request($url_front, $options); httprl_request($url_node, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> **Non Blocking HTTP Operations** Request 10 URLs in a non blocking manner on this server. Checkout watchdog as this should generate 10 404s and the $response object won't contain much info. this should generate 10 404s and the $request object won't contain much info. <?php // Set the blocking mode. Loading @@ -80,10 +80,10 @@ for ($i=1; $i <= $max; $i++) { httprl_request($url, $options); } // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading @@ -110,10 +110,10 @@ for ($i=1; $i <= $max; $i++) { // Queue up the requests. httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -143,10 +143,10 @@ for ($i=1; $i <= $max; $i++) { // Queue up the requests. httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -180,10 +180,10 @@ for ($i=1; $i <= $max; $i++) { // Queue up the requests. httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $request = httprl_send_request(); // Echo out the results. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -214,7 +214,7 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo returned value from function callback. echo $x; Loading Loading @@ -247,7 +247,7 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo returned value from function callback. echo $x; Loading Loading @@ -285,7 +285,7 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo what was returned and printed from function callback. echo $x . "<br />\n"; Loading Loading @@ -318,10 +318,10 @@ $options = array( httprl_request($urls, $options); // Execute requests. $response = httprl_send_request(); $requests = httprl_send_request(); // Print what was done. echo httprl_pr($response); echo httprl_pr($requests); function need_two_good_results($id, &$responses) { static $counter = 0; Loading Loading @@ -380,9 +380,9 @@ $url_front = httprl_build_url_self(); // Queue up the request. httprl_request($url_front, $options); // Execute request. $response = httprl_send_request(); $request = httprl_send_request(); // Echo what was returned. echo httprl_pr($response); echo httprl_pr($request); ?> Loading Loading @@ -425,17 +425,17 @@ $options = array( httprl_request($urls, $options); // Execute request. echo round(timer_read('page')/1000, 3) . " - Time taken to get requests ready.<br> \n"; $response = httprl_send_request(); echo strtoupper(var_export($response, TRUE)) . " - Output from first httprl_send_request() call<br> \n"; $request = httprl_send_request(); echo strtoupper(var_export($request, TRUE)) . " - Output from first httprl_send_request() call<br> \n"; echo round(timer_read('page')/1000, 3) . " - Time taken to send out all fwrites().<br> \n"; sleep(2); echo round(timer_read('page')/1000, 3) . " - Time taken for sleep(2).<br> \n"; $response = httprl_send_request(); $request = httprl_send_request(); echo round(timer_read('page')/1000, 3) . " - Time taken for all freads().<br> \n"; echo "Output from second httprl_send_request() below:<br> \n<br> \n"; echo httprl_pr($response); echo httprl_pr($request); ?> Loading
httprl.async.inc +5 −0 Changes for httprl.async.inc: 5 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ function httprl_async_page() { } } // If on 64bit system give php 3 GB of ram. if (PHP_INT_SIZE > 4) { ini_set('memory_limit', httprl_variable_get('httprl_async_mem_limit', HTTPRL_ASYNC_MEM_LIMIT)); } // Run the function. if (!empty($_POST['function'])) { $data = httprl_run_function($_POST['function'], $args); Loading
httprl.module +148 −33 Changes for httprl.module: 148 added lines, 33 removed lines. Original line number Diff line number Diff line Loading @@ -147,6 +147,16 @@ define('HTTPRL_NON_BLOCKING_FCLOSE_DELAY', 0); */ define('HTTPRL_SERVER_PORT', ''); /** * Just for loopback 127.0.0.1; ignore SSL errors allowing the connection. */ define('HTTPRL_LOOPBACK_IGNORE_SSL_ERRORS', TRUE); /** * If on 64bit system give php 3 GB of ram for async callbacks. */ define('HTTPRL_ASYNC_MEM_LIMIT', '3G'); /** * Implements hook_url_inbound_alter(). */ Loading Loading @@ -259,7 +269,7 @@ function httprl_override_core($url, $options = array()) { // Execute request. $response = httprl_send_request(); // Send back results. return is_array($response) && is_string($url) && array_key_exists($url, $response) ? $response[$url] : is_array($response) ? array_pop($response) : $response; return (is_array($response) && is_string($url) && array_key_exists($url, $response)) ? $response[$url] : (is_array($response) ? array_pop($response) : $response); } /** Loading Loading @@ -537,6 +547,7 @@ function httprl_set_default_options(array &$options) { 'chunk_size_write' => 1024, 'async_connect' => TRUE, 'ping_db' => 20, 'ignore_empty_chunk' => FALSE, 'url_encoding' => array(), ); Loading @@ -556,6 +567,12 @@ function httprl_set_default_options(array &$options) { 'User-Agent' => 'Drupal (+http://drupal.org/)', 'Connection' => 'close', ); if (isset($options['headers']['User-Agent']) && $options['headers']['User-Agent'] === FALSE) { unset($options['headers']['User-Agent']); } if (isset($options['headers']['Connection']) && $options['headers']['Connection'] === FALSE) { unset($options['headers']['Connection']); } // Defaults for url encoding the url. // Use %20 for spaces in the path and in the query string. Loading @@ -571,6 +588,9 @@ function httprl_set_default_options(array &$options) { if (!isset($options['headers']['Referer']) && !empty($options['referrer'])) { if (function_exists('request_uri')) { $options['headers']['Referer'] = $base_root . request_uri(); if (strpos($options['headers']['Referer'], 'httprl_async_function_callback') === TRUE) { $options['headers']['Referer'] = $_SERVER['HTTP_REFERER']; } } } Loading Loading @@ -775,19 +795,11 @@ function httprl_handle_data(&$options) { $options['data'] = $data_stream; } // No files passed in, url-encode the data. elseif (empty($options['data']['files']) || !is_array($options['data']['files'])) { $options['data'] = http_build_query($options['data'], '', '&'); // Set the Content-Type to application/x-www-form-urlencoded if the data // is not empty, the Content-Type is not set, and the method is POST or // PUT. if (!empty($options['data']) && !isset($options['headers']['Content-Type']) && ($options['method'] == 'POST' || $options['method'] == 'PUT')) { $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; } } else { elseif (!empty($options['data']['file']) || !empty($options['data']['files'])) { $data_stream = ''; $data_array = $options['data']; // Add files to the request. if (isset($options['data']['files'])) { foreach ($options['data']['files'] as $field_name => $info) { $multi_field = '[]'; // Convert $info into an array if it's a string. Loading Loading @@ -816,8 +828,26 @@ function httprl_handle_data(&$options) { } } // Remove files from the data array as they have already been added. $data_array = $options['data']; unset($data_array['files']); } elseif (isset($options['data']['file'])) { $fullpath = $options['data']['file']; // Strip '@' from the start of the path (cURL requirement). if (substr($fullpath, 0, 1) == "@") { $fullpath = substr($fullpath, 1); } $filename = basename($fullpath); // TODO: mime detection. $mimetype = 'application/octet-stream'; // Build the data-stream for this file. $data_stream .= '--' . HTTPRL_MULTIPART_BOUNDARY . "\r\n"; $data_stream .= 'Content-Disposition: form-data; name="file"; filename="' . $filename . "\"\r\n"; $data_stream .= 'Content-Transfer-Encoding: binary' . "\r\n"; $data_stream .= 'Content-Type: ' . $mimetype . "\r\n\r\n"; $data_stream .= file_get_contents($fullpath) . "\r\n"; unset($data_array['file']); } // Add fields to the request too: $_POST['foo'] = 'bar'. httprl_multipart_encoder($data_stream, $data_array); Loading @@ -831,6 +861,17 @@ function httprl_handle_data(&$options) { $options['headers']['Content-Type'] = 'multipart/form-data; boundary=' . HTTPRL_MULTIPART_BOUNDARY; } } // No files passed in, url-encode the data. else { $options['data'] = http_build_query($options['data'], '', '&'); // Set the Content-Type to application/x-www-form-urlencoded if the data // is not empty, the Content-Type is not set, and the method is POST or // PUT. if (!empty($options['data']) && !isset($options['headers']['Content-Type']) && ($options['method'] == 'POST' || $options['method'] == 'PUT')) { $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded'; } } } // Only add Content-Length if we actually have any content or if it is a POST Loading Loading @@ -943,7 +984,7 @@ function httprl_stream_connection_error_formatter($errno, $errstr, &$result) { require_once DRUPAL_ROOT . '/includes/unicode.inc'; } else { require_once './includes/unicode.inc'; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/unicode.inc'; } // Convert error message to utf-8. Using ISO-8859-1 (Latin-1) as source Loading Loading @@ -1013,6 +1054,14 @@ function httprl_establish_stream_connection(&$result) { $timeout += $result->options['connect_timeout']; } // Check for timeout here in the connection loop. $now_time = microtime(TRUE); $running_time = $now_time - $start_time; if ($running_time > $timeout) { break; } ini_set('default_socket_timeout', $timeout); // Open the connection. if (empty($result->options['context'])) { $result->fp = @stream_socket_client($result->socket, $errno, $errstr, $timeout, $result->flags); Loading Loading @@ -1143,6 +1192,10 @@ function httprl_establish_stream_connection(&$result) { * - ping_db: After X amount of time, ping the DB with a simple query in order * to keep the connection alive. Default is every 20 seconds. Set to 0 to * disable. * - ignore_empty_chunk: an empty chunk returned from a stream will: * default FALSE - make the connection not 'alive' and stop reading; * TRUE - not stop a stream from being 'alive' and will continue to read * until EOF or timeout. * * @return array * Array where key is the URL and the value is the return value from Loading Loading @@ -1299,7 +1352,7 @@ function httprl_send_request($results = NULL) { continue; } if (!empty($result->cached)) { if (!empty($result->cached->url)) { // Used the cached data. $output[$result->cached->url] = $result->cached; unset($responses[$id]); Loading Loading @@ -1632,8 +1685,13 @@ function httprl_send_request($results = NULL) { // Get stream data. $info = stream_get_meta_data($r); $alive = !$info['eof'] && !feof($r) && !$info['timed_out'] && strlen($chunk); if (!$alive && $responses[$id]->status !== 'Request sent, waiting for response.') { $alive = !$info['eof'] && !feof($r) && !$info['timed_out']; // Determine if an empty chunk of data means the connection should // stop reading even though EOF or timeout has not occurred. if ($alive && !$responses[$id]->options['ignore_empty_chunk'] && !strlen($chunk)) { $alive = FALSE; } if (!$alive) { if ($responses[$id]->status == 'Connecting.') { $responses[$id]->error = $t('Connection refused by destination. TCP.'); $responses[$id]->code = HTTPRL_CONNECTION_REFUSED; Loading Loading @@ -1902,8 +1960,8 @@ function httprl_parse_data(&$result) { $original_location = @parse_url($result->url); // Assume request is to self if none of this was setup correctly. $location['scheme'] = !empty($location['scheme']) ? $location['scheme'] : $original_location['scheme']; $location['host'] = !empty($location['host']) ? $location['host'] : (!empty($original_location['host']) ? $original_location['host'] : $hostname); $location['port'] = !empty($location['port']) ? $location['port'] : (!empty($original_location['port']) ? $original_location['port'] : ''); $location['host'] = !empty($location['host']) ? $location['host'] : ((!empty($original_location['host']) ? $original_location['host'] : $hostname)); $location['port'] = !empty($location['port']) ? $location['port'] : ((!empty($original_location['port']) ? $original_location['port'] : '')); $location = httprl_glue_url($location); } else { Loading @@ -1923,8 +1981,30 @@ function httprl_parse_data(&$result) { $result->error = $t('Maximum allowed redirects exhausted.'); } else { // Prepare the received cookie values from the previous request and pass // them on to the next. $cookie_string = ''; $parsed_location = parse_url($location); if(isset($result->cookies)) { foreach ($result->cookies as $cookie) { // Only add the cookie values if the cookie domain matches. $cookie_domain = ltrim($cookie['domain'], '.'); if (strpos($parsed_location['host'], $cookie_domain) !== FALSE) { if (!empty($cookie_string)) { $cookie_string .= ';'; } $cookie_string .= $cookie['name'] . '=' . $cookie['value']; } } // If the cookie string is changed and thus not empty we want to set // it in the options array. if (!empty($cookie_string)) { $result->options['headers']['Cookie'] = $cookie_string; } } // Redirect to the new location. // TODO: Send cookies in the redirect request if domain/path match. $result->options['max_redirects']--; if (isset($result->options['headers']['Referer'])) { $result->options['headers']['Referer'] = $result->url; Loading Loading @@ -2022,6 +2102,7 @@ function httprl_post_processing($id, &$responses, &$output, $time_left = NULL) { } } @fclose($result->fp); unset($result->fp); } // Set timeout. Loading Loading @@ -2303,7 +2384,18 @@ function httprl_queue_background_callback(&$args, &$result = NULL) { ), 'blocking' => $mode, 'method' => 'POST', 'referrer' => 'TRUE', ); if (empty($callback_options['context']) && httprl_variable_get('httprl_loopback_ignore_ssl_errors', HTTPRL_LOOPBACK_IGNORE_SSL_ERRORS)) { // Set context for loopback 127.0.0.1 to ignore any SSL issues. $drupal_ssl_context_options = array( 'verify_peer' => FALSE, 'verify_peer_name' => FALSE, 'allow_self_signed' => TRUE, ); $options['context'] = stream_context_create(['ssl' => $drupal_ssl_context_options]); } if (isset($callback_options['printed'])) { $options['internal_states']['background_function_printed'] = &$callback_options['printed']; } Loading Loading @@ -2766,26 +2858,29 @@ function httprl_lock_release($name) { * @return mixed * $data */ function httprl_print_empty(&$data, $level = 0) { function httprl_print_empty(&$data, $level = 0, $output_plain_text) { $level++; if ($level < 5) { if (is_object($data)) { $new_object = new stdClass(); $new_object->__original_class_name__ = get_class($data); foreach ($data as $key => $values) { $new_object->{$key} = httprl_print_empty($values, $level); $new_object->{$key} = httprl_print_empty($values, $level, $output_plain_text); } $data = $new_object; } elseif (is_array($data)) { foreach ($data as &$values) { $values = httprl_print_empty($values, $level); $values = httprl_print_empty($values, $level, $output_plain_text); } } elseif (is_bool($data) || strlen((string) $data) == 0) { $data = strtoupper(var_export($data, TRUE)); } elseif (is_string($data) && strlen($data) > HTTPRL_PR_MAX_STRING_LENGTH) { elseif (!$output_plain_text && is_string($data) && strlen($data) > HTTPRL_PR_MAX_STRING_LENGTH ) { // Do not try to print a string longer than 256KB. // Some browsers have issues with very long documents. $data = substr($data, 0, HTTPRL_PR_MAX_STRING_LENGTH); Loading Loading @@ -2815,7 +2910,7 @@ function httprl_pr($input) { $input = func_get_args(); // If bool or strlen = 0 use var_export on that variable. $data = httprl_print_empty($input); $data = httprl_print_empty($input, 0, $output_plain_text); // Merge into base array if only one argument passed in. if (count($data) == 1) { Loading Loading @@ -3596,8 +3691,8 @@ function httprl_call_user_func_array_cache($callback, array $param_arr = array() else { $cid = __FUNCTION__ . ':' . drupal_hash_base64(serialize(array($callback, $param_arr))); } $cache = cache_get($cid, $options['bin']); // Don't use the cache if it's not there or the cached item is older than // the max cache lifetime. if (empty($options['return_null_cache_miss']) && (!isset($cache->data) || $cache->created < REQUEST_TIME - $options['cache_lifetime_max'])) { Loading Loading @@ -3633,13 +3728,24 @@ function httprl_call_user_func_array_cache($callback, array $param_arr = array() && lock_may_be_available($cid . ':run_function') && httprl_acquire_headless_lock($cid, $options['lock_timeout']) ) { // Set max to zero so this gets regenerated in the background. // Also do not skip on a cache miss. $options['cache_lifetime_max'] = 0; $options['return_null_cache_miss'] = FALSE; // Get all function arguments. $args = array($callback, $param_arr, $options); // Call this function again in another process with max lifetime set to // zero. if (!httprl_is_background_callback_capable()) { // Call this function again in a shutdown function. _httprl_run_functions_once_on_shutdown_array_cache($args); } else { // Call this function again in another process. httprl_call_user_func_array_async('httprl_call_user_func_array_cache', $args); } } } return isset($cache->data) ? $cache->data : NULL; } Loading @@ -3662,8 +3768,9 @@ function _httprl_run_functions_once_on_shutdown_array_cache($args = array()) { unset($args); $will_run = array(); $already_ran = array(); foreach ($run_list as $args) { foreach ($run_list as $key => $args) { if (empty($args)) { unset($run_list[$key]); continue; } if (is_string($args[0])) { Loading @@ -3678,8 +3785,10 @@ function _httprl_run_functions_once_on_shutdown_array_cache($args = array()) { } } if (!empty($will_run)) { // Last chance for async call; odds are this will be a sync call if here. httprl_call_user_func_array_async('_httprl_run_cache_functions', array($will_run)); } unset($run_list[$key]); } } Loading @@ -3690,11 +3799,17 @@ function _httprl_run_functions_once_on_shutdown_array_cache($args = array()) { * The callable to be called. */ function _httprl_run_cache_functions($functions_to_cache) { // Cut connection to browser. @ob_end_flush(); @ob_flush(); @flush(); sleep(1); if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } foreach ($functions_to_cache as $args) { // Set max to zero so this gets regenerated in the background. // Also do not skip on a cache miss. $args[2]['cache_lifetime_max'] = 0; $args[2]['return_null_cache_miss'] = FALSE; call_user_func_array('httprl_call_user_func_array_cache', $args); } } Loading