\def\ifhtx{\iffalse}    % Lines used only for the HTML version
\ifhtx
\else
\documentclass[12pt,notitlepage,onecolumn]{note}
\fi

%  TtH processing
\input{tthdefs_note}
\iftth
  \newcommand{\examplesize}{\normalsize}
  \newcommand{\dbreak}{}
  \newcommand{\dbreakd}{}
\else
  \newcommand{\examplesize}{\small}
  \newcommand{\dbreak}{\mbox{}\protect\\}
  \newcommand{\dbreakd}{\mbox{}\protect\\[-3ex]}
\fi
\ifx\pdftexversion\undefined
  \usepackage[dvips]{graphicx}
  \DeclareGraphicsExtensions{.eps,.ps}
  \usepackage[ps2pdf]{hyperref}
\else
  \usepackage[pdftex]{graphicx} %% graphics for pdftex (supports .pdf .jpg .png)
  \usepackage{epstopdf}         %% requires epstopdf
  \makeatletter
  \g@addto@macro\Gin@extensions{,.ps}
  \@namedef{Gin@rule@.ps}#1{{pdf}{.pdf}{`ps2pdf #1}}
  \makeatother
  \pdfadjustspacing=1
\fi

\title{SAMP Web Profile}
\author{Mark Taylor (m.b.taylor@bristol.ac.uk) \\
        Jonathan Fay (jfay@microsoft.com) \\
        Luigi Paioro (luigi@lambrate.inaf.it)}

\begin{document}

\iftth
  \tthmaketitle
\else
  \maketitle
\fi
{\small\verb|$Id$|}

\tableofcontents

\begin{abstract}
This note gives details of the proposed, experimental Web Profile for SAMP.
All items in this document are subject to change.
\end{abstract}

\section{Introduction}

The purpose of the SAMP Web Profile is to enable applications which run
inside a browser sandbox (HTML 5, Silverlight, Flash) to communicate 
with a running SAMP hub,
and hence with other SAMP-compatible applications, running either
on the desktop or in other parts of the browser.
Such ``web applications'' are for good reasons run in a 
``sandbox'', which under normal circumstances blocks access to
sensitive system resources, including I/O of local files and
network-based resources such as URLs other than those hosted at 
the same origin as the web application itself.  It also typically
does not provide the facility to run an externally accessible server.


\subsection{Overview and Comparison with Standard Profile}

The Web Profile is based on the Standard Profile \cite{ref:samp}, but with some 
modifications to the specification which allow clients to overcome
the limitations of the browser sandbox, in a way which still
permits user control over client access so that any compromise
of usual security measures can only take place with explicit user
authorization.

There are four main problems for a web-based SAMP client: hub discovery,
outward hub communication, inward hub communication and
use of third-party URLs.
These are solved in the Web Profile by use of a well-known port,
use of standard and de facto cross-origin access techniques
enabled only by explicit user agreement,
and reverse HTTP/``long poll'' techniques.


\subsubsection{Hub Discovery}

