changed code to use hio_get_mime_type_by_ext()

This commit is contained in:
hyung-hwan 2022-12-16 16:24:10 +00:00
parent 1ba44dc203
commit 9808760d64
6 changed files with 222 additions and 22 deletions

View File

@ -76,7 +76,6 @@ static int process_http_request (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_
mth = hio_htre_getqmethodtype(req);
qpath = hio_htre_getqpath(req);
if (mth == HIO_HTTP_OTHER && hio_comp_bcstr(hio_htre_getqmethodname(req), "UNTAR", 1) == 0)
{
/* don't care about the path for now. TODO: make this secure and reasonable */
@ -85,11 +84,7 @@ static int process_http_request (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_
else // if (mth == HIO_HTTP_GET || mth == HIO_HTTP_POST)
{
/* TODO: proper mime-type */
const hio_bch_t* dot;
hio_bch_t mt[128];
dot = hio_rfind_bchar_in_bcstr(qpath, '.');
hio_fmttobcstr (hio, mt, HIO_COUNTOF(mt), "text/%hs", ((dot && dot[1] != '\0')? &dot[1]: "html")); /* TODO: error check */
if (hio_svc_htts_dofile(htts, csck, req, ext->docroot, qpath, mt, 0) <= -1) goto oops;
if (hio_svc_htts_dofile(htts, csck, req, ext->docroot, qpath, HIO_NULL, 0) <= -1) goto oops;
}
#if 0
else
@ -152,12 +147,12 @@ static void handle_sigint (int sig)
int main (int argc, char* argv[])
{
hio_t* hio = HIO_NULL;
hio_oow_t i;
struct sigaction sigact;
int xret = -1;
#if 0
hio_oow_t i;
// TODO: use getopt() or something similar
for (i = 1; i < argc; )
{

View File

@ -118,6 +118,7 @@ libhio_la_SOURCES = \
tmr.c \
utf8.c \
utl.c \
utl-mime.c \
utl-siph.c \
utl-str.c

View File

@ -154,7 +154,8 @@ am__libhio_la_SOURCES_DIST = chr.c dhcp-svr.c dns.c dns-cli.c ecs.c \
nwif.c opt.c opt-imp.h path.c pipe.c pro.c pty.c rad-msg.c \
sck.c shw.c skad.c sys.c sys-ass.c sys-err.c sys-log.c \
sys-mux.c sys-prv.h sys-tim.c thr.c uch-case.h uch-prop.h \
tar.c tmr.c utf8.c utl.c utl-siph.c utl-str.c mar.c mar-cli.c
tar.c tmr.c utf8.c utl.c utl-mime.c utl-siph.c utl-str.c mar.c \
mar-cli.c
@ENABLE_MARIADB_TRUE@am__objects_1 = libhio_la-mar.lo \
@ENABLE_MARIADB_TRUE@ libhio_la-mar-cli.lo
am_libhio_la_OBJECTS = libhio_la-chr.lo libhio_la-dhcp-svr.lo \
@ -171,8 +172,8 @@ am_libhio_la_OBJECTS = libhio_la-chr.lo libhio_la-dhcp-svr.lo \
libhio_la-sys.lo libhio_la-sys-ass.lo libhio_la-sys-err.lo \
libhio_la-sys-log.lo libhio_la-sys-mux.lo libhio_la-sys-tim.lo \
libhio_la-thr.lo libhio_la-tar.lo libhio_la-tmr.lo \
libhio_la-utf8.lo libhio_la-utl.lo libhio_la-utl-siph.lo \
libhio_la-utl-str.lo $(am__objects_1)
libhio_la-utf8.lo libhio_la-utl.lo libhio_la-utl-mime.lo \
libhio_la-utl-siph.lo libhio_la-utl-str.lo $(am__objects_1)
libhio_la_OBJECTS = $(am_libhio_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -228,6 +229,7 @@ am__depfiles_remade = ./$(DEPDIR)/libhio_la-chr.Plo \
./$(DEPDIR)/libhio_la-sys.Plo ./$(DEPDIR)/libhio_la-tar.Plo \
./$(DEPDIR)/libhio_la-thr.Plo ./$(DEPDIR)/libhio_la-tmr.Plo \
./$(DEPDIR)/libhio_la-utf8.Plo \
./$(DEPDIR)/libhio_la-utl-mime.Plo \
./$(DEPDIR)/libhio_la-utl-siph.Plo \
./$(DEPDIR)/libhio_la-utl-str.Plo \
./$(DEPDIR)/libhio_la-utl.Plo
@ -474,7 +476,7 @@ libhio_la_SOURCES = chr.c dhcp-svr.c dns.c dns-cli.c ecs.c ecs-imp.h \
opt.c opt-imp.h path.c pipe.c pro.c pty.c rad-msg.c sck.c \
shw.c skad.c sys.c sys-ass.c sys-err.c sys-log.c sys-mux.c \
sys-prv.h sys-tim.c thr.c uch-case.h uch-prop.h tar.c tmr.c \
utf8.c utl.c utl-siph.c utl-str.c $(am__append_2)
utf8.c utl.c utl-mime.c utl-siph.c utl-str.c $(am__append_2)
libhio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libhio_la_CFLAGS = $(CFLAGS_LIB_COMMON) $(am__append_3)
libhio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON) $(am__append_4)
@ -617,6 +619,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-thr.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-tmr.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-utf8.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-utl-mime.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-utl-siph.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-utl-str.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhio_la-utl.Plo@am__quote@ # am--include-marker
@ -945,6 +948,13 @@ libhio_la-utl.lo: utl.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-utl.lo `test -f 'utl.c' || echo '$(srcdir)/'`utl.c
libhio_la-utl-mime.lo: utl-mime.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -MT libhio_la-utl-mime.lo -MD -MP -MF $(DEPDIR)/libhio_la-utl-mime.Tpo -c -o libhio_la-utl-mime.lo `test -f 'utl-mime.c' || echo '$(srcdir)/'`utl-mime.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-utl-mime.Tpo $(DEPDIR)/libhio_la-utl-mime.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utl-mime.c' object='libhio_la-utl-mime.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -c -o libhio_la-utl-mime.lo `test -f 'utl-mime.c' || echo '$(srcdir)/'`utl-mime.c
libhio_la-utl-siph.lo: utl-siph.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhio_la_CPPFLAGS) $(CPPFLAGS) $(libhio_la_CFLAGS) $(CFLAGS) -MT libhio_la-utl-siph.lo -MD -MP -MF $(DEPDIR)/libhio_la-utl-siph.Tpo -c -o libhio_la-utl-siph.lo `test -f 'utl-siph.c' || echo '$(srcdir)/'`utl-siph.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhio_la-utl-siph.Tpo $(DEPDIR)/libhio_la-utl-siph.Plo
@ -1175,6 +1185,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libhio_la-thr.Plo
-rm -f ./$(DEPDIR)/libhio_la-tmr.Plo
-rm -f ./$(DEPDIR)/libhio_la-utf8.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl-mime.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl-siph.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl-str.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl.Plo
@ -1267,6 +1278,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libhio_la-thr.Plo
-rm -f ./$(DEPDIR)/libhio_la-tmr.Plo
-rm -f ./$(DEPDIR)/libhio_la-utf8.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl-mime.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl-siph.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl-str.Plo
-rm -f ./$(DEPDIR)/libhio_la-utl.Plo

View File

@ -224,6 +224,22 @@
#define HIO_HASH_UCSTR(hv, ptr) HIO_HASH_VPTR(hv, ptr, const hio_uch_t)
#define HIO_HASH_MORE_UCSTR(hv, ptr) HIO_HASH_MORE_VPTR(hv, ptr, const hio_uch_t)
/* =========================================================================
* MIME TYPE ENTRY
* ========================================================================= */
struct hio_mime_type_t
{
const hio_bch_t* ext;
const hio_bch_t* type;
};
typedef struct hio_mime_type_t hio_mime_type_t;
#if defined(__cplusplus)
extern "C" {
#endif
/* =========================================================================
* STRING
* ========================================================================= */
@ -652,7 +668,6 @@ static HIO_INLINE hio_uint128_t hio_bswap128 (hio_uint128_t x)
# error UNKNOWN ENDIAN
#endif
/* =========================================================================
* SIP-HASH-PRF
* ========================================================================= */
@ -663,4 +678,15 @@ HIO_EXPORT void hio_sip_hash_24 (
hio_uint8_t out[8]
);
/* =========================================================================
* mime-type by extension
* ========================================================================= */
HIO_EXPORT const hio_bch_t* hio_get_mime_type_by_ext (
const hio_bch_t* ext
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -479,12 +479,16 @@ static int file_send_header_to_client (file_t* file, int status_code, int force_
content_length = file->end_offset - file->start_offset + 1;
if (status_code == HIO_HTTP_STATUS_OK && file->total_size != content_length) status_code = HIO_HTTP_STATUS_PARTIAL_CONTENT;
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %s\r\nConnection: %hs\r\nAccept-Ranges: bytes\r\nContent-Type: %hs\r\n",
if (hio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %s\r\nConnection: %hs\r\nAccept-Ranges: bytes\r\n",
file->req_version.major, file->req_version.minor,
status_code, hio_http_status_to_bcstr(status_code),
cli->htts->server_name, dtbuf,
(force_close? "close": "keep-alive"), mime_type) == (hio_oow_t)-1) return -1;
(force_close? "close": "keep-alive")) == (hio_oow_t)-1) return -1;
/* Content-Type is not set if mime_type is null or blank */
if (mime_type && mime_type[0] != '\0' &&
hio_becs_fcat(cli->sbuf, "Content-Type: %hs\r\n", mime_type) == (hio_oow_t)-1) return -1;
if (file->req_method == HIO_HTTP_GET && hio_becs_fcat(cli->sbuf, "ETag: %hs\r\n", file->peer_etag) == (hio_oow_t)-1) return -1;
if (status_code == HIO_HTTP_STATUS_PARTIAL_CONTENT && hio_becs_fcat(cli->sbuf, "Content-Ranges: bytes %ju-%ju/%ju\r\n", (hio_uintmax_t)file->start_offset, (hio_uintmax_t)file->end_offset, (hio_uintmax_t)file->total_size) == (hio_oow_t)-1) return -1;
@ -672,9 +676,11 @@ static HIO_INLINE int process_range_header (file_t* file, hio_htre_t* req, int*
return 0;
}
static int open_peer_with_mode (file_t* file, const hio_bch_t* actual_file, int flags, int* error_status)
static int open_peer_with_mode (file_t* file, const hio_bch_t* actual_file, int flags, int* error_status, const hio_bch_t** actual_mime_type)
{
struct stat st;
const hio_bch_t* opened_file;
flags |= O_NONBLOCK;
#if defined(O_CLOEXEC)
@ -691,7 +697,8 @@ static int open_peer_with_mode (file_t* file, const hio_bch_t* actual_file, int
return -1;
}
if (fstat(file->peer, &st) >= 0 && S_ISDIR(st.st_mode))
opened_file = actual_file;
if ((flags & O_RDONLY) && fstat(file->peer, &st) >= 0 && S_ISDIR(st.st_mode)) /* only for read operation */
{
hio_bch_t* alt_file;
int alt_fd;
@ -701,14 +708,30 @@ static int open_peer_with_mode (file_t* file, const hio_bch_t* actual_file, int
if (alt_file)
{
alt_fd = open(alt_file, flags, 0644);
hio_freemem (file->htts->hio, alt_file);
if (alt_fd >= 0)
{
close (file->peer);
file->peer = alt_fd;
opened_file = alt_file;
}
}
}
if (actual_mime_type)
{
const hio_bch_t* dot;
dot = hio_rfind_bchar_in_bcstr(opened_file, '.');
if (dot)
{
const hio_bch_t* mt;
mt = hio_get_mime_type_by_ext(dot + 1);
if (mt) *actual_mime_type = mt;
}
}
if (opened_file != actual_file)
hio_freemem (file->htts->hio, (hio_bch_t*)opened_file);
return 0;
}
@ -854,7 +877,10 @@ int hio_svc_htts_dofile (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t*
switch (file->req_method)
{
case HIO_HTTP_GET:
if (open_peer_with_mode(file, actual_file, O_RDONLY, &status_code) <= -1) goto done_with_status_code;
{
const hio_bch_t* actual_mime_type = mime_type;
if (open_peer_with_mode(file, actual_file, O_RDONLY, &status_code, (mime_type? HIO_NULL: &actual_mime_type)) <= -1) goto done_with_status_code;
if (process_range_header(file, req, &status_code) <= -1) goto done_with_status_code;
if (file->etag_match)
@ -869,13 +895,14 @@ int hio_svc_htts_dofile (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t*
#endif
set_tcp_cork (file->client->sck);
if (file_send_header_to_client(file, HIO_HTTP_STATUS_OK, 0, mime_type) <= -1 ||
if (file_send_header_to_client(file, HIO_HTTP_STATUS_OK, 0, actual_mime_type) <= -1 ||
file_send_contents_to_client(file) <= -1) goto oops;
break;
}
case HIO_HTTP_HEAD:
if (open_peer_with_mode(file, actual_file, O_RDONLY, &status_code) <= -1) goto done_with_status_code;
if (open_peer_with_mode(file, actual_file, O_RDONLY, &status_code, HIO_NULL) <= -1) goto done_with_status_code;
if (process_range_header(file, req, &status_code) <= -1) goto done_with_status_code;
status_code = HIO_HTTP_STATUS_OK;
goto done_with_status_code;
@ -888,7 +915,7 @@ int hio_svc_htts_dofile (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t*
goto done_with_status_code;
}
if (open_peer_with_mode(file, actual_file, O_WRONLY | O_TRUNC | O_CREAT, &status_code) <= -1) goto done_with_status_code;
if (open_peer_with_mode(file, actual_file, O_WRONLY | O_TRUNC | O_CREAT, &status_code, HIO_NULL) <= -1) goto done_with_status_code;
/* the client input must be written to the peer side */
file_mark_over (file, FILE_OVER_READ_FROM_PEER);

139
lib/utl-mime.c Normal file
View File

@ -0,0 +1,139 @@
/*
Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <hio-utl.h>
/* Keep this table sorted for binary search */
static hio_mime_type_t mime_type_tab[] =
{
{"3gp", "video/3gpp"},
{"3g2", "video/3gpp2"},
{"7z", "application/x-7z-compressed"},
{"aac", "audio/aac"},
{"abw", "application/x-abiword"},
{"arc", "application/x-freearc"},
{"avif", "image/avif"},
{"avi", "video/x-msvideo"},
{"azw", "application/vnd.amazon.ebook"},
{"bin", "application/octet-stream"},
{"bmp", "image/bmp"},
{"bz", "application/x-bzip"},
{"bz2", "application/x-bzip2"},
{"cda", "application/x-cdf"},
{"csh", "application/x-csh"},
{"css", "text/css"},
{"csv", "text/csv"},
{"doc", "application/msword"},
{"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
{"eot", "application/vnd.ms-fontobject"},
{"epub", "application/epub+zip"},
{"gz", "application/gzip"},
{"gif", "image/gif"},
{"htm", "text/html"},
{"html", "text/html"},
{"ico", "image/vnd.microsoft.icon"},
{"ics", "text/calendar"},
{"jar", "application/java-archive"},
{"jpeg", "image/jpeg"},
{"jpg", "image/jpeg"},
{"js", "text/javascript"},
{"json", "application/json"},
{"jsonld", "application/ld+json"},
{"mid", "audio/midi"},
{"midi", "audio/midi"},
{"mjs", "text/javascript"},
{"mp3", "audio/mpeg"},
{"mp4", "video/mp4"},
{"mpeg", "video/mpeg"},
{"mpkg", "application/vnd.apple.installer+xml"},
{"odp", "application/vnd.oasis.opendocument.presentation"},
{"ods", "application/vnd.oasis.opendocument.spreadsheet"},
{"odt", "application/vnd.oasis.opendocument.text"},
{"oga", "audio/ogg"},
{"ogv", "video/ogg"},
{"ogx", "application/ogg"},
{"opus", "audio/opus"},
{"otf", "font/otf"},
{"png", "image/png"},
{"pdf", "application/pdf"},
{"php", "application/x-httpd-php"},
{"ppt", "application/vnd.ms-powerpoint"},
{"pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
{"rar", "application/vnd.rar"},
{"rtf", "application/rtf"},
{"sh", "application/x-sh"},
{"svg", "image/svg+xml"},
{"tar", "application/x-tar"},
{"tif", "image/tiff"},
{"tiff", "image/tiff"},
{"ts", "video/mp2t"},
{"ttf", "font/ttf"},
{"txt", "text/plain"},
{"vsd", "application/vnd.visio"},
{"wav", "audio/wav"},
{"weba", "audio/webm"},
{"webm", "video/webm"},
{"webp", "image/webp"},
{"woff", "font/woff"},
{"woff2", "font/woff2"},
{"xhtml", "application/xhtml+xml"},
{"xls", "application/vnd.ms-excel"},
{"xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
{"xml", "application/xml"},
{"xul", "application/vnd.mozilla.xul+xml"},
{"zip", "application/zip"}
};
const hio_bch_t* hio_get_mime_type_by_ext(const hio_bch_t* ext)
{
/* perform binary search */
/* declaring left, right, mid to be of int is ok
* because we know mtab is small enough. */
int left = 0, right = HIO_COUNTOF(mime_type_tab) - 1, mid;
while (left <= right)
{
int n;
hio_mime_type_t* entry;
/*mid = (left + right) / 2;*/
mid = left + (right - left) / 2;
entry = &mime_type_tab[mid];
n = hio_comp_bcstr(ext, entry->ext, 1);
if (n < 0)
{
/* if left, right, mid were of hio_oow_t,
* you would need the following line.
if (mid == 0) break;
*/
right = mid - 1;
}
else if (n > 0) left = mid + 1;
else return entry->type;
}
return HIO_NULL;
}