]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/FetchRemote/FetchRemotePlugin.php
Possibly replace weirdly capitalized htTPs: too
[quix0rs-gnu-social.git] / plugins / FetchRemote / FetchRemotePlugin.php
1 <?php
2 /*
3  * GNU social - a federating social network
4  * Copyright (C) 2013-2014, Free Software Foundation, Inc.
5  *
6  * This program 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  * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /**
21  * Uses WebFinger to implement remote notice retrieval for GNU social.
22  *
23  * Depends on: WebFinger plugin
24  *
25  * @package GNUsocial
26  * @author  Mikael Nordfeldth <mmn@hethane.se>
27  */
28
29 if (!defined('GNUSOCIAL')) { exit(1); }
30
31 class FetchRemotePlugin extends Plugin
32 {
33     static function fetchNoticeFromUrl($url)
34     {
35         if (!common_valid_http_url($url)) {
36             throw new InvalidUrlException($url);
37         }
38         $host = parse_url($url, PHP_URL_HOST);
39
40         // TODO: try to fetch directly, either by requesting Atom or
41         // Link headers/<head> elements with rel=alternate and compare
42         // the remote domain name with the notice URL's.
43
44         if (!$stored instanceof Notice) {
45             common_log(LOG_INFO, 'Could not fetch remote notice from URL: '._ve($url));
46             throw new ServerException('Could not fetch remote notice.');
47         }
48         return $stored;
49     }
50
51     public function onFetchRemoteNoticeWithSource($uri, Profile $source, &$stored)
52     {
53         if (common_valid_http_url($uri) && !Event::handle('FetchRemoteNoticeFromUrl', array($url, &$stored))) {
54             // Woopi, we got it straight from a URL-formatted URI!
55             return false;
56         }
57
58         // Let's assume we can only do this over HTTPS and a proper
59         // WebFinger (RFC7033) endpoint on /.well-known/webfinger
60         try {
61             $source_url = parse_url($source->getUrl());
62         } catch (InvalidUrlException $e) {
63             return true;
64         }
65         if ($source_url['scheme'] !== 'https') {
66             common_debug('Will not try to fetch remote notice from non-HTTPS capable profile source');
67             return true;
68         }
69
70         try {
71             $port    = isset($source_url['port']) ? ":{$source_url['port']}" : '';
72             $rfc7033 = "https://{$source_url['host']}{$port}/.well-known/webfinger";
73             $params  = ['resource' => $uri];
74             common_debug(__METHOD__ . ": getting json data about notice from: {$rfc7033}?resource=$uri");
75             $json    = HTTPClient::quickGetJson($rfc7033, $params);
76         } catch (Exception $e) {
77             // NOPE NOPE NOPE NOPE
78             // couldn't get remote data about this notice's URI
79             // FIXME: try later?
80             return true;
81         }
82
83         if (!isset($json->aliases)) {
84            // FIXME: malformed json for our current use, but maybe we could find rel="alternate" type="text/html"?
85            return true;
86         }
87
88         common_debug(__METHOD__ . ": Found these aliases: "._ve($json->aliases));
89         foreach ($json->aliases as $alias) {
90             try {
91                 $stored = self::fetchNoticeFromUrl($url);
92                 if ($stored instanceof Notice) {
93                     // we're done here! all good, let's get back to business
94                     return false;
95                 }
96             } catch (InvalidUrlException $e) {
97                 /// mmmmye, aliases might not always be HTTP(S) URLs.
98             } catch (Exception $e) {
99                 // oh well, try the next one and see if it works better.
100                 common_debug(__METHOD__ . ": {$e->getMessage()}");
101             }
102         }
103
104         // Nothing found, return true to continue processing the event
105         return true;
106     }
107
108     public function onPluginVersion(array &$versions)
109     {
110         $versions[] = array('name' => 'FetchRemote',
111                             'version' => GNUSOCIAL_VERSION,
112                             'author' => 'Mikael Nordfeldth',
113                             'homepage' => 'http://www.gnu.org/software/social/',
114                             // TRANS: Plugin description.
115                             'rawdescription' => _m('Retrieves remote notices (and serves local) via WebFinger'));
116
117         return true;
118     }
119 }