PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/_Other/httprl/README.txt

https://github.com/all4senses/bvc
Plain Text | 594 lines | 497 code | 97 blank | 0 comment | 0 complexity | 2e865452c3836ab01b3f8473b5985e26 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, GPL-2.0, LGPL-2.1
  1. ------------------------------------------------
  2. HTTP PARALLEL REQUEST & THREADING LIBRARY MODULE
  3. ------------------------------------------------
  4. CONTENTS OF THIS FILE
  5. ---------------------
  6. * About HTTPRL
  7. * Requirements
  8. * Configuration
  9. * API Overview
  10. * Technical Details
  11. * Code Examples
  12. ABOUT HTTPRL
  13. ------------
  14. http://drupal.org/project/httprl
  15. HTTPRL is a flexible and powerful HTTP client implementation. Correctly handles
  16. GET, POST, PUT or any other HTTP requests & the sending of data. Issue blocking
  17. or non-blocking requests in parallel. Set timeouts, max simultaneous connection
  18. limits, chunk size, and max redirects to follow. Can handle data with
  19. content-encoding and transfer-encoding headers set. Correctly follows
  20. redirects. Option to forward the referrer when a redirect is found. Cookie
  21. extraction and parsing into key value pairs.
  22. REQUIREMENTS
  23. ------------
  24. Requires PHP 5. The following functions must be available on the server:
  25. * stream_socket_client
  26. * stream_select
  27. * stream_set_blocking
  28. * stream_get_meta_data
  29. * stream_socket_get_name
  30. Some hosting providers disable these functions; but they do come standard with
  31. PHP 5.
  32. CONFIGURATION
  33. -------------
  34. Settings page is located at:
  35. 6.x: admin/settings/httprl
  36. 7.x: admin/config/development/httprl
  37. * IP Address to send all self server requests to. If left blank it will use the
  38. same server as the request. If set to -1 it will use the host name instead of
  39. an IP address. This controls the output of httprl_build_url_self().
  40. API OVERVIEW
  41. ------------
  42. Issue HTTP Requests:
  43. httprl_build_url_self()
  44. - Helper function to build an URL for asynchronous requests to self.
  45. httprl_request()
  46. - Queue up a HTTP request in httprl_send_request().
  47. httprl_send_request()
  48. - Perform many HTTP requests.
  49. Create and use a thread:
  50. httprl_queue_background_callback()
  51. - Queue a special HTTP request (used for threading) in httprl_send_request().
  52. Other Functions:
  53. httprl_background_processing()
  54. - Output text, close connection, continue processing in the background.
  55. httprl_strlen()
  56. - Get the length of a string in bytes.
  57. httprl_glue_url()
  58. - Alt to http_build_url().
  59. httprl_get_server_schema()
  60. - Return the server schema (http or https).
  61. httprl_pr()
  62. - Pretty print data.
  63. httprl_fast403()
  64. - Issue a 403 and exit.
  65. TECHNICAL DETAILS
  66. -----------------
  67. Using stream_select() HTTPRL will send http requests out in parallel. These
  68. requests can be made in a blocking or non-blocking way. Blocking will wait for
  69. the http response; Non-Blocking will close the connection not waiting for the
  70. response back. The API for httprl is similar to the Drupal 7 version of
  71. drupal_http_request().
  72. CODE EXAMPLES
  73. -------------
  74. Request this servers own front page & the node page.
  75. <?php
  76. // Build URL to point to front page of this server.
  77. $url_front = httprl_build_url_self();
  78. $url_node = httprl_build_url_self('node');
  79. // Queue up the requests.
  80. httprl_request($url_front);
  81. httprl_request($url_node);
  82. // Execute requests.
  83. $request = httprl_send_request();
  84. // Echo out the results.
  85. echo httprl_pr($request);
  86. ?>
  87. Request 10 URLs in a non blocking manner on this server. Checkout watchdog as
  88. this should generate 10 404s and the $request object won't contain much info.
  89. <?php
  90. // Set the blocking mode.
  91. $options = array(
  92. 'blocking' => FALSE,
  93. );
  94. // Queue up the requests.
  95. $max = 10;
  96. for ($i=1; $i <= $max; $i++) {
  97. // Build URL to a page that doesn't exist.
  98. $url = httprl_build_url_self('asdf-asdf-asdf-' . $i);
  99. httprl_request($url, $options);
  100. }
  101. // Execute requests.
  102. $request = httprl_send_request();
  103. // Echo out the results.
  104. echo httprl_pr($request);
  105. ?>
  106. print 'My Text'; cut the connection by sending the data over the wire and do
  107. processing in the background.
  108. <?php
  109. httprl_background_processing('My Text');
  110. // Everything after this point does not affect page load time.
  111. ?>
  112. Use a callback in the event loop to do processing on the request. In this case
  113. we are going to use httprl_pr() as the callback function.
  114. <?php
  115. // Setup return variable.
  116. $x = '';
  117. // Setup options array.
  118. $options = array(
  119. 'method' => 'HEAD',
  120. 'callback' => array(
  121. array(
  122. 'function' => 'httprl_pr',
  123. 'return' => &$x,
  124. ),
  125. ),
  126. );
  127. // Build URL to point to front page of this server.
  128. $url_front = httprl_build_url_self();
  129. // Queue up the request.
  130. httprl_request($url_front, $options);
  131. // Execute request.
  132. $request = httprl_send_request();
  133. // Echo returned value from function callback.
  134. echo $x;
  135. ?>
  136. Use a background callback in the event loop to do processing on the request.
  137. In this case we are going to use httprl_pr() as the callback function. A
  138. background callback creates a new thread to run this function in.
  139. <?php
  140. // Setup return variable.
  141. $x = '';
  142. // Setup options array.
  143. $options = array(
  144. 'method' => 'HEAD',
  145. 'background_callback' => array(
  146. array(
  147. 'function' => 'httprl_pr',
  148. 'return' => &$x,
  149. ),
  150. ),
  151. );
  152. // Build URL to point to front page of this server.
  153. $url_front = httprl_build_url_self();
  154. // Queue up the request.
  155. httprl_request($url_front, $options);
  156. // Execute request.
  157. $request = httprl_send_request();
  158. // Echo returned value from function callback.
  159. echo $x;
  160. ?>
  161. Use a background callback in the event loop to do processing on the request.
  162. In this case we are going to use print_r() as the callback function. A
  163. background callback creates a new thread to run this function in. The first
  164. argument passed in is the request object, the FALSE tells print_r to echo out
  165. instead of returning a value.
  166. <?php
  167. // Setup return & print variable.
  168. $x = '';
  169. $y = '';
  170. // Setup options array.
  171. $options = array(
  172. 'method' => 'HEAD',
  173. 'background_callback' => array(
  174. array(
  175. 'function' => 'print_r',
  176. 'return' => &$x,
  177. 'printed' => &$y,
  178. ),
  179. FALSE,
  180. ),
  181. );
  182. // Build URL to point to front page of this server.
  183. $url_front = httprl_build_url_self();
  184. // Queue up the request.
  185. httprl_request($url_front, $options);
  186. // Execute request.
  187. $request = httprl_send_request();
  188. // Echo what was returned and printed from function callback.
  189. echo $x . "<br />\n";
  190. echo $y;
  191. ?>
  192. Use 2 threads to load up 4 different nodes.
  193. <?php
  194. // List of nodes to load; 241-244.
  195. $nodes = array(241 => '', 242 => '', 243 => '', 244 => '');
  196. foreach ($nodes as $nid => &$node) {
  197. // Setup callback options array.
  198. $callback_options = array(
  199. array(
  200. 'function' => 'node_load',
  201. 'return' => &$node,
  202. // Setup options array.
  203. 'options' => array(
  204. 'domain_connections' => 2, // Only use 2 threads for this request.
  205. ),
  206. ),
  207. $nid,
  208. );
  209. // Queue up the request.
  210. httprl_queue_background_callback($callback_options);
  211. }
  212. // Execute request.
  213. httprl_send_request();
  214. // Echo what was returned.
  215. echo httprl_pr($nodes);
  216. ?>
  217. Run a function in the background. Notice that there is no return or printed key
  218. in the callback options.
  219. <?php
  220. // Setup callback options array; call watchdog in the background.
  221. $callback_options = array(
  222. array(
  223. 'function' => 'watchdog',
  224. ),
  225. 'httprl-test', 'background watchdog call done', array(), WATCHDOG_DEBUG,
  226. );
  227. // Queue up the request.
  228. httprl_queue_background_callback($callback_options);
  229. // Execute request.
  230. httprl_send_request();
  231. ?>
  232. Pass by reference example. Example is D7 only; pass by reference works in
  233. D6 & D7.
  234. <?php
  235. // Code from system_rebuild_module_data().
  236. $modules = _system_rebuild_module_data();
  237. ksort($modules);
  238. // Show first module before running system_get_files_database().
  239. echo httprl_pr(current($modules));
  240. $callback_options = array(
  241. array(
  242. 'function' => 'system_get_files_database',
  243. 'return' => '',
  244. ),
  245. &$modules, 'module'
  246. );
  247. httprl_queue_background_callback($callback_options);
  248. // Execute requests.
  249. httprl_send_request();
  250. // Show first module after running system_get_files_database().
  251. echo httprl_pr(current($modules));
  252. ?>
  253. Request multiple URLs with one httprl_request() call. These URLs will all have
  254. the same options.
  255. <?php
  256. // Set the blocking mode.
  257. $options = array(
  258. 'method' => 'HEAD',
  259. 'blocking' => FALSE,
  260. );
  261. // Queue up the requests.
  262. $max = 10;
  263. $urls = array();
  264. for ($i=1; $i <= $max; $i++) {
  265. // Build URL to a page that doesn't exist.
  266. $urls[] = httprl_build_url_self('asdf-asdf-asdf-' . $i);
  267. }
  268. // Queue up the requests.
  269. httprl_request($urls, $options);
  270. // Execute requests.
  271. $request = httprl_send_request();
  272. // Echo out the results.
  273. echo httprl_pr($request);
  274. ?>
  275. Get 2 results from 2 different queries at the hook_boot bootstrap level in D6.
  276. <?php
  277. // Run 2 queries and get the result.
  278. $x = db_result(db_query_range("SELECT filename FROM {system} ORDER BY filename ASC", 0, 1));
  279. $y = db_result(db_query_range("SELECT filename FROM {system} ORDER BY filename DESC", 0, 1));
  280. echo $x . "<br \>\n" . $y . "<br \>\n";
  281. unset($x, $y);
  282. // Run above 2 queries and get the result via a background callback.
  283. $args = array(
  284. // First query.
  285. array(
  286. 'type' => 'function',
  287. 'call' => 'db_query_range',
  288. 'args' => array('SELECT filename FROM {system} ORDER BY filename ASC', 0, 1),
  289. ),
  290. array(
  291. 'type' => 'function',
  292. 'call' => 'db_result',
  293. 'args' => array('last' => NULL),
  294. 'return' => &$x,
  295. ),
  296. // Second Query.
  297. array(
  298. 'type' => 'function',
  299. 'call' => 'db_query',
  300. 'args' => array('SELECT filename FROM {system} ORDER BY filename DESC', 0, 1),
  301. ),
  302. array(
  303. 'type' => 'function',
  304. 'call' => 'db_result',
  305. 'args' => array('last' => NULL),
  306. 'return' => &$y,
  307. ),
  308. );
  309. $callback_options = array(array('return' => ''), &$args);
  310. // Queue up the request.
  311. httprl_queue_background_callback($callback_options);
  312. // Execute request.
  313. httprl_send_request();
  314. // Echo what was returned.
  315. echo httprl_pr($x, $y);
  316. ?>
  317. Get 2 results from 2 different queries at the hook_boot bootstrap level in D7.
  318. <?php
  319. $x = db_select('system', 's')
  320. ->fields('s', array('filename'))
  321. ->orderBy('filename', 'ASC')
  322. ->range(0, 1)
  323. ->execute()
  324. ->fetchField();
  325. $y = db_select('system', 's')
  326. ->fields('s', array('filename'))
  327. ->orderBy('filename', 'DESC')
  328. ->range(0, 1)
  329. ->execute()
  330. ->fetchField();
  331. echo $x . "<br \>\n" . $y . "<br \>\n";
  332. unset($x, $y);
  333. // Run above 2 queries and get the result via a background callback.
  334. $args = array(
  335. // First query.
  336. array(
  337. 'type' => 'function',
  338. 'call' => 'db_select',
  339. 'args' => array('system', 's',),
  340. ),
  341. array(
  342. 'type' => 'method',
  343. 'call' => 'fields',
  344. 'args' => array('s', array('filename')),
  345. ),
  346. array(
  347. 'type' => 'method',
  348. 'call' => 'orderBy',
  349. 'args' => array('filename', 'ASC'),
  350. ),
  351. array(
  352. 'type' => 'method',
  353. 'call' => 'range',
  354. 'args' => array(0, 1),
  355. ),
  356. array(
  357. 'type' => 'method',
  358. 'call' => 'execute',
  359. 'args' => array(),
  360. ),
  361. array(
  362. 'type' => 'method',
  363. 'call' => 'fetchField',
  364. 'args' => array(),
  365. 'return' => &$x,
  366. ),
  367. // Second Query.
  368. array(
  369. 'type' => 'function',
  370. 'call' => 'db_select',
  371. 'args' => array('system', 's',),
  372. ),
  373. array(
  374. 'type' => 'method',
  375. 'call' => 'fields',
  376. 'args' => array('s', array('filename')),
  377. ),
  378. array(
  379. 'type' => 'method',
  380. 'call' => 'orderBy',
  381. 'args' => array('filename', 'DESC'),
  382. ),
  383. array(
  384. 'type' => 'method',
  385. 'call' => 'range',
  386. 'args' => array(0, 1),
  387. ),
  388. array(
  389. 'type' => 'method',
  390. 'call' => 'execute',
  391. 'args' => array(),
  392. ),
  393. array(
  394. 'type' => 'method',
  395. 'call' => 'fetchField',
  396. 'args' => array(),
  397. 'return' => &$y,
  398. ),
  399. );
  400. $callback_options = array(array('return' => ''), &$args);
  401. // Queue up the request.
  402. httprl_queue_background_callback($callback_options);
  403. // Execute request.
  404. httprl_send_request();
  405. // Echo what was returned.
  406. echo httprl_pr($x, $y);
  407. ?>
  408. Run a cache clear at the DRUPAL_BOOTSTRAP_FULL level as the current user in a
  409. non blocking background request.
  410. <?php
  411. // Normal way to do this.
  412. drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
  413. module_load_include('inc', 'system', 'system.admin');
  414. system_clear_cache_submit();
  415. // How to do it in a non blocking background request.
  416. $args = array(
  417. array(
  418. 'type' => 'function',
  419. 'call' => 'drupal_bootstrap',
  420. 'args' => array(DRUPAL_BOOTSTRAP_FULL),
  421. ),
  422. array(
  423. 'type' => 'function',
  424. 'call' => 'module_load_include',
  425. 'args' => array('inc', 'system', 'system.admin'),
  426. ),
  427. array(
  428. 'type' => 'function',
  429. 'call' => 'system_clear_cache_submit',
  430. 'args' => array('', ''),
  431. ),
  432. array(
  433. 'type' => 'function',
  434. 'call' => 'watchdog',
  435. 'args' => array('httprl-test', 'background cache clear done', array(), WATCHDOG_DEBUG),
  436. ),
  437. );
  438. // Pass the current session to the sub request.
  439. if (!empty($_COOKIE[session_name()])) {
  440. $options = array('headers' => array('Cookie' => session_name() . '=' . $_COOKIE[session_name()] . ';'));
  441. }
  442. else {
  443. $options = array();
  444. }
  445. $callback_options = array(array('options' => $options), &$args);
  446. // Queue up the request.
  447. httprl_queue_background_callback($callback_options);
  448. // Execute request.
  449. httprl_send_request();
  450. ?>
  451. Hit 4 different URLs, Using at least 2 that has a status code of 200 and
  452. erroring out on the others that didn't return. Data is truncated as well.
  453. // Array of URLs to get.
  454. $urls = array(
  455. 'http://google.com/',
  456. 'http://bing.com/',
  457. 'http://yahoo.com/',
  458. 'http://www.duckduckgo.com/',
  459. 'http://www.drupal.org/',
  460. );
  461. // Process list of URLs.
  462. $options = array(
  463. 'alter_all_streams_function' => 'need_two_good_results',
  464. 'callback' => array(array('function' => 'limit_data_size')),
  465. );
  466. // Queue up the requests.
  467. httprl_request($urls, $options);
  468. // Execute requests.
  469. $requests = httprl_send_request();
  470. // Print what was done.
  471. echo httprl_pr($requests);
  472. function need_two_good_results($id, &$responses, &$streams, $current_time) {
  473. static $counter = 0;
  474. foreach ($responses as $id => &$result) {
  475. // Skip if we got a 200.
  476. if ($result->code == 200) {
  477. $counter = $counter + 1;
  478. continue;
  479. }
  480. if ($result->status == 'Done.') {
  481. continue;
  482. }
  483. if ($counter >= 2) {
  484. // Set the code to request was aborted.
  485. $result->code = HTTPRL_REQUEST_ABORTED;
  486. $result->status = 'Done.';
  487. $result->options['timeout'] = $result->options['timeout'] - $current_time;
  488. // Close the file pointer and remove from the stream from the array.
  489. fclose($streams[$id]);
  490. unset($streams[$id]);
  491. }
  492. }
  493. }
  494. function limit_data_size(&$result) {
  495. // Only use the first and last 256 characters in the data array.
  496. $result->data = substr($result->data, 0, 256) . "\n\n ... \n\n" . substr($result->data, strlen($result->data)-256);
  497. }