From: Dean M. B. <mik...@gm...> - 2008-08-28 01:32:33
|
Hi Glyn, On Wed, Aug 27, 2008 at 8:44 PM, Glyn Matthews <gly...@gm...> wrote: > Hello, > > > I have some questions about the way HTTP requests are made using the current > interface, specifically this (taken from the http_1_0_test.cpp): > > using namespace boost::network; > http::request request("http://www.boost.org/"); > http::client client_; > http::response response_; > response_ = client_.get(request); > > > What exactly is the role of the client here? I'm a little confused by the > syntax because it reads as though you're trying to make a get request to an > HTTP client. Would it perhaps be better to rename http::client to > http::connection? > I haven't given this much thought, but now that you mention it, the idea of client.get(...) Is to instruct the client instance to perform a get(...) given a request instance. So it's like "sending a get(...) message to the client instance". > Secondly, why is the domain passed as an argument to the http::request > constructor? To me, this doesn't feel like the right unit of encapsulation. > Right. In other network libraries (like in Windows' MFC/ATL) there is a separation between the 'transport' or 'connection' and the individual resources or URI's that you access given certain transports. (see more below) > Does the following example code make more sense? > > using namespace boost::network; > http::connection c("http://www.boost.org"); > http::request request1("/users/news/version_1_36_0"); > http::response response1 = c.get(request); > http::request request2("/cgi-bin/path"); > request2 << body("post_body"); > http::response response2 = c.post(request2); > > Two observations about this: > The current implementation creates a new socket for each request that is > made, whereas the above suggestion allows a socket to remain open for > multiple requests. Additionally, the URI processing is currently done > inside the request constructor. I think it would be better to re-factor > this into a separate package. > The current implementation is an HTTP 1.0 client, which by design creates a single connection for every request. This is the reason why the request line puts HTTP/1.0 instead of HTTP/1.1; In HTTP 1.1, the client can keep a connection open and make multiple requests using the same connection (this is referred to as persistent connections, and with this the possibility of request pipelining). What I would be inclined to support is something of a request builder implementation, which allows for example: http::request::builder builder("http", "www.boost.org"); http::request r1 = builder.create("/"); http::request r2 = builder.create("/some_uri?param1=value"); http::request r3 = builder.create("/login.php", "username=user&password=password"); http::client client; http::response response = client.get(r1); The idea here is that we should be able to encapsulate the connection-mapping logic in the client between domains and actual sockets. That means, inside the client, it may be able to hold on to existing connections (in HTTP 1.1 clients) and then perform the correct actions. The aim of the interface is to convey that: - the client knows how to handle the connections so you don't have to worry about it - the request object as far as you are concerned is the base unit of data you can use to instruct the client what to do - you can craft any http::request and use it with any instance of the client without necessarily binding the client to a single destination/connection If it helps, you can think of an http::client object as an encapsulated browser of sorts, which can perform well-crafted requests on the users' behalf. This breaks the existing conventions on how HTTP clients look like and behave -- and existing library designs. I personally think this is a good thing, because we're doing it from scratch anyway. ;) Besides, it makes things easier for developers (I think) because it allows a more consistent way of thinking about crafting HTTP requests and asking a client to perform a request on their behalf -- as compared to being encumbered with the notion that an http::connection is bound to a certain destination and that a request object is associated with a URI instead of being a fully-encapsulated HTTP request. > Any thoughts? I think so. ;-) See above? :-D HTH -- Dean Michael C. Berris Software Engineer, Friendster, Inc. |