No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.php 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. // TODO: Better logging
  3. // TODO: Normalize target_url
  4. /**
  5. * Simple, Mf2-aware, quick & dirty script to handle webmentions
  6. */
  7. require_once('config.php');
  8. require_once('extlib/webmention.php');
  9. require_once('vendor/autoload.php');
  10. /*********
  11. * Utils *
  12. *********/
  13. function safe($unsafe) {
  14. $unsafe = strip_tags($unsafe);
  15. $safe = htmlspecialchars($unsafe, ENT_QUOTES);
  16. return $safe;
  17. }
  18. // Returns author info as well as truncated post text suitable for display.
  19. function getWebmention($mf, $url) {
  20. foreach($mf['items'] as $microformat) {
  21. return IndieWeb\comments\parse($microformat, $url);
  22. }
  23. }
  24. $source_url = $_POST['source'];
  25. $target_url = $_POST['target'];
  26. /************************
  27. * House-keeping stuffs *
  28. ************************/
  29. // Make sure the mentioned page is from our host
  30. if (parse_url($target_url, PHP_URL_HOST) !== $config["site"]["host"]) {
  31. error_log("Webmention for another host: " . $source_url, 4);
  32. exit("Err");
  33. }
  34. // Make sure the mentioned page exists
  35. if (head($target_url) === null) {
  36. error_log("Webmention for a page that doesn't exist: " . $target_url, 4);
  37. exit("Err");
  38. }
  39. // HTTP GET
  40. $source_html = get($source_url, $target_url);
  41. if ($source_html === null) {
  42. error_log("Failed to fetch remote page: " . $source_url, 4);
  43. exit("Err");
  44. }
  45. /**************
  46. * Mf2 stuffs *
  47. **************/
  48. $mf = Mf2\parse($source_html, $source_url);
  49. $webmention = getWebmention($mf, $target_url);
  50. // FIXME:
  51. // https://github.com/pear2/Services_Linkback/blob/2afd453254c531925484196670e2953f669ae141/src/PEAR2/Services/Linkback/Server/Callback/LinkExists.php#L40
  52. // https://github.com/indieweb/php-mf2/blob/master/Mf2/Parser.php#L966
  53. // https://stackoverflow.com/questions/2087103/how-to-get-innerhtml-of-domnode
  54. if (!stristr($source_html, $target_url) || $webmention === null) {
  55. error_log("Fake webmention from: " . $source_url, 4);
  56. exit("Fake");
  57. }
  58. /*************
  59. * DB Stuffs *
  60. *************/
  61. $dsn = 'mysql:dbname=' . $config['db']['name'] . ';host=' . $config['db']['host'];
  62. $user = $config['db']['username'];
  63. $password = $config['db']['password'];
  64. try {
  65. $dbh = new PDO($dsn, $user, $password);
  66. } catch (PDOException $e) {
  67. error_log('Connection failed: ' . $e->getMessage(), 4);
  68. exit("Err");
  69. }
  70. $sth = $dbh->prepare(
  71. 'INSERT INTO webmentions (local_url, url, name, text, author_name, author_url, type) ' .
  72. 'VALUES(?, ?, ?, ?, ?, ?, ?)'
  73. );
  74. if ($sth === false) {
  75. error_log("Could not prepare SQL statement.");
  76. error_log("Error code: " . $dbh->errorCode());
  77. error_log("Error info: " . $dbh->errorInfo());
  78. }
  79. $remote_url = safe(($webmention['url'] !== false) ? $webmention['url'] : $source_url);
  80. // Prevent authorship spoofing
  81. // FIXME: make better.
  82. $author_url = $webmention['author']['url'];
  83. if (parse_url($author_url, PHP_URL_HOST) !== parse_url($source_url, PHP_URL_HOST)) {
  84. error_log('Author URL host does not match source url host; discarding...', 4);
  85. error_log('Author URL: ' . $author_url, 4);
  86. error_log('Source URL: ' . $source_url, 4);
  87. $author_url = '';
  88. }
  89. $res = $sth->execute(array(
  90. $target_url,
  91. $remote_url,
  92. safe($webmention['name']),
  93. safe($webmention['text']),
  94. safe($webmention['author']['name']),
  95. safe($author_url),
  96. safe($webmention['type'])
  97. ));
  98. if ($res === false) {
  99. error_log("Could not execute SQL query.");
  100. error_log("Error code: " . $dbh->errorCode());
  101. error_log("Error info: " . print_r($dbh->errorInfo(), true));
  102. error_log(
  103. print_r($webmention, true),
  104. 4
  105. );
  106. }