From: Darren G. <dar...@gm...> - 2010-02-11 17:03:23
|
Hi Dean, On 11 February 2010 14:25, Dean Michael Berris <mik...@gm...>wrote: > I was thinking about this a little and thought it would be cool to > have a collection of utilities of commonly-performed actions that > others might find useful in the library. Off the top of my head I find > that these would be cool functions/mini-libraries to have: * MIME Parser (Marshall Clow has a cool one worthy of more attention > and discussion, hopefully he merges it into cpp-netlib in time for > BoostCon 2010 ;) ). > I've taken a look at this. It looks pretty cool, like it could fit the bill. Two extra features that I would find very useful are: * Either: - Ability to restart the parser - ie. support chunked data. or: - Ability to pass in a Boost.Asio-compatible *ReadStream instead of an istream. * Ability to store file uploads directly to the filesystem (ie. so you can support uploading huge files). Marshall, are you planning to integrate your MIME parser with cpp-netlib? * Form encoding/decoding (for HTTP clients/servers to handle HTML > form encoded data) > * Query string encoding/decoding (for GET queries) > * Base64 stream/string encoding/decoding (for Binary data) > There is overlap with the CGI library under development. Is there anything we can do to find some common ground here? > * URI pattern-based dispatch (ala Rails, or Django/Tornado) > Very useful feature, but must be kept distinctly separate from the core IMHO. I have some code which does dynamic dispatching of handlers based on regular expressions matching with the path-info of a request. This also dispatches to a specific handler depending on the request-method of the request. For example: // One of many potential request handlers: struct some_handler : request_handler<some_handler, Context> { int get(Context& self) { /* ... */ } int post(Context& self, boost::regex_match& url_matches) { /* ... */ } int put(Context& self) { /* ... */ } }; The above pattern uses virtual functions to allow it to work. When a handler for the specified request method isn't found, this is captured in the base class. If the handler overrides the base class method, the handler's method is called. The handler is able to have an optional regex_match argument, which allows the regular expression of the match to use sub-matches. For example, the url pattern "(/*)" would match any request and attempt to call the relevant handler. If the handler took a regex_match, this would be called with the full path_info of the request. The code doesn't currently fall back to a handler that works with any request method, but could easily enough. Also, it may benefit from some metaprogramming to make the dispatching static... My feelings at the time were that one or two virtual function calls per request are fine - feel free to disagree! Thoughts? > I find myself wanting to write these myself or at least using them > when I write programs that use cpp-netlib. Simple things like for HTTP > server based applications I want to be able to parse a list of > parameters (remembering what Jeroen was proposing to do with the URI > parser one time). > > Any takers? It would be cool if we had these in the library before May > where I will be presenting the library and the techniques used in the > library at a high level. ;) > Not sure how much time I'll have to spare as I'm quite busy with work and pushing to getting a release of the CGI library out ASAP. I use Boost.Tokenizer for splitting query strings and cookies and a custom url_decode function for parsing. The data is stored in std::map<>s, with a case-insensitive string as the key_type. That said, these aren't using Spirit yet. Maybe compilers are fast enough to deal with sprinklings of Spirit coolness everywhere now? Cheers, Darren |