From: Jeroen H. <vex...@gm...> - 2010-02-11 22:41:26
|
Hi again, On Thu, Feb 11, 2010 at 18:27, Dean Michael Berris <mik...@gm...> wrote: > Hey Darren! > > It's great to see you here. :) > > On Fri, Feb 12, 2010 at 1:02 AM, Darren Garvey <dar...@gm...> wrote: >> >> 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). >> > > I think Marshall has taken the input from the boost-devel mailing list > regarding this and *might* be working on something similar. I'm not > sure though what his timetable on that would be. :) > >> Marshall, are you planning to integrate your MIME parser with cpp-netlib? >> > > /me silently wishes Marshall does! :D > >>> * 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? >> > > Definitely! > > Have you looked at the HTTP Server template yet? It's very bare and if > we can plug in the CGI handlers through the HTTP Server template then > I think my search for one half of a C++ Application Servlet Container > would be complete. The other half would only be actual session > handling and persistence subsystem managers. :D > >>> >>> * URI pattern-based dispatch (ala Rails, or Django/Tornado) >> >> Very useful feature, but must be kept distinctly separate from the core >> IMHO. > > 100% agree. I'm thinking this alone would be cool in its own right and > might be a full-blown library waiting to happen. I can definitely see > this being useful in other contexts like command consoles, scripting > interfaces, etc. -- which is also why I'm thinking a utilities > collection would be a good place to host something like this. ;) I agree this must be kept distinctly separate from the core, and I think we need to decide how far we want to take this. In its simplest form it would be a very handy utility, which shows the basics of what can be done, though in it's most extensive form it would indeed be a full-blown library. The former seems to be nice to have around May, mostly to show how the library can be used in practice. >> 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. >> > > This sounds like exactly what I'm looking for. My only gripe is that > it uses virtual functions. ;) > >> 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! >> > > Actually, I think you can get away with a chain pattern, using > Boost.Fusion for compile-time wired static dispatch. If I understand > it correctly, you might be able to get away with a combination of > Boost.Xpressive for the statically defined regex's and handlers that > adhere to a certain Concept. > > The recipe would involve (from the top of my head) a Fusion sequence > of pairs of Xpressive patterns and opaque handlers. You run it through > Fusion's `any` function and find the first match and invoke the > associated handler. Given a little more prodding I might implement it > myself just as an exercise on Fusion, Xpressive, and some > metaprogramming kung fu. :) This might be pushing people in the direction of Xpressive when there's no need for it, simple prefix matching is often enough. Could this be done either simpler, or more generically? >> >>> >>> 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? >> > > Boost.Spirit FTW -- the cost of compile times definitely justify the > performance gains at runtime. :) Very much so :) >> Cheers, >> Darren >> > > Thanks for sharing your thoughts Darren! I hope some of my thoughts help too. :D > > I'm also looking forward to the CGI library. :) > > -- > Dean Michael Berris > cplusplus-soup.com | twitter.com/deanberris > linkedin.com/in/mikhailberis | facebook.com/dean.berris | deanberris.com > Jeroen |