A Standard Profile SAMP client locates the Hub by reading a file at
a well-known location in the filesystem.  This file provides both
the HTTP endpoint at which the hub XML-RPC server is listening, and a
``secret'', a password which the client must present in order to
register.  The logic is that only those clients which have permission
to read the file (typically this means processes running with the
hub owner's access permissions) will be able to register.
A web client cannot access the local filesystem, so is unable to
read a file to discover the hub.

In the Web Profile, the hub HTTP server listens on a well-known port.
No secret string is required for registration.
Instead, when a client attempts to register, the Hub asks the
user for explicit permission for this registration, typically using
a popup dialogue box.  If the user does not grant this permission,
the registration attempt will fail.

For a web client to be able to access this well-known port at all,
the techniques discussed in the next section are required.


\subsubsection{Outward Communications}

In the Standard Profile, all hub communication is done using the HTTP-based
XML-RPC protocol \cite{ref:xmlrpc}, usually to a port on the local host.

This is problematic for web-based clients, since Cross-Origin policies
enforced by browsers restrict HTTP access under normal circumstances
to only servers at the {\em Origin}\/ domain, that is the one which
served the document hosting the client.  This excludes access to a
server on the host where the browser is running, which is where the
SAMP hub is likely to reside.

Since cross-origin access is a common requirement for web-based clients,
and it is not always in conflict with the security concerns of servers,
a number of mechanisms have been implemented in browser techonology
which allow a sandboxed client to talk to an HTTP server
which has explicitly opted in for such cross-domain communications.
The ones we consider here are:
\begin{itemize}
\item Cross-Origin Resource Sharing standard (W3C)
\item {\tt crossdomain.xml} resource (Flash)
\item {\tt clientaccesspolicy.xml} resource (Silverlight) 
\end{itemize}

The Web Profile's approach is to RECOMMEND that the hub HTTP server 
implements all of
these workarounds in the widest possible way, so that any web client which
takes any of these approaches to circumventing browser cross-origin 
safeguards has unrestricted access to the hub's HTTP server.
The belief is that cross-origin access to such an HTTP server 
from almost any browser is possible by using one or more client-side
technologies (more work needs to be done to establish exactly the
extent of this supposition, and to provide guidelines for implementors
to take advantage of it).


\subsubsection{Inward Communications}

All SAMP clients must be able to send messages to the Hub.
Optionally, a SAMP client may declare itself {\em Callable\/} - 
this means that it is able to receive messages from the Hub
(hence from other clients).  Whether a client needs to do this
depends on its purpose and capabilities; a client which simply
needs to send an image to another client (a common scenario for
browser-based applications) does not need to be callable, 
but one which wishes to receive images, or to keep
track of the other clients currently registered, does need to.

In the Standard Profile a client declares itself Callable by 
providing to the Hub an HTTP endpoint to which the Hub may make 
XML-RPC requests.  Thus, the client must itself run a publicly 
accessible HTTP server in order to be callable.
Running an HTTP server is typically not within the capabilities
of a browser-based application.

In the Web Profile, inward communications are effected by using
the ``Long Poll'' technique, in which the direction of HTTP communication
is reversed.  Instead of the client running a server which listens
for incoming messages from the Hub, the Hub maintains a queue
of messages destined for the client, and the client polls
the Hub to find out if any are available.  The client may
either make periodic short-timeout requests to the hub, or
make a long-timeout request which only returns if and when one
or more messages are available.


\subsubsection{Third-Party URLs}

Although it is not fundamental to the SAMP protocol itself, many 
SAMP MTypes are defined in such a way that a receiving client
must retrieve data from a URL external to the SAMP client-hub system in order
to act on them.  For instance the {\tt table.load.votable} message
has an argument named ``{\tt url}'', which contains the location of
the VOTable document which is to be loaded.  Such URLs may point
to the local filesystem, to a server run by the sending client,
or to some other web server internal or external to the host on
which the SAMP communications are taking place.  In any of these
cases, it is likely that a browser-based client will be blocked
by the browser's cross-origin policy from access to the content
of the resource in question.

The Web Profile therefore mandates that the Hub must provide to
registered clients a mechanism for translating arbitrary URLs
into cross-origin-accessible URLs with the same content as the
specified resource.  The obvious implementation for such a 
facility is for the hub to operate a proxy service which provides
the content of the external resources from its own HTTP server,
which is already required to provide cross-origin access.


\subsection{Security Considerations}
\label{sec:security}

Browsers implement cross-origin access policies in order to prevent
web-based clients from activity on a local host which presents 
a security risk, for instance read and write access to local files.
This means that, at least in principle, a user can visit a web page
without worrying about security issues in a way which is not the
case if they download an application to install and run outside
a browser.

The Web Profile relies on neutralising these security measures.
Although it only affects access to a single resource, the HTTP
server on which the SAMP hub resides, this is a serious matter,
since any client registered with the SAMP Hub has indirect access,
via exchange of SAMP messages with other clients, and also via
the Web Profile's URL translation service, to many resources
on the hub's host.  In fact it is probably safest to assume
that a registered client may be able to perform any action 
consistent with the system privileges of the user under whose
identity the Hub, or of any client connected to it, is running.

The crucial issue is that only {\em registered\/} SAMP clients are
able to perform potentially dangerous activities.  Although the hub's
HTTP server itself is open to access by any web client, only
a registered SAMP client can do anything useful with it
(with the exception of a denial of service attack, which sandboxed
web clients are capable of in any case).
So what the Web Profile does is to remove any effective access control
applied by the browser when a URL dereference is attempted, 
and to replace it with access control applied by the Hub,
and under usual circumstances deferred to the user via a popup dialogue,
when SAMP registration is attempted.

The effect of this from the user's point of view is very similar
to what they see when a signed Java applet is used to provide SAMP
functionality within web applications: a popup dialogue is posted,
which asks for the user's consent, which if accepted, allows the
web application unrestricted access to the local host.
The privacy technology (signed certificates) used by the signed applet
route is considerably more sophisticated than that described by the
Web Profile, but the actual level of security is in practice no greater,
since users of astronomical applications very rarely pay attention to
or understand the details of the signature certificate in use.


\section{Behaviour of the Web Profile Hub}

The Web Profile is based on one-way client$\rightarrow$hub XML-RPC 
communications, with the hub residing at a well-known port,
with some special measures for allowing cross-origin requests.
In most ways it resembles the Standard Profile, but there are some
differences.

\subsection{Data Type Mappings}

SAMP argument and return value data types are encoded into XML-RPC
exactly as for the Standard Profile \cite{ref:samp}.

\subsection{API Mappings}

The operation names in the SAMP hub API very nearly has a one to one
mapping with those in the Web Profile XML-RPC API.  The Web Profile
Hub API MUST be implemented as described in the main part of the
SAMP specification, with a number of REQUIRED adjustments.
These are summarised as follows, and described in more detail later.

\begin{enumerate}
\item The XML-RPC method names (i.e.\ the contents of the XML-RPC
      {\tt <methodName>} elements) are formed by prefixing
      the hub abstract API operation names with ``{\tt samp.webhub.}''.
      For brevity, this prefix is not written in the rest of this document,
      but it is to be understood on all hub API XML-RPC calls.
\item The {\tt register()} operation takes the following form:
      \begin{itemize}
      \item {\tt map reg-info = register(string app-name)}
      \end{itemize}
      The {\tt app-name} is a short string supplied by the registering
      application to indicate its identity.  This SHOULD be presented
      by the hub to the user when the user's consent is requested for
      registration.
\item The {\tt reg-info} map returned from the {\tt register} method
      MUST contain two entries additional to those mandated by the
      hub API:
      \begin{itemize}
      \item {\tt samp.private-key}: the value of this key is a string which
            identifies this registered client.
            This string SHOULD be difficult for third parties to guess.
      \item {\tt samp.url-translator}: the value of this key is a string
            which forms the base for a URL proxying service.
            See Section \ref{sec:urltrans}.
      \end{itemize}
\item {\em All\/} hub methods other than {\tt register}
      take the {\tt private-key} as their first argument,
      except where otherwise noted ({\tt ping}).
      For brevity, this argument is not written in the rest of this document,
      but it is to be understood on all hub API calls.
\item Two new methods are added to the hub API to support reversed callbacks
      (Section \ref{sec:callable}):
      \begin{itemize}
      \item {\tt void allowReverseCallbacks(string allow)}
      \item {\tt map pullCallbacks(string timeout)}
      \end{itemize}
\item Another new method is added to the hub API:
      \begin{itemize}
      \item {\tt void ping()}
      \end{itemize}
      This may be called by registered or unregistered applications
      (as a special case the {\tt private-key} argument may be omitted),
      and can be used to determine whether the hub is responding to requests.
      Any non-error return indicates that the hub is running.
\end{enumerate}

\subsection{Hub Server}
\label{sec:httpd}

Communications are from the client to the Hub, using the XML-RPC protocol
\cite{ref:xmlrpc}.
XML-RPC works using POSTs to an HTTP server.  The Web Profile hub HTTP
server resides on the well-known port 21012, 
so that clients know where to find it on the local host.
The XML-RPC endpoint for Web Profile requests
is at the root of that server, so that web clients can access it by
POSTing to the URL ``{\tt http://localhost:21012/}''.

In general, web clients operate inside a browser-enforced sandbox that
prevents them from accessing external resources, including HTTP-based ones
served from the local host.  However there are a number of
ways that an HTTP server can elect to permit access from browser-based
clients.  In order to be useful a Web Profile hub must implement at
least some of these.  A Web Profile hub SHOULD provide the widest
possible access from sandboxed clients, by implementing as many
cross-domain schemes as possible, in a way that allows any web-based
client to connect.  The RECOMMENDED ones are currently:
\begin{description}
\item[Cross-Origin Resource Sharing:]
CORS \cite{ref:cors} is a W3C standard which allows a hub 
to make use of the HTTP Origin header and related headers 
to grant access to clients originating in CORS-compliant browsers.
It forms part of the XmlHttpRequest Level 2
standard \cite{ref:xhrTwo},
which is implemented by Chrome v2.0+, Firefox v3.5+ and Safari v4.0+.
Microsoft's IE8+ implements CORS via its own non-standard XDomainRequest
object.
It is RECOMMENDED that Web Profile hubs use the techniques in the
CORS standard to permit both {\em simple\/} and {\em preflight\/}
requests from clients with any Origin.
\item[Flash cross-domain policy:] Adobe's Flash browser plugin makes
use of a resource named ``crossdomain.xml'', which, if present on
an external HTTP server, is taken to indicate willingness to serve
cross-domain requests \cite{ref:flash-crossdomain}.
This has emerged as something of a de facto standard, and the
crossdomain file is honoured by Silverlight and unsigned java
Applets/WebStart applications for Java v1.6.0\_10 and later
(\href{http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6676256}
      {Java bug \#6676256}).
A Web Profile hub can permit access to
cross-domain requests from Flash-based clients by serving a resource
named ``{\tt /crossdomain.xml}'' with a Content-Type header of
``{\tt text/x-cross-domain-policy}'' and content like:
{\footnotesize\begin{verbatim}
   <?xml version="1.0"?>
   <!DOCTYPE cross-domain-policy
             SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
   <cross-domain-policy>
     <site-control permitted-cross-domain-policies="all"/>
     <allow-access-from domain="*"/>
     <allow-http-request-headers-from domain="*" headers="*"/>
   </cross-domain-policy>
\end{verbatim}}
\item[Silverlight cross-domain policy:]
Microsoft's Silverlight environment will take note of Flash-style
{\tt crossdomain.xml} files, so the above measure ought to permit
Silverlight clients to access a compliant HTTP server.  However,
Silverlight has its own cross-domain policy mechanism,
\cite{ref:silverlight-crossdomain} so it is
RECOMMENDED to implement this as well.  This can be done by
serving a resource named ``{\tt /clientaccesspolicy.xml}''
with a Content-Type header of ``{\tt text/xml}'' and content like:
{\footnotesize\begin{verbatim}
   <?xml version="1.0"?>
   <access-policy>
     <cross-domain-access>
       <policy>
         <allow-from>
           <domain uri="http://*"/>
         </allow-from>
         <grant-to>
           <resource path="/" include-subpaths="true"/>
         </grant-to>
       </policy>
     </cross-domain-access>
   </access-policy>
\end{verbatim}}
\end{description}

As discussed in Section \ref{sec:security}, opening up the server to 
cross-domain requests in this way makes it imperative that
the ability to make HTTP requests {\it per se\/} is not a security risk.
This is true of the Web Profile, since only clients which have
registered, for which they need explicit user authorisation,
are able to use the hub HTTP server to perform potentially
sensitive activities.


\subsection{Registration}
\label{sec:registration}

In order to request registration with the Web Profile, a client needs
only to present an application name to the XML-RPC server, by invoking
the following XML-RPC method:
\begin{verbatim}
   map register(string appName)
\end{verbatim}
The Hub SHOULD then present the supplied {\tt appName}
along with other available relevant information to the user, 
and ask for explicit confirmation that this client is allowed to
register for SAMP communications.  The {\tt register} XML-RPC
request will not return until the user has responded.
This user interaction will typically be achieved using a 
popup dialogue window.
In the case of a long delay while the user deliberates this risks
an HTTP timeout, but users are not expected to take many minutes to
respond, so this is not considered a problem.

If the user accepts, the hub MUST return to the client 
a SAMP map with the following keys
in addition to those mandated by the SAMP standard:
\begin{description}
\item[{\tt samp.private-key}:]
     used as the first argument of all hub API XML-RPC calls
     (as for the Standard Profile)
\item[{\tt samp.url-translator}:]
     used as described in Section \ref{sec:urltrans}
\end{description}
If the user refuses, the hub MUST return to the client
an XML-RPC Fault, which SHOULD have a suitably explanatory
{\tt faultString}.

The following items of information about a client requesting registration
are available to the hub:
\begin{description}
\item[Supplied application name:]
      This is not really a security measure, since the application may
      lie about its name, but it gives the user an idea of who is asking.
\item[Host from which the request is received:]
      Under normal circumstances this will be the local host.
      If it is not, it is likely that the client is not running in
      a web browser.  It is RECOMMENDED that the hub automatically
      block requests from hosts other than the local host.
\item[Client Origin:]
      CORS requires the browser to pass information to the server about
      the Origin of the request, that is the (hostname, port, protocol)
      triple which supplied the web page in which the client is embedded
      \cite{ref:origin}.  This can be useful to give the user an idea
      whether the code is likely to be trustworthy.  Unfortunately,
      if the client is attempting access using one of the non-CORS routes
      (Flash or Silverlight mechanisms) this information is not present
      in the request.
\end{description}
These SHOULD be presented to the user to inform the decision about
whether to permit registration.

Since possession of a private key is all that is required for
web clients to perform potentially dangerous activities by means of
SAMP communications, the hub should take care that private keys are
not easy to guess, and that they are dispensed to clients only with
the explicit consent of a user who is aware of the consequences.


\subsection{Callable Clients}
\label{sec:callable}

In order to be able to receive communications (incoming messages and 
asynchronous message replies) {\em from\/} the hub, the Web Profile
provides for the client to be able to poll the hub server for any
messages which are ready for receipt.  In this way, such communications
are pulled by the client rather than being pushed by the hub, so that
no server component is required from the client.

Two hub methods are provided to implement this:
\begin{itemize}
\item {\tt void allowReverseCallbacks(string allow)}
\item {\tt list pullCallbacks(string timeout-secs)}
\end{itemize}
Both these methods, like the others in the interface are named with the
{\tt samp.webhub.} prefix and take the {\tt private-key} as an additional
first argument.

The {\tt allow} argument of {\tt allowReverseCallbacks} is a 
{\em SAMP boolean\/} (``0'' for false and any other for true), and
the {\tt timeout-secs} argument of {\tt pullCallbacks} is a {\em SAMP int}.

If a client wishes to poll for callbacks it MUST invoke
{\tt allowReverseCallbacks} with a true argument.  
If it wishes to cease polling it SHOULD invoke it with a false argument.
The client becomes {\em callable\/} only when it has invoked this
method with a true argument.

Having invoked {\tt allowReverseCallbacks} with a true argument,
the client SHOULD periodically invoke {\tt allowReverseCallbacks} whose
return value is return a {\tt list} of {\tt map}s giving the details of
any callbacks ready for dispatch to the client.
The {\tt timeout-secs} parameter is the maximum number of seconds the
client wishes to wait for a response.  When the method is called,
the hub SHOULD wait until at least one callback is available, and
at that point SHOULD return any pending callbacks.  If the length of time
exceeds the number of seconds given by the {\tt timeout-secs} argument,
the hub SHOULD return with an empty list of callbacks.
The hub MAY return with an empty list of callbacks before the
given timeout has elapsed, for instance if it reaches an internal
timeout limit.

The format of the returned value from {\tt pullCallbacks} is a {\tt list}
of elements each of which is a {\tt map} representing a callback 
corresponding to one of the methods in the SAMP client API.
Each of these callbacks is encoded as a {\tt map} with the
following REQUIRED keys:
\begin{description}
\item[{\tt samp.methodName}] ---
     The client API method name for the callback.
     Its value is a {\tt string} taking one of the values
     ``{\tt receiveNotification}'', ``{\tt receiveCall}'' or
     ``{\tt receiveResponse}''.
\item[{\tt samp.params}] ---
     A {\tt list} of the parameters taken by the client API method in
     question, as documented in the SAMP standard.
\end{description}
These items correspond to the elements present in an XML-RPC call.


\subsection{URL Translation}
\label{sec:urltrans}

In order that sandboxed clients are able to obtain the content of
URLs from foreign domains, as is often required by SAMP interoperation,
the hub provides a service which is able to dereference general URLs.

At registration time, as described in Section \ref{sec:registration},
one of the values provided to the registering client is that of the
{\tt samp.url-translator} key.  This is a partial URL which, when
another URL {\em u1\/} is appended to it, will return the same content as
{\em u1\/} from an HTTP GET request.  
If {\em u1} is a syntactically legal URL according to
RFC 2396 \cite{ref:rfc2396}, no additional encoding
needs to be performed on it by the client prior to the concatenation.

A sample of ECMAScript code using this facility might look something
like this:
\begin{verbatim}
   var url_trans = reg_info["samp.url-translator"];
   var u1 = msg["samp.params"]["url"];      // base URL received from message
   var u2 = url_trans + u1;                 // URL ready for retrieval
\end{verbatim}

The partial translator URL might typically be implemented as a URL
pointing to the same HTTP server in which the hub is hosted, and missing
its query part.  The content of URLs accessed in this way MUST be 
available under the same sandbox-friendly arrangements described
in Section \ref{sec:httpd}.  For security reasons the hub SHOULD ensure
that this facility can only be used by registered clients, for instance
by embedding the private key in the URL.  Thus a translator URL might
look something like
\begin{quote}
{\tt http://localhost:21012/translator}/{\sl client-private-key\/}{\tt ?}
\end{quote}

The URL translation service SHOULD in general write an HTTP response
with HTTP headers appropriate for the resource being served,
in accordance with the HTTP version in use (e.g.\ \cite{ref:rfc2616}).
Where the content type of
a resource is not known (which is typical if that resource is backed
by a file rather than an HTTP URI) the HTTP Content-Type header MAY
be omitted.

\section{Client Behaviour}

The steps that a client must take to register with a Web Profile hub and
participate in two-way SAMP communications are as follows:
\begin{enumerate}
\item Acquire a cross-domain capable HTTP client.
      Something based on Cross-Origin Resource Sharing 
      (W3C XMLHttpResource Level 2, Microsoft XDomainRequest, \ldots?)
      Adobe Flash
      (\href{http://flxhr.flensed.com/}{flXHR},
       \href{http://code.google.com/p/crossxhr/}{crossXHR} libraries)
      or Microsoft Silverlight are possibilities.
\item Prepare to make XML-RPC communications with the XML-RPC endpoint
      {\tt http://localhost:21012/}.
\item Call the {\tt register}
      XML-RPC method with a short application
      name as the sole argument.  
      If this succeeds (returns a non-Fault XML-RPC response),
      the client is registered.
\item If the client wishes to receive as well as send communications
      (to be {\em Callable\/}), first call
      {\tt allowReverseCallbacks} and then
      periodically call {\tt pullCallbacks}.
      Call {\tt declareSubscriptions} as required.
      Act on retrieved callbacks as appropriate.
\item Send SAMP messages etc as required.
\item Call {\tt unregister} - ensure that this is done on page unload
      or other similar events.
\end{enumerate}


\section*{Acknowledgements}

This work has been supported by Microsoft Research.


\begin{thebibliography}{99}
\bibitem{ref:samp} Simple Applications Messaging Protocol, IVOA,
    \\ \url{http://www.ivoa.net/Documents/latest/SAMP.html}
\bibitem{ref:xmlrpc} XML-RPC Remote Procedure Call prototol,
    \\ \url{http://www.xmlrpc.com/}
\bibitem{ref:cors} Cross-Origin Resource Sharing, W3C,
    \\ \url{http://www.w3.org/TR/cors/}
\bibitem{ref:xhrTwo} XmlHttpRequest Level 2, W3C,
    \\ \url{http://www.w3.org/TR/XMLHttpRequest2/}
\bibitem{ref:origin} The HTTP Origin Header, IETF (work in progress),
    \\ \url{http://tools.ietf.org/html/draft-abarth-origin-08}
\bibitem{ref:flash-crossdomain} Adobe Flash cross-domain policy,
    \\ \url{http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html}
\bibitem{ref:silverlight-crossdomain} Microsoft Silverlight cross-domain policy,
    \\ \url{http://msdn.microsoft.com/en-us/library/cc645032(VS.95).aspx}
\bibitem{ref:rfc2396} Uniform Resource Identifiers: Generic Syntax, IETF,
    \\ \href{http://www.ietf.org/rfc/rfc2396.txt}{RFC 2396}
\bibitem{ref:rfc2616} Hypertext Transfer Protocol --- HTTP/1.1, IETF,
    \\ \href{http://www.w3.org/Protocols/rfc2616/rfc2616.html}{RFC 2616}
\end{thebibliography}

\end{document}


