Boost logo

Boost :

Subject: Re: [boost] [asio-users] [http] Formal review of Boost.Http
From: Lee Clagett (forum_at_[hidden])
Date: 2015-08-09 16:46:57


On Sun, Aug 9, 2015 at 6:24 AM, Vinícius dos Santos Oliveira <
vini.ipsmaker_at_[hidden]> wrote:

> 2015-08-08 16:36 GMT-03:00 Lee Clagett <forum_at_[hidden]>:
>
> > [...] The problem is the lack of composability. If a different
> > http::Socket concept is desired (someone not using ASIO, etc.), then the
> > http::ServerSocket concept has to be re-implemented also since there is
> no
> > other implementation.
> >
>
> Exactly.
>
> The obvious way is to achieve composability is to use inheritance with:
> > `http::basic_server_socket<Socket>` where `Socket` is a http::Socket
> > concept. Inheritance in this situation has its drawbacks, for sure (a
> > virtual destructor should be considered).
> >
>
> I don't know. The only place that I see that can be abstracted among all
> alternative http backends is management of read_state and write_state and
> some auxiliary functions to check user intent (close connection...). The
> auxiliary functions can be provided without a base class and the read_state
> and write_state code is too little to convince me it's worth.
>
> http::SocketServer implementations manipulate the state of the http::Socket
> > (and indirectly the asio::tcp::socket), making some actions unavailable
> > after invoking those functions. For example, after invoking
> > `async_write_response`, no writes on the http::Socket/http::ServerSocket
> or
> > asio::ip::tcp::socket can occur until the callback is invoked because it
> > calls asio::write on the asio::ip::tcp::socket directly. So unless I am
> > incorrect, it is important for the users to know whats being manipulated
> > (the effects).
> >
>
> The documentation points the use of composed operations:
> https://boostgsoc14.github.io/boost.http/reference/basic_socket.html
>
> It's akin to Asio documentation on composed operations:
>
> http://www.boost.org/doc/libs/1_58_0/doc/html/boost_asio/reference/async_write/overload1.html
> (i.e. "the stream performs no other [...] until this operation completes")
>
> But now that you mentioned, I see that documentation can receive some
> improvements on the topic. The ServerSocket concept doesn't mention that
> some models can make use of this restriction nor there is any trait to
> detect if a model makes use of composed operations.
>
> The http::ServerSocket concept requires a http::Socket to write its
> > messages, but does the http::ServerSocket concept need to be a refinement
> > of the http::Socket concept? This implies a strong relationship. The
> > current specification looks like a http::ServerTraits concept - its
> > specifying how a http::Socket is being used in situations specific to
> > servers. There doesn't appear to be any additional state tracking needed
> > for the http::ServerSocket functions, which is why I suggested standalone
> > functions (I didn't see the FileServer section). In fact implementation
> can
> > be inverted; make all of the current implementations for
> http::ServerSocket
> > standalone functions, and then have the default http::ServerTraits
> > implementation call the standalone versions of the functions. The
> > http::ServerTraits should then take a http::Socket as an argument for
> each
> > of the functions. This complete de-coupling would allow someone to
> > independently change the behavior of any related server functions, even
> > while using the same http::Socket object.
> >
>
> If I understood you correctly, you're proposing that all functions should
> be free functions, not member-functions, then everybody can customize any
> type to model a ServerSocket. And then you criticize the strong
> relationship between Socket and ServerSocket.
>
> Asio doesn't follow this model (async_read_some is a member-function, not a
> free function). It does appear to be an interesting idea, but I'm not sure
> I'm prepared to solve this detail of customization level. The order of
> includes could completely change the behaviour and this is the least of the
> problems. Can you elaborate more, then we can discuss?
>
> And the reason behind Socket and ServerSocket is the future addition of a
> ClientSocket, which will be a refinement of Socket.
>
>
The problem is that I incorrectly jumped to conclusions after seeing the
http::Socket concept, and assumed it had all the functionality to parse
HTTP (server and client), because thats exactly how I would try do it for
flexibility purposes. This http::Socket concept explicitly does not provide
a mechanism to read the first line & headers of a HTTP message. I expected
the concept to handle the fields portion of the header at least, since they
are identical. This is why I thought the http::ServerSocket were more like
traits - I thought they were defining some convenience functions into the
more basic calls of the http::Socket concept.

Anyway-
Can http::Socket concept define a function for reading the headers (they
should be identical)? OR can the first line of a http message be read into
the empty "" string of the headers map? OR could the http::Socket require a
separate string for the first line?

If either of the last two were chosen - standalone functions could
"compose" against a http::Socket::async_read_headers function, where upon
completion they would move the first line to some place else or parse them
apart them into separate fields provided by the user. The major funky thing
is handling HEAD command responses, which I assume was going to have a
specific function in http::ClientSocket ? This might need a special state
manipulation regardless.

I'll probably have to start using it before saying much more I guess ...

Lee


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk