eidheim / Simple-Web-Server

A very simple, fast, multithreaded, platform independent HTTP and HTTPS server and client library implemented using C++11 and Boost.Asio. Created to be an easy way to make REST resources available from C++ applications.
MIT License
2.62k stars 758 forks source link

Showing a way to handle Mime Types and the Apache mime.types file #113

Open hytano opened 7 years ago

hytano commented 7 years ago

It is nice if a server responds with Content-Type set in the header when sending files.

The example shows a way to handle mime types (ready for copy and paste for all the lazy ones ;-) ) and how to use it in the default file handler of the example. The mime types are downloaded from the web. This demonstrates the use of Client to download content from another server and react on the content of the respone's status code. If successful (200 OK) it parses the content into a simple lookup table.

Perhaps it is useful to move the "class MimeTypes" lookup table to some other part of the project. Having a config option to automatic load a file in the mime.types format. I missed this kind of feature everytime I had to use an embedded web server. But perhaps this is not in the scope of this project...?

eidheim commented 7 years ago

It is slightly out of scope of this project, but I'm thinking of adding a util.hpp with various functions such as this maybe. At the moment though, the client is able to figure out the file type based on the extension of the give path? There are cases though where the file extension is not given in the path, for instance if something like this is used instead: http://localhost/file?id=42.

hytano commented 7 years ago

In my changes in http_example.cpp the mime type is detected based on the file extension of the file on disk which is send back by the "default handler".

I guess a utils.hpp would be really nice.

In most cases the author of the handler methods is in charge for setting (or not setting) the Content-Type correctly. Usually the handler knows what it delivers. But the default (file) handler in the example does not know. It only sends files back. It needs a way to detect what Conten-Type to set based on the real content of the file. And this simple mapping from file extension to mime type is enough for most use cases. This is all what my example does. MimeTypes only parses the mime.types file with an "official" list of file extension to mime type mapping. (The file can be distributed like a config file or hard coded or downloaded in the real application which is using SimpleWebServer. Downloading the file from apache has nothing to do with this Content-Type stuff in general. I only thought it is nice to show the use of the Client downloading something and then processing it.)

eidheim commented 7 years ago

Thank you, but let's say that you request http://localhost/test.jpg form the client. At least most browsers understands that the response is a jpg file (when Content-Type is absent) based on the request path (/test.jpg), or am I wrong?

hytano commented 7 years ago

I guess some browsers simply try to identify the real content of the data they get in response. I cannot immagine that examining the request path is really done (and I immagine that this could induce some security risks. But I am no expert!) Another feature: One can use the Content-Type to explicitly tell the client what this representation of a resource really is. Without Content-Type present in the header a lot clients interpret the data as application/octet-stream which perhaps opens a download window or something like this. While image/jpeg displays the same data of this resource on the screen. But this has nothing to do with the Mime Type lookup in my http_example.

I think correct handling of Content-Type is "polite" and especially for RESTful services more or less important.

eidheim commented 7 years ago

You are right, it is polite to add Content-Type:) Do you know of a git repository that is dedicated to having an up to date Mime type lookup? We could maybe add this as a git submodule and use this in case it is present? The functionality should maybe be in a utils.hpp file instead of the http(s)_examples.cpp since these latter files should be as basic as possible I think. The function definition could maybe be something like SimpleWeb::Utils::content_type(const std::string &extension) and should return for instance image/jpg if jpg is the extension parameter. I'm open for discussion however!

sebt3 commented 7 years ago

Some browser (like chrome) couldnt care less about the content-type (probably doing some mime magic stuff). But some are expecting them (like firefox) and might even whine in some context to the end-user.