3 This directory contains the HTTP Tunneling, Bidirectional, Protocol
4 implementation. This is a new streaming abstraction layered over an
5 HTTP document request/reply mechanism. It is designed to allow clients
6 that are inside a of a corporate firewall to communicate with servers
7 that are outside, hence HTTP Tunneling. Also, once a connection is
8 established, the outside peer is able to send asynchronous messages to
9 the inside peer, hence Bidirectional.
11 HTBP provides Acceptor, Connector, and Stream classes that follow the
12 interface defined for the ACE_Acceptor and ACE_Connector
13 templates. This means that HTBP can be used right away with
14 applications designed to use these templates.
16 Bidirectionality is achieved in the context of the proxy's restriction
17 by using two channels between the peers. One channel is defined for
18 data flow from the inside to the outside, data flow from the outside
19 in occurs on the other channel. In-to-out data is passed in the form
20 of a PUT command with the data payload marshalled into an
21 "application/gzip" buffer. On this channel, the outside peer always
22 responds with a simple document which serves as an ack. On the
23 out-to-in channel, the inside client must send a token request in the
24 form of a GET command. This request goes unfulfilled until the outside
25 peer has data to send, which it does by supplying an HTML document
26 that again encapsulates the data so that it may pass through the proxy
29 The connections from the inside peer to the proxy, or from the proxy
30 to the outside peer may be closed by the proxy at any time. The inside
31 peer will automatically reconnect as needed when this happens. Since
32 the outside peer cannot actively connect to the proxy, it will queue
33 outbound messages as long as it can until a new out-to-in channel is
34 made available, at which time it will flush its queue. The sense of
35 channels may change over time, as the proxy may choose any local
36 connection to the server to send any request (GET or POST).
38 The outside peer is identified using an ordinary INET addr, however
39 the inside peer uses a simple, transient unique ID to identify
40 itself. Inside peers will never have any type of persistent identity.
41 The unique ID used to identify the inside peer is usually a UUID value
42 as composed by ACE_UUID_Generator. However, a domain based unique ID
43 may also be obtainedusing HTBP::ID_Requestor::get_HTID(). If no domain
44 based ID generator is configured, get_HTID() will return a UUID value.
46 As there are a variety of HTTP proxies available, HTBP uses a
47 pluggable filter class that defines the particular characteristics of
48 a proxy and is responsible for marshalling and unmarshalling binary
49 data. As of now there is a single filter available that works with a
50 defaulted Squid proxy and may also be used as a null filter, directly
51 connecting the inside and outside peers. This mode is useful for
55 This is done through the ACE_Configuration framework. On windows
56 platforms, the Windows Registry may be used, whereas on non-windows, a
57 flat file is used to configure. Configuration data may also be
58 persisted in a memory mapped file.
60 The configuration map contains a single section, HTBP, that contains
61 all the configurable parameters in name=value form. The following is
62 an example of a configuration file:
65 proxy_host=<hostname> This is the hostname of the http
66 proxy through which all requests
68 proxy_port=<port> This is the proxy's port.
69 htid_url=<url> If a domain based unique id is
70 required, this is the URL of the
72 htid_via_proxy=<1|0> If the htid_url must be reached
73 via the proxy, set this to 1.
74 Default is 0, meaning the ID
75 generator is directly accessible.
77 COMPANION DIRECTORIES:
78 $ACE_ROOT/tests/HTBP. These are the test drivers, which
79 also serve as example code.
80 $TAO_ROOT/orbsvcs/orbsvcs/HTIOP This is a TAO pluggable protocol
82 $TAO_ROOT/orbsvcs/tests/HTIOP The tests for HTIOP.
85 BACKGROUND INFORMATION
89 The class HT_Addr is a subclass of ACE_INET_Addr class. The interface
90 for the HT_Addr is a common interface to be used with the inside and
91 outside peers. The inside peer is identified by a HTID while the
92 outside peer is identified with an ip address. Constructors are
93 provided to initialize the inside and outside peers in addition to the
94 default and copy constructors. addr_to_string and string_to_addr
95 methods from the base class are overridden to help convert the HT_Addr
96 to a string and vice versa. Finally, the class provides accessor
97 methods for the default local address and the default proxy addresses.
99 The local address is the address of the inside peer and is obtained
100 using the singleton HTID_Requestor class. The HTID_Requestor class
101 sends a request to the web server that is running at the htid_url to
102 get the HTID unique to each inside peer.
104 The proxy address is of ACE_INET_Addr type as it is no different to a
105 regular server. It is obtained using the singleton HT_Environment
106 class. The HT_Environment class helps read the HT configuration file
107 and provides acccessors to the proxy address, port and the htid url.
109 The code below illustrates the initialization of a local or inside,
110 remote or outside and the proxy addresses using the classes
113 HT_Addr local(HTID_REQUESTOR::instance()->get_HTID());
115 char hostname [1000];
116 if (ACE_OS::hostname (hostname,
119 ACE_DEBUG ((LM_DEBUG, "Could not get the host name\n"));
123 HT_Addr remote (8088, hostname);
125 char proxy_address [1000];
126 HT_ENVIRONMENT::instance ()->get_proxy_address (proxy_address);
128 unsigned int proxy_port;
129 HT_ENVIRONMENT::instance ()->get_proxy_port (proxy_port);
131 ACE_INET_Addr proxy(port, proxy_address);
136 The class HT_Stream is a sibling of the ACE_SOCK_IO class. It is used
137 to send and receive messages between two peers identified by their HT
138 addresses. It is made a sibling of the ACE_SOCK_IO class rather than
139 a decendant. This is due to the requirement in the HTBP protocol to
140 wrap all messages with an HTTP request or reply wrapper, and to send
141 application data in only one direction on one stream.
145 A session is an entity that combines two HT_Streams that connect
146 directly to a proxy to manage communication with a remote peer. The
147 session may persist longer than either stream, assuming that the proxy
148 is libel to close a connection at any time. This means that the
149 session needs to be able to reconnect to the remote peer. This also
150 means that the session needs to be aware of its location. If it is
151 outside the proxy and looses a stream, nothing can really be done. If
152 it is inside, then the next time a stream is required, then it must
153 reconnect before returning the stream. The session does not queue
154 outbound messages. It will be the responsibility of the application or
155 a higher level protocol wrapper.
157 Each session is identified by a special type,
158 HT_Session_Id_t. HT_Session_Id_t is a class with three members, the
159 local address, the peer address and an id of type ACE_UINT32. A
162 Besides the default constructor and copy constructors, two other
163 constructors are provided to initialize a session and are shown below.
166 /// Constructor (sets the underlying session id with <sid>).
167 HT_Session (const HT_Addr& peer,
168 const HT_Addr& local = HT_Addr::default_local(),
170 ACE_INET_Addr *proxy = 0,
173 HT_Session (const HT_Session_Id_t &id,
174 ACE_INET_Addr *proxy = 0,
179 If a session id (sid) is not provided by the user, it is generated
180 using the static method HT_Session::next_session_id().
182 The following code illustrates the usage of HT_Stream and HT_Session