La procedura di pingback permette all'autore di un blog o di una pubblicazione web di ricevere un segnale di notifica, basato su una chiamata XML-RPC, quando un altro autore inserisce all'interno di una propria notizia o post, un collegamento ipertestuale (link) ad uno dei documenti del primo.
A questo punto il sistema di gestione dei contenuti che riceve la notifica, dopo aver effettuato una serie di controlli per evitare che il messaggio sia un tentativo di spam, registra i dati ad esso relativi in coda al post, generalmente nell'area dedicata ai commenti (se presente), e risponde all'host di provenienza con un altro messaggio XML-RPC contenente lo stato dell'operazione (successo o messaggio di errore).
Questa procedura presume che entrambe le piattaforme di gestione dei contenuti, quella che effettua la notifica (client) e quella che la riceve (server), siano abilitate alla gestione (invio, ricezione ed elaborazione) del protocollo di pingback. E' allo stesso tempo auspicabile che l'implementazione del sistema di gestione del pingback sia dotato di eventi di controllo che "filtrino" in maniera adeguata il contenuto della chiamata XML-RPC, per evitare l'introduzione di codice malevolo all'interno della pagina all'atto della registrazione dell'avvenuta notifica nella sezione dei commenti.
La chiamata XML-RPC ha un formato simile al seguente:
POST /xmlrpc.aspx HTTP/1.0
User-Agent: My user agent
Host: me.mydomain.com
Content-Type: text/xml
Content-length: 181
<?xml version="1.0"?>
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param>
<value><string>http://uri-di-provenienza</string></value>
</param>
<param>
<value><string>http://uri-destinazione</string></value>
</param>
</params>
</methodCall>
L'uri-di-provenienza e l'uri-destinazione contengono rispettivamente l'indirizzo assoluto della pagina contenente il collegamento al documento e l'indirizzo assoluto del documento stesso. Il server pingback, una volta ricevuta la chiamata dovrebbe effettuare i seguenti controlli:
- Verificare che l'uri-di-provenienza esista e sia valido, quindi che la pagina relativa a tale indirizzo contenga effettivamente un collegamento ipertestuale verso l'uri-destinazione e che questo sia ben formato (del tipo: <a href="http://uri-destinazione">...</a>)
- Verificare che l'uri-destinazione sia relativo ad una notizia o post valido all'interno del proprio archivio.
- Verificare che non sia stato effettuato in precedenza un pingback dall'uri-di-provenienza all'uri-di-destinazione e, di conseguenza, non sia già stato registrato.
- Registrare le informazioni essenziali all'individuazione del pingback nella sezione commenti dell'articolo o post di riferimento.
- Restituire un messaggio XML-RPC contenente lo stato finale dell'operazione
Una delle fasi più delicate è quella di acquisizione ed analisi della pagina indirizzata dall'uri-di-provenienza: non esiste infatti alcuna regola che indichi quali siano i dati da estrarre e poi da registrare come commento di pingback. Una buona pratica è quella di registrare il titolo della pagina ed il nome del sito di provenienza come testo del commento, magari includendo anche la dicitura pingback per indicare l'avvenuto automatismo (es: "NomeDelBlog" ha effettuato un pingback nel post "TitoloDelPost"). L'autore del commento si attribuisce indicando il nome del sito di provenienza (linkato al post medesimo).
Poichè alcune di queste informazioni non sono inviate mediante la chiamata XML-RPC dall'applicazione client, è compito dell'applicazione server ricavarle mediante una webrequest all'uri-di-provenienza. Un esempio di codice VB che effettua tale operazione potrebbe essere:
Function GetHtmlPageSource(ByVal sURI As String) As String
Dim st As System.IO.Stream
Dim sr As System.IO.StreamReader
Try
' Web request
Dim req As System.Net.WebRequest = _
System.Net.WebRequest.Create(sURI)
' risposta e lettura del flusso in ingresso
Dim resp As System.Net.WebResponse = _
req.GetResponse
st = resp.GetResponseStream
sr = New System.IO.StreamReader(st)
Return sr.ReadToEnd
Catch ex As Exception
Return ""
Finally
sr.Close()
st.Close()
End Try
End Function
La funzione GetHtmlSource richiede in ingresso l'indirizzo html assoluto della pagina che si vuole analizzare e ne restituisce il sorgente sotto forma di stringa di testo; in caso di errore restituisce una stringa nulla. Ottenuto il codice della pagina, utilizzando le regular expression per isolare la coppia di tag <title> ... </title>, è possibile estrarne il titolo che andra registrato come parte del testo del commento. Contestualmente è possibile verificare l'esistenza dell'uri-di-provenienza e la presenza del link al post a cui è stato fatto il pingback.
Public Function CheckForURL(ByVal sURI As String, ByVal tURI As String, ByRef pageTitle As String) As String
Try
Dim page As String = GetHtmlPageSource(sURI)
If (page.Trim = "") Or (page.IndexOf(tURI) < 0) Then
Return "0"
Else
Dim pat As String =_
"<head.*?>.*<title.*?>(.*)</title.*?>.*</head.*?>"
Dim reg As Regex = New Regex(pat, _
RegexOptions.IgnoreCase Or RegexOptions.Singleline)
Dim m As Match = reg.Match(page)
If m.Success Then
pageTitle = m.Result("$1")
Return pageTitle
End If
End If
Catch ex As Exception
Return "0"
End Try
Return pageTitle
End Function
La funzione CheckForUrl richiede in ingresso l'indirizzo di provenienza (sURI), l'indirizzo di destinazione o pingback (tURI) e restituisce il titolo della pagina (la stessa stringa viene restituita anche mediante il parametro pageTitle). A questo punto sono disponibili tutti i dati necessari per la registrazione del commento di pingback: in realtà la stringa contenente il titolo del post deve essere ulteriormente bonificata dall'eventuale presenza di tag html. Generalmente il titolo, per essere ben formato, non dovrebbe contenere alcun tag ma, in alcuni casi di spam o di attacco all'host di destinazione, vi si potrebbero celare degli script contenenti codice malevolo. Per prevenire una simile eventualità si può ricorrere, sempre mediante l'uso delle regular expression ad una semplice funzione filtro come la seguente:
Public Function RemoveTag(byVal sSource as String) as String
Dim reg As Regex = New Regex( "<[^>]*>", _
RegexOptions.IgnoreCase Or RegexOptions.Singleline)
Return RegEx.Replace(sSource, "")
End Function
In questo modo si eliminano tutti i tag, tra i quali anche l'eventuale presenza di coppie di tag <script> ... </script> che potrebbero contenere o delimitare della aree di codice javascript potenzialmente pericoloso. Tale funzione non elimina intenzionalmente il testo racchiuso tra i tag per consentire all'amministratore del sito di rilevare, visionando il testo del commento una volta registrato, un eventuale tentativo di spam o di attacco: infatti il codice javascript non viene eseguito dal client se non è racchiuso tra i tag che lo identificano, e viene interpretato come un innocuo frammento di testo.
Questa trattazione ha valore puramente accademico e non vuole costituire nè un sistema completo di gestione della procedura di pingback nè una proposta definitiva per l'eliminazione dei rischi dovuti all'aquisizione di codice potenzialmente pericoloso: per informazioni più dettagliate è possibile fare riferimento alle specifiche originali di questo protocollo come definite da Stuart Langridge e Ian Hickson, o alla loro traduzione non ufficiale in lingua italiana.