├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── README.md
├── composer.json
├── coverage
├── MentionClient.php.html
├── clover.xml
├── css
│ ├── bootstrap.min.css
│ ├── nv.d3.min.css
│ └── style.css
├── dashboard.html
├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ └── glyphicons-halflings-regular.woff2
├── index.html
└── js
│ ├── bootstrap.min.js
│ ├── d3.min.js
│ ├── holder.min.js
│ ├── html5shiv.min.js
│ ├── jquery.min.js
│ ├── nv.d3.min.js
│ └── respond.min.js
├── example.php
├── phpunit
├── phpunit.xml
├── src
└── IndieWeb
│ ├── MentionClient.php
│ └── MentionClientTest.php
└── tests
├── DiscoverTest.php
├── FindOutgoingLinksTest.php
├── LinkHeaderParserTest.php
├── SendMentionsTest.php
├── SendPingbackTest.php
├── SendWebmentionTest.php
├── TagParserTest.php
├── bootstrap.php
└── data
├── 404.response.txt
├── pingback-endpoint.example
├── 404-response
├── empty-body
├── invalid-body
├── invalid-request
├── invalid-xmlrpc
└── valid-response
├── pingback-target.example
├── has-erroring-endpoint.html
├── has-valid-endpoint.html
└── no-endpoint.html
├── source.example.com
├── mixed-success-links.html
├── no-links.html
├── send-to-h-entry-links.html
├── target-has-both.html
└── two-valid-links.html
├── target.example.com
├── body-a.html
├── body-link-org.html
├── body-link-org2.html
├── body-link.html
├── document-order-1.html
├── document-order-2.html
├── empty-string.html
├── false-endpoint-in-comment.html
├── header.html
├── only-pingback.html
├── pingback-failed.html
├── redirect.html
├── relative
│ ├── after-redirect.html
│ └── path-relative-endpoint.html
├── webmention-created.html
├── webmention-failed.html
├── webmention-only-failed.html
├── webmention-rocks-test-1.html
├── webmention-rocks-test-2.html
├── webmention-rocks-test-3.html
├── webmention-rocks-test-4.html
├── webmention-rocks-test-5.html
├── webmention-rocks-test-6.html
├── webmention-rocks-test-7.html
└── webmention-rocks-test-8.html
├── webmention-endpoint.example
├── 404-response
├── 500-response
├── created-response
├── invalid-request
└── queued-response
└── webmention-target.example
├── has-erroring-endpoint.html
├── has-valid-endpoint.html
└── no-endpoint.html
/.gitignore:
--------------------------------------------------------------------------------
1 | composer.phar
2 | composer.lock
3 | .DS_Store
4 | /vendor/
5 | .idea/*
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 5.6
4 | - 7.2
5 | - 7.3
6 | - 7.4
7 | before_script: composer install
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | By contributing to this project, you agree to irrevocably release your contributions under the same licenses as this project. See README.md for more details.
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Webmention Client
2 | =================
3 |
4 | Client library for sending [webmention](http://indiewebcamp.com/webmention) and [pingback](http://indiewebcamp.com/pingback) notifications.
5 |
6 | [](http://travis-ci.org/indieweb/mention-client-php)
7 | [](https://packagist.org/packages/indieweb/mention-client)
8 |
9 | Usage
10 | -----
11 |
12 | ### Basic Usage
13 |
14 | Given one of your source URLs, this function will find links on the page,
15 | discover the webmention and pingback endpoints for each, and send mentions for any
16 | it discovers.
17 |
18 | ```php
19 | sendMentions($sourceURL);
22 |
23 | echo "Sent $sent mentions\n";
24 | ?>
25 | ```
26 |
27 | The library will fetch the source URL, parse it, and look for the first h-entry,
28 | h-card or h-event. It will then attempt to send webmentions (and pingbacks) to
29 | all URLs found in the object, as either properties or inside the "content" HTML.
30 |
31 | The library attempts to find the endpoints by doing a HEAD request to the target URL
32 | and looking at the headers, and if none are found, then it makes a GET request
33 | and searches the body of the page for the rel values.
34 |
35 | After finding either pingback or webmention endpoints, the request is sent to each.
36 |
37 | Alternatively, you can pass in HTML as the second parameter and the library will
38 | look for ALL absolute links in the HTML instead of fetching your post contents and
39 | looking for the microformats object.
40 |
41 | ```php
42 | sendMentions($sourceURL, $sourceHTML);
45 |
46 | echo "Sent $sent mentions\n";
47 | ?>
48 | ```
49 |
50 | ### Discovering the Webmention endpoint
51 |
52 | Given a target URL, this function will return its webmention endpoint
53 | if found, otherwise it will return false.
54 |
55 | ```php
56 | discoverWebmentionEndpoint($targetURL);
59 | $endpoint = $client->discoverPingbackEndpoint($targetURL);
60 | ?>
61 | ```
62 |
63 | ### Sending a Webmention
64 |
65 | To send a webmention to a target URL, you can use the function below. This will
66 | first discover the webmention endpoint of the target, and if found, will then
67 | send the webmention payload to it. You can pass an additional parameter to include
68 | other properties in the payload.
69 |
70 | ```php
71 | sendWebmention($sourceURL, $targetURL);
74 | $response = $client->sendWebmention($sourceURL, $targetURL, ['vouch'=>$vouch]);
75 | ?>
76 | ```
77 |
78 | If no webmention endpoint was found at the target, the function will return false.
79 | See the function below for an example of the response when the webmention is successful.
80 |
81 | You can also check if the endpoint advertises a webmention endpoint before trying
82 | to send one:
83 |
84 | ```php
85 | discoverWebmentionEndpoint($targetURL);
88 | if($supportsWebmention) {
89 | $client->sendWebmention($sourceURL, $targetURL);
90 | }
91 | ?>
92 | ```
93 |
94 | ### Sending a Pingback
95 |
96 | ```php
97 | sendPingback($sourceURL, $targetURL);
100 | ?>
101 | ```
102 |
103 | You can also check if the endpoint advertises a pingback endpoint before trying
104 | to send one:
105 |
106 | ```php
107 | discoverPingbackEndpoint($targetURL);
110 | if($supportsPingback) {
111 | $client->sendPingback($sourceURL, $targetURL);
112 | }
113 | ?>
114 | ```
115 |
116 | ### Sending the Webmention or Pingback directly
117 |
118 | To send the actual webmention or pingback payload, you can use the static functions below.
119 | You can pass additional properties for the webmention request in an array if needed.
120 |
121 | ```php
122 | $vouch]);
125 | ?>
126 | ```
127 |
128 | The response is an array containing the HTTP status code, HTTP headers, and the response body:
129 |
130 | ```json
131 | {
132 | "code": 202,
133 | "headers": {
134 | "Content-Type: text/plain"
135 | },
136 | "body": "Webmention is processing"
137 | }
138 | ```
139 |
140 | You can check if the webmention was accepted by testing if the response code is 200, 201 or 202.
141 |
142 | ```php
143 |
146 | ```
147 |
148 | The pingback function returns true or false depending on whether the pingback was successfully sent.
149 |
150 |
151 |
152 | ### Finding target URLs in a source document
153 |
154 | If you have a rendered HTML page (or partial HTML page), you can use this function to
155 | return a list of outgoing links found on the page.
156 |
157 | ```php
158 | findOutgoingLinks($html);
161 | ?>
162 | ```
163 |
164 | Alternately, you can pass a parsed Microformats object to the `findOutgoingLinks`
165 | function and it will search for URLs in any property as well as in the HTML of
166 | any e-content objects.
167 |
168 | ```php
169 | $client = new IndieWeb\MentionClient();
170 | $parsed = \Mf2\parse($html, $sourceURL);
171 | $urls = $client->findOutgoingLinks($parsed);
172 | ```
173 |
174 | All links found will be returned an array, with duplicate URLs removed. If no links
175 | are found, it will return an empty array.
176 |
177 | ```json
178 | [
179 | "http://example.com/1",
180 | "http://example.com/2"
181 | ]
182 | ```
183 |
184 | ### Custom User Agent
185 |
186 | You can set the user agent that this library uses when making HTTP requests.
187 |
188 | ```php
189 | IndieWeb\MentionClient::setUserAgent('Custom user agent string');
190 | ```
191 |
192 | At that point, any HTTP request (GET, HEAD, POST) that this library makes will include the user agent header you've set.
193 |
194 |
195 | ### Debugging
196 |
197 | If you want to collect debugging information so you can see the steps the library
198 | is doing, run `IndieWeb\MentionClient::enableDebug();` before calling any other function.
199 |
200 |
201 |
202 |
203 | About Webmention
204 | ----------------
205 |
206 | To learn more about Webmention, see [webmention.net](http://webmention.net).
207 |
208 | The [webmention.io](http://webmention.io/) service can also act as a pingback->webmention
209 | proxy which will allow you to accept pingbacks as if they were sent as webmentions.
210 |
211 |
212 | About Pingback
213 | --------------
214 |
215 | If you want to accept pingbacks on your site, check out [webmention.io](http://webmention.io/#use-it)
216 | which handles accepting the XMLRPC request and exposes the data via an API.
217 |
218 |
219 | License
220 | -------
221 |
222 | Copyright 2013-2017 by Aaron Parecki and contributors
223 |
224 | Available under the Apache 2.0 and MIT licenses.
225 |
226 | #### Apache 2.0
227 |
228 | Licensed under the Apache License, Version 2.0 (the "License");
229 | you may not use this file except in compliance with the License.
230 | You may obtain a copy of the License at
231 |
232 | http://www.apache.org/licenses/LICENSE-2.0
233 |
234 | Unless required by applicable law or agreed to in writing, software
235 | distributed under the License is distributed on an "AS IS" BASIS,
236 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
237 | See the License for the specific language governing permissions and
238 | limitations under the License.
239 |
240 | #### MIT
241 |
242 | Permission is hereby granted, free of charge, to any person obtaining a copy
243 | of this software and associated documentation files (the "Software"), to deal
244 | in the Software without restriction, including without limitation the rights
245 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
246 | copies of the Software, and to permit persons to whom the Software is
247 | furnished to do so, subject to the following conditions:
248 |
249 | The above copyright notice and this permission notice shall be included in all
250 | copies or substantial portions of the Software.
251 |
252 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
253 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
254 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
255 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
256 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
257 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
258 | SOFTWARE.
259 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "indieweb/mention-client",
3 | "description": "Client library for sending webmention and pingback notifications",
4 | "type": "library",
5 | "license": "Apache-2.0",
6 | "homepage": "https://github.com/indieweb/mention-client-php",
7 | "authors": [
8 | {
9 | "name": "Aaron Parecki",
10 | "email": "aaron@parecki.com",
11 | "homepage": "http://aaronparecki.com/"
12 | }
13 | ],
14 | "autoload": {
15 | "psr-0": {
16 | "IndieWeb": "src/"
17 | }
18 | },
19 | "minimum-stability": "dev",
20 | "require": {
21 | "php": ">=5.6",
22 | "mf2/mf2": ">=0.2"
23 | },
24 | "require-dev": {
25 | "phpunit/phpunit": "^6"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/coverage/clover.xml:
--------------------------------------------------------------------------------
1 |
2 |
Class | 57 |Coverage | 58 |
---|
Class | 73 |CRAP | 74 |
---|
Method | 110 |Coverage | 111 |
---|
Method | 126 |CRAP | 127 |
---|
33 | | Code Coverage |
34 | ||||||||
37 | | Lines |
38 | Functions and Methods |
39 | Classes and Traits |
40 | ||||||
Total | 45 |
46 |
50 |
49 | |
51 | 100.00% |
52 | 229 / 229 |
53 |
54 |
58 |
57 | |
59 | 100.00% |
60 | 18 / 18 |
61 |
62 |
66 |
65 | |
67 | 100.00% |
68 | 1 / 1 |
69 |
MentionClient.php | 73 |
74 |
78 |
77 | |
79 | 100.00% |
80 | 229 / 229 |
81 |
82 |
86 |
85 | |
87 | 100.00% |
88 | 18 / 18 |
89 |
90 |
94 |
93 | |
95 | 100.00% |
96 | 1 / 1 |
97 |
Hello World
No links here
'); 12 | $this->assertEquals(0, $total); 13 | } 14 | 15 | public function testFromURLWithNoLinks() { 16 | $total = $this->client->sendMentions('http://source.example.com/no-links.html'); 17 | $this->assertEquals(0, $total); 18 | } 19 | 20 | public function testFromURLWithTwoValidLinks() { 21 | $total = $this->client->sendMentions('http://source.example.com/two-valid-links.html'); 22 | $this->assertEquals(2, $total); 23 | } 24 | 25 | public function testFromURLWithOneValidAndOneInvalidLink() { 26 | $total = $this->client->sendMentions('http://source.example.com/mixed-success-links.html'); 27 | $this->assertEquals(1, $total); 28 | } 29 | 30 | public function testDoesNotSendToLinksOutsideHEntry() { 31 | $total = $this->client->sendMentions('http://source.example.com/send-to-h-entry-links.html'); 32 | $this->assertEquals(1, $total); 33 | } 34 | 35 | public function testPrioritizesWebmentionEndpointOverPingback() { 36 | $result = $this->client->sendFirstSupportedMention('http://source.example.com/example.html', 'http://target.example.com/header.html'); 37 | $this->assertEquals('webmention', $result); 38 | } 39 | 40 | public function testFindsPingbackEndpointBecauseNoWebmentionEndpoint() { 41 | $result = $this->client->sendFirstSupportedMention('http://source.example.com/example.html', 'http://target.example.com/only-pingback.html'); 42 | $this->assertEquals('pingback', $result); 43 | } 44 | 45 | public function testDoesNotSendPingbackDespiteWebmentionFail() { 46 | $result = $this->client->sendFirstSupportedMention('http://source.example.com/example.html', 'http://target.example.com/webmention-failed.html'); 47 | $this->assertEquals(false, $result); 48 | } 49 | 50 | public function testSendsFailingPingback() { 51 | $result = $this->client->sendFirstSupportedMention('http://source.example.com/example.html', 'http://target.example.com/pingback-failed.html'); 52 | $this->assertEquals(false, $result); 53 | } 54 | 55 | public function testSendsFailingWebmention() { 56 | $result = $this->client->sendFirstSupportedMention('http://source.example.com/example.html', 'http://target.example.com/webmention-only-failed.html'); 57 | $this->assertEquals(false, $result); 58 | } 59 | 60 | public function testSendsWebmentionAndWasCreated() { 61 | $result = $this->client->sendFirstSupportedMention('http://source.example.com/example.html', 'http://target.example.com/webmention-created.html'); 62 | $this->assertEquals('webmention', $result); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /tests/SendPingbackTest.php: -------------------------------------------------------------------------------- 1 | client = new IndieWeb\MentionClientTest(false, 'empty'); 8 | } 9 | 10 | public function testNot200Response() { 11 | $endpoint = 'http://pingback-endpoint.example/404-response'; 12 | $response = $this->client->sendPingbackToEndpoint($endpoint, 'source', 'target'); 13 | $this->assertFalse($response); 14 | } 15 | 16 | public function testInvalidXMLResponse() { 17 | $endpoint = 'http://pingback-endpoint.example/invalid-xmlrpc'; 18 | $response = $this->client->sendPingbackToEndpoint($endpoint, 'source', 'target'); 19 | $this->assertFalse($response); 20 | } 21 | 22 | public function testInvalidBodyResponse() { 23 | $endpoint = 'http://pingback-endpoint.example/invalid-body'; 24 | $response = $this->client->sendPingbackToEndpoint($endpoint, 'source', 'target'); 25 | $this->assertFalse($response); 26 | } 27 | 28 | public function testInvalidRequest() { 29 | $endpoint = 'http://pingback-endpoint.example/invalid-request'; 30 | $response = $this->client->sendPingbackToEndpoint($endpoint, 'source', 'target'); 31 | $this->assertFalse($response); 32 | } 33 | 34 | public function testEmptyBodyResponse() { 35 | $endpoint = 'http://pingback-endpoint.example/empty-body'; 36 | $response = $this->client->sendPingbackToEndpoint($endpoint, 'source', 'target'); 37 | $this->assertTrue($response); 38 | } 39 | 40 | public function testValidResponse() { 41 | $endpoint = 'http://pingback-endpoint.example/valid-response'; 42 | $response = $this->client->sendPingbackToEndpoint($endpoint, 'source', 'target'); 43 | $this->assertTrue($response); 44 | } 45 | 46 | public function testSendPingbackNoEndpoint() { 47 | $target = 'http://pingback-target.example/no-endpoint.html'; 48 | $result = $this->client->sendPingback('http://source.example.com/', $target); 49 | $this->assertFalse($result); 50 | } 51 | 52 | public function testSendPingbackHasValidEndpoint() { 53 | $target = 'http://pingback-target.example/has-valid-endpoint.html'; 54 | $result = $this->client->sendPingback('http://source.example.com/', $target); 55 | $this->assertTrue($result); 56 | } 57 | 58 | public function testSendPingbackHasErroringEndpoint() { 59 | $target = 'http://pingback-target.example/has-erroring-endpoint.html'; 60 | $result = $this->client->sendPingback('http://source.example.com/', $target); 61 | $this->assertFalse($result); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/SendWebmentionTest.php: -------------------------------------------------------------------------------- 1 | client = new IndieWeb\MentionClientTest(false, 'empty'); 8 | } 9 | 10 | public function testNot200Response() { 11 | $endpoint = 'http://webmention-endpoint.example/404-response'; 12 | $response = $this->client->sendWebmentionToEndpoint($endpoint, 'source', 'target'); 13 | $this->assertInternalType('array', $response); 14 | $this->assertEquals(404, $response['code']); 15 | } 16 | 17 | public function testInvalidRequest() { 18 | $endpoint = 'http://webmention-endpoint.example/invalid-request'; 19 | $response = $this->client->sendWebmentionToEndpoint($endpoint, 'source', 'target'); 20 | $this->assertInternalType('array', $response); 21 | $this->assertEquals(400, $response['code']); 22 | } 23 | 24 | public function testValidResponse() { 25 | $endpoint = 'http://webmention-endpoint.example/queued-response'; 26 | $response = $this->client->sendWebmentionToEndpoint($endpoint, 'source', 'target'); 27 | $this->assertInternalType('array', $response); 28 | $this->assertEquals(202, $response['code']); 29 | } 30 | 31 | public function testSendWebmentionNoEndpoint() { 32 | $target = 'http://webmention-target.example/no-endpoint.html'; 33 | $response = $this->client->sendWebmention('http://source.example.com/', $target); 34 | $this->assertFalse($response); 35 | } 36 | 37 | public function testSendWebmentionHasValidEndpoint() { 38 | $target = 'http://webmention-target.example/has-valid-endpoint.html'; 39 | $response = $this->client->sendWebmention('http://source.example.com/', $target); 40 | $this->assertEquals(202, $response['code']); 41 | } 42 | 43 | public function testSendWebmentionHasErroringEndpoint() { 44 | $target = 'http://webmention-target.example/has-erroring-endpoint.html'; 45 | $response = $this->client->sendWebmention('http://source.example.com/', $target); 46 | $this->assertEquals(500, $response['code']); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /tests/TagParserTest.php: -------------------------------------------------------------------------------- 1 | client = new IndieWeb\MentionClientTest(false, 'empty'); 8 | } 9 | 10 | public function testFindWebmentionTagRelWebmentionHref() { 11 | $html = ''; 12 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 13 | $this->assertEquals('http://example.com/webmention', $endpoint); 14 | } 15 | 16 | public function testFindWebmentionATagRelWebmentionHref() { 17 | $html = 'this site supports webmention'; 18 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 19 | $this->assertEquals('http://example.com/webmention', $endpoint); 20 | } 21 | 22 | public function testFindWebmentionATagRelSpaceBeforeWebmentionHref() { 23 | $html = 'this site supports webmention'; 24 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 25 | $this->assertEquals('http://example.com/webmention', $endpoint); 26 | } 27 | 28 | public function testFindWebmentionATagRelSpaceAfterWebmentionHref() { 29 | $html = 'this site supports webmention'; 30 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 31 | $this->assertEquals('http://example.com/webmention', $endpoint); 32 | } 33 | 34 | public function testFindWebmentionLinkTagRelSpaceAroundWebmentionHref() { 35 | $html = ''; 36 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 37 | $this->assertEquals('http://example.com/webmention', $endpoint); 38 | } 39 | 40 | public function testFindWebmentionTagHrefRelWebmention() { 41 | $html = ''; 42 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 43 | $this->assertEquals('http://example.com/webmention', $endpoint); 44 | } 45 | 46 | public function testFindWebmentionTagRelNoSlashHref() { 47 | $html = ''; 48 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 49 | $this->assertEquals('http://example.com/webmention', $endpoint); 50 | } 51 | 52 | public function testFindWebmentionTagHrefRelNoSlash() { 53 | $html = ''; 54 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 55 | $this->assertEquals('http://example.com/webmention', $endpoint); 56 | } 57 | 58 | public function testFindWebmentionTagRelHref() { 59 | $html = ''; 60 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 61 | $this->assertEquals('http://example.com/webmention', $endpoint); 62 | } 63 | 64 | public function testFindWebmentionTagHrefRel() { 65 | $html = ''; 66 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 67 | $this->assertEquals('http://example.com/webmention', $endpoint); 68 | } 69 | 70 | public function testFindWebmentionTagExtraWhitespace() { 71 | $html = ''; 72 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 73 | $this->assertEquals('http://example.com/webmention', $endpoint); 74 | } 75 | 76 | public function testFindWebmentionTagNoWhitespace() { 77 | $html = ''; 78 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 79 | $this->assertEquals('http://example.com/webmention', $endpoint); 80 | } 81 | 82 | public function testFindWebmentionTagNoCloseTag() { 83 | $html = ''; 84 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html); 85 | $this->assertEquals('http://example.com/webmention', $endpoint); 86 | } 87 | 88 | public function testFindWebmentionTagRelativeUrl() { 89 | $html = ''; 90 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html, 'http://example.com/post/1'); 91 | $this->assertEquals('http://example.com/webmention', $endpoint); 92 | } 93 | 94 | public function testFindWebmentionTagMultipleRels() { 95 | $html = ''; 96 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html, 'http://example.com/post/1'); 97 | $this->assertEquals('http://example.com/webmention', $endpoint); 98 | } 99 | 100 | public function testParseProtocolRelativeURL() { 101 | $html = ''; 102 | $endpoint = $this->client->_findWebmentionEndpointInHTML($html, 'https://example.com/post/1'); 103 | $this->assertEquals('https://example.com/webmention', $endpoint); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 9 |Hello World
9 | -------------------------------------------------------------------------------- /tests/data/pingback-target.example/has-valid-endpoint.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.0.14 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | X-Pingback: http://pingback-endpoint.example/valid-response 7 | 8 |Hello World
9 | -------------------------------------------------------------------------------- /tests/data/pingback-target.example/no-endpoint.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.0.14 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 |Hello World
8 | -------------------------------------------------------------------------------- /tests/data/source.example.com/mixed-success-links.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 |There are no links in this page
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/source.example.com/send-to-h-entry-links.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 |14 | two 15 |
16 |You can send me a webmention
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/data/target.example.com/body-link-org.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |You can send me a webmention
14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/data/target.example.com/body-link-org2.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |You can send me a webmention
14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/data/target.example.com/body-link.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |You can send me a webmention or pingback
14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/data/target.example.com/document-order-1.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 |You can send me a webmention or pingback
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/target.example.com/document-order-2.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 |You can send me a webmention or pingback
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/data/target.example.com/empty-string.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 |You can send me a webmention
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/target.example.com/false-endpoint-in-comment.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 |You can send me a webmention
13 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/data/target.example.com/header.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.0.14 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | Link:You can send a webmention or a pingback here
10 | -------------------------------------------------------------------------------- /tests/data/target.example.com/only-pingback.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 |You can send me a pingback
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/target.example.com/pingback-failed.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 |You can send me a pingback but it will fail
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/target.example.com/redirect.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 302 Found 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | Location: relative/after-redirect.html 7 | 8 | Redirecting... 9 | -------------------------------------------------------------------------------- /tests/data/target.example.com/relative/after-redirect.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.9.10 3 | Content-Type: text/html; charset=UTF-8 4 | Link:You can send me a webmention
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/target.example.com/webmention-failed.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |You can send me a webmention or pingback but the webmention will fail
14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/data/target.example.com/webmention-only-failed.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Apache 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 | 8 | 9 | 10 | 11 | 12 |You can send me a webmention but it will fail
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/target.example.com/webmention-rocks-test-1.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.9.10 3 | Date: Tue, 12 Apr 2016 02:05:15 GMT 4 | Content-Type: text/html; charset=UTF-8 5 | Content-Length: 14459 6 | Connection: keep-alive 7 | X-Powered-By: PHP/5.6.18-1+deb.sury.org~trusty+1 8 | Link: ; rel=webmention 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |Link
header. The URL is relative, so this will also test whether your discovery code properly resolves the relative URL.Link
header. The Webmention endpoint is listed as an absolute URL.<link>
tag in the document. The URL is relative, so this will also test whether your discovery code properly resolves the relative URL.<link>
tag in the document. The Webmention endpoint is listed as an absolute URL.<a>
tag in the body. The URL is relative, so this will also test whether your discovery code properly resolves the relative URL.<a>
tag in the body. The Webmention endpoint is listed as an absolute URL.LinK
". This helps you test whether you are handling HTTP header names in a case insensitive way.Link
header. Unlike tests #1 and #2, the rel value is quoted, since HTTP allows both rel="webmention"
and rel=webmention
for the Link header.Hello World
13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/data/webmention-target.example/has-valid-endpoint.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.0.14 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | Link:Hello World
9 | -------------------------------------------------------------------------------- /tests/data/webmention-target.example/no-endpoint.html: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.0.14 3 | Date: Wed, 09 Dec 2015 03:29:14 GMT 4 | Content-Type: text/html; charset=utf-8 5 | Connection: keep-alive 6 | 7 |Hello World
8 | --------------------------------------------------------------------------------