Tectu / malloy

A cross-platform C++20 library providing embeddable server & client components for HTTP and WebSocket.
BSD 3-Clause "New" or "Revised" License
66 stars 8 forks source link

Registerable mime-types #4

Open Tectu opened 3 years ago

Tectu commented 3 years ago

Add an interface to register mime-types.

Something similar to how nginx configuration files allow for http { types { } } .

0x00002a commented 3 years ago

This could now be done atop #17. With the Filter concept a function like valid_request could be introduced, which took in a header and just returned bool as to whether to accept that request. Alternatively it could be a more specialised accept_mimetype which only takes in a string for the mimetype and returns bool.

One snag is that only router::add currently allows passing a filter, so if we went that route it would need to be added to add_file_serving and add_redirect (potentially). So it might actually be better to define another concept that is an optional subset of Filter and use that (for Filter accepts_mimetype would be optional, add_file_serving uses the subset where that is not optional).

Finally, a seperate but related issue, should mimetypes be strongly typed? (i.e. have a mime object passed around instead of std::string or whatever). I have some code for mimetype detection that uses a constexpr array for the lookup and stores the index to the pair that has the extension + name in it. This has the advantage that it can be constructed from either the extension or name (and can be asked for either) and is the size of a uint16_t (could be smaller with less recognised mimetypes). Problem with that is how to deal with unknown mimetypes.

Thoughts?

Tectu commented 3 years ago

At this point I'd mainly like to note that this functionality is also relevant for responses, not just requests.

Personally I am very-pro providing strongly typed values for common MIME types. However, the user needs to be able to set any MIME-type as well (i.e. by just passing a string). It should be fairly simple to provide the infrastructure to use built-in strongly typed MIME types for the standard types and as an option allow to just set a string value instead. I also think that the list of pre-defined strongly typed MIME types should ideally be extendable by the user during compile time for registering non-standard, application specific MIME types while still being able to use them through the strongly-typed interface(s) after registration.

0x00002a commented 3 years ago

I was thinking it wouldn't make much sense for it to apply to the Filter for responses since theres no overloading happening there. Not sure if thats what you meant.

I agree that the mimetype list needs to be extensible by the user. But having it as a global which is also extensible is a bad idea imo. One way around that would be template-based dependency injection like what beast::http::message uses. That would allow us to define a basic set of common ones and have users define their own, while maintaing the lightweight nature. The type to inject could be specified in the Filter (accepts_mimetype would take in a mime<T>)

0x00002a commented 3 years ago

I made an example for the above approach: gist. As I mention there, there are a few disadvantages most notably the non-dynamic lookup ability and use of static methods.

Love to hear your thoughts on it

Tectu commented 3 years ago

I had a look at this - I think that's a pretty good start!

Cons: Its templated, meaning library code for it will also need to be templated in some way

I'm wondering how bad this is gonna be in practice. After all, malloy is already heavily templated and underlying boost even more so.

Tectu commented 1 year ago

@0x00002a I'm currently revisiting this topic - are you up for a discussion?