PluginProbe
ActivityPub / 7.8.4
ActivityPub v7.8.4
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / class-http.php

class-http.php in ActivityPub 7.8.4, at includes/class-http.php

276 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ActivityPub HTTP Class.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub;
9
10 use Activitypub\Collection\Actors;
11
12 /**
13 * ActivityPub HTTP Class
14 *
15 * @author Matthias Pfefferle
16 */
17 class Http {
18 /**
19 * Send a POST Request with the needed HTTP Headers
20 *
21 * @param string $url The URL endpoint.
22 * @param string $body The Post Body.
23 * @param int $user_id The WordPress User-ID.
24 *
25 * @return array|\WP_Error The POST Response or an WP_Error.
26 */
27 public static function post( $url, $body, $user_id ) {
28 /**
29 * Fires before an HTTP POST request is made.
30 *
31 * @param string $url The URL endpoint.
32 * @param string $body The POST body.
33 * @param int $user_id The WordPress User ID.
34 */
35 \do_action( 'activitypub_pre_http_post', $url, $body, $user_id );
36
37 /**
38 * Filters the HTTP headers user agent string.
39 *
40 * @param string $user_agent The user agent string.
41 */
42 $user_agent = \apply_filters( 'http_headers_useragent', 'WordPress/' . get_masked_wp_version() . '; ' . \get_bloginfo( 'url' ) );
43 $args = array(
44 'timeout' => 100,
45 'limit_response_size' => 1048576,
46 'redirection' => 3,
47 'user-agent' => "$user_agent; ActivityPub",
48 'headers' => array(
49 'Accept' => 'application/activity+json',
50 'Content-Type' => 'application/activity+json',
51 'Date' => \gmdate( 'D, d M Y H:i:s T' ),
52 ),
53 'body' => $body,
54 'key_id' => \json_decode( $body )->actor . '#main-key',
55 'private_key' => Actors::get_private_key( $user_id ),
56 'user_id' => $user_id,
57 );
58
59 $response = \wp_safe_remote_post( $url, $args );
60 $code = \wp_remote_retrieve_response_code( $response );
61
62 if ( $code >= 400 ) {
63 $response = new \WP_Error(
64 $code,
65 __( 'Failed HTTP Request', 'activitypub' ),
66 array(
67 'status' => $code,
68 'response' => $response,
69 )
70 );
71 }
72
73 /**
74 * Action to save the response of the remote POST request.
75 *
76 * @param array|\WP_Error $response The response of the remote POST request.
77 * @param string $url The URL endpoint.
78 * @param string $body The Post Body.
79 * @param int $user_id The WordPress User-ID.
80 */
81 \do_action( 'activitypub_safe_remote_post_response', $response, $url, $body, $user_id );
82
83 return $response;
84 }
85
86 /**
87 * Send a GET Request with the needed HTTP Headers.
88 *
89 * @param string $url The URL endpoint.
90 * @param bool|int $cached Optional. Whether the result should be cached, or its duration. Default false.
91 *
92 * @return array|\WP_Error The GET Response or a WP_Error.
93 */
94 public static function get( $url, $cached = false ) {
95 /**
96 * Fires before an HTTP GET request is made.
97 *
98 * @param string $url The URL endpoint.
99 */
100 \do_action( 'activitypub_pre_http_get', $url );
101
102 if ( $cached ) {
103 $transient_key = self::generate_cache_key( $url );
104
105 $response = \get_transient( $transient_key );
106
107 if ( $response ) {
108 /**
109 * Action to save the response of the remote GET request.
110 *
111 * @param array|\WP_Error $response The response of the remote GET request.
112 * @param string $url The URL endpoint.
113 */
114 \do_action( 'activitypub_safe_remote_get_response', $response, $url );
115
116 return $response;
117 }
118 }
119
120 /**
121 * Filters the HTTP headers user agent string.
122 *
123 * This filter allows developers to modify the user agent string that is
124 * sent with HTTP requests.
125 *
126 * @param string $user_agent The user agent string.
127 */
128 $user_agent = \apply_filters( 'http_headers_useragent', 'WordPress/' . get_masked_wp_version() . '; ' . \get_bloginfo( 'url' ) );
129
130 /**
131 * Filters the timeout duration for remote GET requests in ActivityPub.
132 *
133 * @param int $timeout The timeout value in seconds. Default 100 seconds.
134 */
135 $timeout = \apply_filters( 'activitypub_remote_get_timeout', 100 );
136
137 $args = array(
138 'timeout' => $timeout,
139 'limit_response_size' => 1048576,
140 'redirection' => 3,
141 'user-agent' => "$user_agent; ActivityPub",
142 'headers' => array(
143 'Accept' => 'application/activity+json',
144 'Content-Type' => 'application/activity+json',
145 'Date' => \gmdate( 'D, d M Y H:i:s T' ),
146 ),
147 'key_id' => Actors::get_by_id( Actors::APPLICATION_USER_ID )->get_id() . '#main-key',
148 'private_key' => Actors::get_private_key( Actors::APPLICATION_USER_ID ),
149 );
150
151 $response = \wp_safe_remote_get( $url, $args );
152 $code = \wp_remote_retrieve_response_code( $response );
153
154 if ( $code >= 400 ) {
155 $response = new \WP_Error( $code, __( 'Failed HTTP Request', 'activitypub' ), array( 'status' => $code ) );
156 }
157
158 /**
159 * Action to save the response of the remote GET request.
160 *
161 * @param array|\WP_Error $response The response of the remote GET request.
162 * @param string $url The URL endpoint.
163 */
164 \do_action( 'activitypub_safe_remote_get_response', $response, $url );
165
166 if ( $cached ) {
167 $cache_duration = $cached;
168 if ( ! is_int( $cache_duration ) ) {
169 $cache_duration = HOUR_IN_SECONDS;
170 }
171 \set_transient( $transient_key, $response, $cache_duration );
172 }
173
174 return $response;
175 }
176
177 /**
178 * Check for URL for Tombstone.
179 *
180 * @param string $url The URL to check.
181 *
182 * @return bool True if the URL is a tombstone.
183 */
184 public static function is_tombstone( $url ) {
185 _deprecated_function( __METHOD__, '7.3.0', 'Activitypub\Tombstone::exists_remote' );
186
187 return Tombstone::exists_remote( $url );
188 }
189
190 /**
191 * Generate a cache key for the URL.
192 *
193 * @param string $url The URL to generate the cache key for.
194 *
195 * @return string The cache key.
196 */
197 public static function generate_cache_key( $url ) {
198 return 'activitypub_http_' . \md5( $url );
199 }
200
201 /**
202 * Requests the Data from the Object-URL or Object-Array.
203 *
204 * @param array|string $url_or_object The Object or the Object URL.
205 * @param bool $cached Optional. Whether the result should be cached. Default true.
206 *
207 * @return array|\WP_Error The Object data as array or WP_Error on failure.
208 */
209 public static function get_remote_object( $url_or_object, $cached = true ) {
210 /**
211 * Filters the preemptive return value of a remote object request.
212 *
213 * @param array|string|null $response The response.
214 * @param array|string|null $url_or_object The Object or the Object URL.
215 */
216 $response = apply_filters( 'activitypub_pre_http_get_remote_object', null, $url_or_object );
217 if ( null !== $response ) {
218 return $response;
219 }
220
221 $url = object_to_uri( $url_or_object );
222
223 if ( preg_match( '/^@?' . ACTIVITYPUB_USERNAME_REGEXP . '$/i', $url ) ) {
224 $url = Webfinger::resolve( $url );
225 }
226
227 if ( ! $url ) {
228 return new \WP_Error(
229 'activitypub_no_valid_actor_identifier',
230 \__( 'The "actor" identifier is not valid', 'activitypub' ),
231 array(
232 'status' => 404,
233 'object' => $url,
234 )
235 );
236 }
237
238 if ( \is_wp_error( $url ) ) {
239 return $url;
240 }
241
242 if ( ! \wp_http_validate_url( $url ) ) {
243 return new \WP_Error(
244 'activitypub_no_valid_object_url',
245 \__( 'The "object" is/has no valid URL', 'activitypub' ),
246 array(
247 'status' => 400,
248 'object' => $url,
249 )
250 );
251 }
252
253 $response = self::get( $url, $cached );
254
255 if ( \is_wp_error( $response ) ) {
256 return $response;
257 }
258
259 $data = \wp_remote_retrieve_body( $response );
260 $data = \json_decode( $data, true );
261
262 if ( ! $data ) {
263 return new \WP_Error(
264 'activitypub_invalid_json',
265 \__( 'No valid JSON data', 'activitypub' ),
266 array(
267 'status' => 400,
268 'object' => $url,
269 )
270 );
271 }
272
273 return $data;
274 }
275 }
276