Browse Host Extension

From Gnutella Developers

<< Link Compression Extension | Magnet URI Extension >> | Main Page

At a high level, the protocol manages the exchange of binary Query Replies through the HTTP protocol used for Uploads and Downloads.

Here are the details about the standard:

1. Advertising Browse Host through GGEP

'Browse Host' capable clients notify others of this feature via GGEP.

The new extension ID for Browse Host is 'BH' (subject to approval) and 'Browse Host' capable clients should add a corresponding extension header to all Query Replies. There is no need for any extension data.

In the future, this may be extended to allow more depth in the description of Browse Host capabilities (via a non-empty extension data field), i.e. "text/html" or "binary QR". For now, simply having a GGEP ext. ID (and no data) is sufficient because different 'Browse Host' implementations are resolved via the 'Accept' HTTP header flag (see below for more detail).

2. The HTTP-based Browse Host Protocol

2.1. The Protocol

A Browse Host request will be satisfied through an HTTP GET request. The request will list media types that are acceptable as a return value (via the 'Accept' request header field, RFC 1945, pg. 59). The request lists these media types with a empty-string valued GET.

For example, here is a sample Browse Host HTTP request:

 Client (LimeWire)
 -------------------------
 GET / HTTP/1.1<CR><LF>
 Host: w.x.y.z<CR><LF>
 User-Agent: Limewire x.y.z Pro<CR><LF>
 Accept: text/html, application/x-gnutella-packets<CR><LF>
 Connection: close<CR><LF>
 <CR><LF>

     Server (New BearShare)
     -------------------------
     HTTP/1.1 200 OK<CR><LF>
     Server: BearShare/x.y<CR><LF>
     Content-Type: text/html; charset=iso-8859-1<CR><LF>
     Connection: close<CR><LF>
     <CR><LF>
     <HTML><HEAD>
       <TITLE>Sample HTML page.</TITLE>
     </HEAD><BODY>
       <H1>List of shared files on w.x.y.z.</H1>
       <P>Some filenames and links...</P>
     </BODY></HTML>

 Client (closes the session)
 ---------------------------

In this example above, LimeWire wants to browse a BearShare and it accepts responses with media types "text/html" and "application/x-gnutella-packets". The BearShare supports "text/html" only. Therefore it returns a OK indicating that responses will be sent back as html (the HTML will immediately follow the HTTP OK Response). Requesting the root "/" in the GET request is translated into an Browse Host request.

The server's IP and port can be retrieved via the standard route, ie a Query Reply.

As can be seen, servers reply back with the media type that will be returned - the standard response media type is "application/x-gnutella-packets". This media type implies that a stream of binary Query Replies describing the shared files of the responding servent will be returned.

The "text/html" media type is featured in BearShare clients. Bearshare has had the browse host feature for some time now. The "text/html" media type simply sends back a HTML page listing the servent's files. This media type lacks several important features, such as reporting file size. It is recommended that all implementations use the "application/x-gnutella-packets" media type as their default but implement "text/html" reception (to be compatible with older BearShare's). Minimally, all implementation must support the "application/x-gnutella-packets" media type for output while being browsed. The GUID of the query replies sent back for a "application/x-gnutella-packets" Browse Host request can be determined arbritrarily by the Server.

Other media types will be followed by different responses, as necessary.

A server may compress the results of a Browse Host query. First, the server should confirm that the client accepts the compressed encoding, ie "deflate". This can be communicated by the client through use of the HTTP 'Accept-Encoding' header and by the server's use of the HTTP 'Content-Encoding' header. For example:

 Client (LimeWire)
 -------------------------
 GET / HTTP/1.1<CR><LF>
 Host: w.x.y.z<CR><LF>
 User-Agent: Limewire x.y.z Pro<CR><LF>
 Accept: text/html, application/x-gnutella-packets<CR><LF>
 Accept-Encoding: deflate<CR><LF>
 Connection: close<CR><LF>
 <CR><LF>

     Server (New BearShare)
     -------------------------
     HTTP/1.1 200 OK<CR><LF>
     Server: BearShare/x.y<CR><LF>
     Content-Type: text/html; charset=iso-8859-1<CR><LF>
     Content-Encoding: deflate<CR><LF>
     Connection: close<CR><LF>
     <CR><LF>
     Deflated (binary) HTML content...

 Client (closes the session)
 -------------------------

2.2. Error Cases

If a servent cannot respond to any of the requested media types, an HTTP error message is returned. For example:

 Client (Old BearShare)
 -------------------------
 GET / HTTP/1.0<CR><LF>
 Accept:text/html<CR><LF>
 <CR><LF>

     Server (LimeWire)
     -------------------------
     HTTP/1.1 406 Not Acceptable<CR><LF>
     Content-Type: text/html<CR><LF>
     Connection: close<CR><LF>
     <CR><LF>

 Client (closes the session)
 ---------------------------

Old BearShare's only support text/html and LimeWire does not, so a 406 is returned (This is a example only).

2.3. Servent Specific Behavior

A servent may impose whatever limitations on responding to Browse Host requests that they see fit, such as Upload Slot and Bandwidth Usage limitations.

It is recommended that Upload Slot limitations are not enforced for the majority of clients though (A client sharing a large number of files may want to limit 'Browse Host' requests).

3. Browse Host through Pushes

Pushes are also supported. A Push is routed in the normal fashion (a la Push Requests). The Push Request can technically have any index.

The GIV message (sent from the server to the client requesting a browse host) is the same. The Server should connect back to the client regardless of the value of the index - what is most important is the <servent-identifier> (the server's guid), which is used by the client to match up the appropriate state.

For example, in response to the PushRequest, the following transaction takes place:

 Server (just connected to Client)
 -------------------------
 GIV 4141414141:<servent-identifier>/<CR><LF>

     Client (noting the servent-identifier)
     -------------------------
     GET / HTTP/1.1<CR><LF>
     Host: w.x.y.z<CR><LF>
     User-Agent: Limewire x.y.z Pro<CR><LF>
     Accept: text/html, application/x-gnutella-packets<CR><LF>
     Connection: close<CR><LF>
     <CR><LF>

 Server
 -------------------------
 HTTP/1.1 200 OK<CR><LF>
 Server: BearShare/x.y<CR><LF>
 Content-Type: text/html; charset=iso-8859-1<CR><LF>
 Connection: close<CR><LF>
 <CR><LF>
 <HTML>...Some HTML content...</HTML>

     Client (closes the session)
     -------------------------

4. Protocol Advantages

This scheme has the following advantages:

  1. It works seamlessly with all existing BearShares. This flexibility also allows clients to create custom media type standards if they wish, while still allowing for inter-vendor browsing.
  2. No new message format is needed - pre-existing infrastructure is special cased and the HTTP protocol is leveraged.
  3. As a consequence of (2), Browse Host works through Pushes.

<< Link Compression Extension | Magnet URI Extension >> | Main Page