Table of contents

  1. Introduction
  2. Server Status Codes
    1. 401 Unauthorized
    2. 403 Forbidden
  3. Server Responses
    1. Server Response Headers
    2. Server Redirect Fields
  4. Client Requests
    1. Ajax request via CORS
    2. Form Submit
  5. Security
  6. The Complete Flow
  7. Example Code
    1. JQuery JavaScript
    2. PHP

Introduction

The Pingback specification currently covers mainly the use case without authentication. To avoid complex authentication delegation only Ajax requests via CORS and form post request are covered in this document. With enabled authentication the source value is no longer required. The endpoint fills the source value with the authenticated agent.

Server Status Codes

Beside the success codes we also have to define the behavior for two error codes.

401 Unauthorized

The client didn't send the required authentication via Ajax or the supported authentication mechanisms don't support Ajax.

403 Forbidden

Authentication was successful but the endpoint doesn't allow Pingbacks with the given source or target agent.

Server Status Codes

Beside the success codes we also have to define the behavior for two error codes.

Server Response Headers

The server must send all required header fields defined by the CORS specification. The "Access-Control-Allow-Origin" field must contain the "Origin" request header field value as some browsers don't support post requests with the "*" wildcard. "Access-Control-Allow-Credentials" must contain "true" to support authentication. To enable the "Accept-Authentication" client header field [2] the "Access-Control-Allow-Headers" must be used.

Here an example:

Access-Control-Allow-Origin: https://www.example.org
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Accept-Authentication

Server Redirect Fields

If the client has send a "redirect_uri" data field the server must redirect after the client to the defined URI, after process the Pingback request. If an error has occurred the "error" field must be used to transfer the status code to the origin. Optional the "error_description" field can be used to describe the error more detailed.

Client Requests

Beside the success codes we also have to define the behavior for two error codes.

Ajax request via CORS

To allow authentication, the "withCredentials" properties must be set to true. Additional the "Accept-Authentication" can be used to tell the server which authentication mechanism the clients supports.

Form Submit

Also a form with the action pointing to the Pingback service can be used. Authentications with page flows must use this method. Additional to the fields defined by the Pingback spec a "redirect_uri" field must be given. The Pingback service must redirect after a successful or failed Pingback to this URI.

Security

A Pingback request must not be used to share data beside the triples defined by the Pingback specification. The response of the Pingback Ajax request via CORS must not contain any additional personalized data of the authenticated user. A CORS request can be detected by cheching the Origin HTTP Header Field.

For example if the request asks for HTML content and by default the page shows the foaf:name property of the user, in the Pingback use case this information must not be shown.

The Complete Flow

First the client should try to use a Ajax request with CORS. If the server returns the unauthorized status code the client should fallback to the form submit method. If JavaScript is disabled the server should show only the form submit method.

Example Code

JQuery JavaScript

pingback.Request.prototype.send = function(to, options) {
	var successCallback = (options['success'] !== undefined) ? options.success : function() {};
	var errorCallback = (options['error'] !== undefined) ? options.error : function() {};

	var data = {};

	if(this.source() != null)
		data.source = this.source();

	if(this.target() != null)
		data.target = this.target();

	if(this.comment() != null)
		data.comment = this.comment();

	var pingbackRequest = this;

	jQuery.support.cors = true;

	$.ajax({
			url: to,
			type: "POST",
			xhrFields: { withCredentials: true },
			data: data,
			headers: { 'Accept-Authentication': "WebID" },
			success: function(data, textStatus, jqXHR) { successCallback(); },
			error: function(jqXHR, textStatus, errorThrown) {
				if($.browser.msie) {
					if(errorThrown.number == -2147024891)
						pingbackRequest.sendFormSubmit(to);
					else
						errorCallback();
				} else {
					if(errorThrown != "Forbidden")
						pingbackRequest.sendFormSubmit(to);
					else
						errorCallback();
				}
			}
	});
};

pingback.Request.prototype.sendFormSubmit = function(to) {
	var html = '<form id="pingback-form" action="' + to + '" method="POST">';

	if(this.source() != null)
		html += '<input type="hidden" name="source" value"' + this.source() + '" />';

	if(this.target() != null)
		html += '<input type="hidden" name="target" value"' + this.target() + '" />';

	if(this.comment() != null)
		html += '<input type="hidden" name="comment" value"' + this.comment() + '" />';

	html += '</form>';

	$("body").append(html);
	$("#pingback-form").submit();
};

PHP

A. References

Pingback
Pingback at the W3C Wiki
Pingback Namespace
Friending on the Social Web
CORS
Cross-Origin Resource Sharing