LrddMethodLinkHtml.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. declare(strict_types = 1);
  3. namespace Component\FreeNetwork\Util\LrddMethod;
  4. // This file is part of GNU social - https://www.gnu.org/software/social
  5. //
  6. // GNU social is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // GNU social is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with GNU social. If not, see <http://www.gnu.org/licenses/>.
  18. use Component\FreeNetwork\Util\LrddMethod;
  19. use XML_XRD_Element_Link;
  20. /**
  21. * Implementation of discovery using HTML <link> element
  22. *
  23. * Discovers XRD file for a user by fetching the URL and reading any
  24. * <link> elements in the HTML response.
  25. *
  26. * @category Discovery
  27. * @package GNUsocial
  28. *
  29. * @author James Walker <james@status.net>
  30. * @copyright 2010 StatusNet, Inc.
  31. * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  32. */
  33. class LrddMethodLinkHtml extends LRDDMethod
  34. {
  35. /**
  36. * For HTTP IDs, fetch the URL and look for <link> elements
  37. * in the HTML response.
  38. *
  39. * @todo fail out of WebFinger URIs faster
  40. */
  41. public function discover($uri)
  42. {
  43. $response = self::fetchUrl($uri);
  44. return self::parse($response->getContent());
  45. }
  46. /**
  47. * Parse HTML and return <link> elements
  48. *
  49. * Given an HTML string, scans the string for <link> elements
  50. *
  51. * @param string $html HTML to scan
  52. *
  53. * @return array array of associative arrays in JRD-ish array format
  54. */
  55. public function parse($html)
  56. {
  57. $links = [];
  58. preg_match('/<head(\s[^>]*)?>(.*?)<\/head>/is', $html, $head_matches);
  59. if (\count($head_matches) != 3) {
  60. return [];
  61. }
  62. [, , $head_html] = $head_matches;
  63. preg_match_all('/<link\s[^>]*>/i', $head_html, $link_matches);
  64. foreach ($link_matches[0] as $link_html) {
  65. $link_url = null;
  66. $link_rel = null;
  67. $link_type = null;
  68. preg_match('/\srel=(("|\')([^\\2]*?)\\2|[^"\'\s]+)/i', $link_html, $rel_matches);
  69. if (\count($rel_matches) > 3) {
  70. $link_rel = $rel_matches[3];
  71. } elseif (\count($rel_matches) > 1) {
  72. $link_rel = $rel_matches[1];
  73. }
  74. preg_match('/\shref=(("|\')([^\\2]*?)\\2|[^"\'\s]+)/i', $link_html, $href_matches);
  75. if (\count($href_matches) > 3) {
  76. $link_uri = $href_matches[3];
  77. } elseif (\count($href_matches) > 1) {
  78. $link_uri = $href_matches[1];
  79. }
  80. preg_match('/\stype=(("|\')([^\\2]*?)\\2|[^"\'\s]+)/i', $link_html, $type_matches);
  81. if (\count($type_matches) > 3) {
  82. $link_type = $type_matches[3];
  83. } elseif (\count($type_matches) > 1) {
  84. $link_type = $type_matches[1];
  85. }
  86. $links[] = new XML_XRD_Element_Link($link_rel, $link_uri, $link_type);
  87. }
  88. return $links;
  89. }
  90. }