Преглед изворни кода

Used Unicode functions when opening files for downloading. (Fix #50)

silvioprog пре 4 година
родитељ
комит
33ec9719af
5 измењених фајлова са 83 додато и 46 уклоњено
  1. 1 1
      include/sagui.h
  2. 49 40
      src/sg_httpres.c
  3. 25 1
      src/sg_macros.h
  4. 3 3
      src/sg_utils.c
  5. 5 1
      src/sg_utils.h

+ 1 - 1
include/sagui.h

@@ -74,7 +74,7 @@ extern "C" {
 
 #define SG_VERSION_MAJOR 3
 #define SG_VERSION_MINOR 3
-#define SG_VERSION_PATCH 1
+#define SG_VERSION_PATCH 2
 #define SG_VERSION_HEX                                                         \
   ((SG_VERSION_MAJOR << 16) | (SG_VERSION_MINOR << 8) | (SG_VERSION_PATCH))
 

+ 49 - 40
src/sg_httpres.c

@@ -47,53 +47,62 @@
 static void sg__httpres_openfile(struct sg_httpres *res, const char *filename,
                                  const char *disposition, uint64_t max_size,
                                  int *fd, struct stat *sbuf, int *errnum) {
-  const char *fn;
-  size_t fn_size;
-  char *disp;
+  const char *base_name;
+  size_t base_name_size;
+  char *header;
 #ifdef _WIN32
-  if (stat(filename, sbuf)) {
-    *errnum = errno;
-    return;
-  }
-  if (S_ISDIR(sbuf->st_mode)) {
-    *errnum = EISDIR;
-    return;
-  }
+#define SG__HTTPRES_OPENFILE_ERROR(e)                                          \
+  do {                                                                         \
+    *errnum = (e);                                                             \
+    goto error;                                                                \
+  } while (0)
+  wchar_t *file_name = stow(filename);
+#define SG__FILENAME file_name
+#else /* _WIN32 */
+#define SG__HTTPRES_OPENFILE_ERROR(e)                                          \
+  do {                                                                         \
+    *errnum = (e);                                                             \
+    return;                                                                    \
+  } while (0)
+#define SG__FILENAME filename
 #endif /* _WIN32 */
-  *fd = open(filename, O_RDONLY);
-  if ((*fd == -1) || fstat(*fd, sbuf)) {
-    *errnum = errno;
-    return;
-  }
+#ifdef _WIN32
+  if (SG__STAT(SG__FILENAME, sbuf))
+    SG__HTTPRES_OPENFILE_ERROR(errno);
+  if (S_ISDIR(sbuf->st_mode))
+    SG__HTTPRES_OPENFILE_ERROR(EISDIR);
+#endif /* _WIN32 */
+  *fd = SG__OPEN(SG__FILENAME, O_RDONLY);
+  if ((*fd == -1) || fstat(*fd, sbuf))
+    SG__HTTPRES_OPENFILE_ERROR(errno);
 #ifndef _WIN32
-  if (S_ISDIR(sbuf->st_mode)) {
-    *errnum = EISDIR;
-    return;
-  }
+  if (S_ISDIR(sbuf->st_mode))
+    SG__HTTPRES_OPENFILE_ERROR(EISDIR);
 #endif /* _WIN32 */
-  if (!S_ISREG(sbuf->st_mode)) {
-    *errnum = EBADF;
-    return;
-  }
-  if ((max_size > 0) && ((uint64_t) sbuf->st_size > max_size)) {
-    *errnum = EFBIG;
-    return;
-  }
+  if (!S_ISREG(sbuf->st_mode))
+    SG__HTTPRES_OPENFILE_ERROR(EBADF);
+  if ((max_size > 0) && ((uint64_t) sbuf->st_size > max_size))
+    SG__HTTPRES_OPENFILE_ERROR(EFBIG);
   if (disposition) {
-#define SG__FNFMT "%s; filename=\"%s\""
-    fn = sg__basename(filename);
-    fn_size = (size_t) snprintf(NULL, 0, SG__FNFMT, disposition, fn) + 1;
-    disp = sg_malloc(fn_size);
-    if (!disp) {
-      *errnum = ENOMEM;
-      return;
-    }
-    snprintf(disp, fn_size, SG__FNFMT, disposition, fn);
-#undef SG__FNFMT /* SG__FNFMT */
+#define SG__BASENAME_FMT "%s; filename=\"%s\""
+    base_name = sg__basename(filename);
+    base_name_size =
+      (size_t) snprintf(NULL, 0, SG__BASENAME_FMT, disposition, base_name) + 1;
+    header = sg_malloc(base_name_size);
+    if (!header)
+      SG__HTTPRES_OPENFILE_ERROR(ENOMEM);
+    snprintf(header, base_name_size, SG__BASENAME_FMT, disposition, base_name);
+#undef SG__BASENAME_FMT /* SG__BASENAME_FMT */
     *errnum =
-      sg_strmap_set(&res->headers, MHD_HTTP_HEADER_CONTENT_DISPOSITION, disp);
-    sg_free(disp);
+      sg_strmap_set(&res->headers, MHD_HTTP_HEADER_CONTENT_DISPOSITION, header);
+    sg_free(header);
   }
+#ifdef _WIN32
+error:
+  sg_free(SG__FILENAME);
+#endif /* _WIN32 */
+#undef SG__FILENAME /* SG__FILENAME */
+#undef SG__HTTPRES_OPENFILE_ERROR /* SG__HTTPRES_OPENFILE_ERROR */
 }
 
 #ifdef SG_HTTP_COMPRESSION

+ 25 - 1
src/sg_macros.h

@@ -7,7 +7,7 @@
  *
  * Cross-platform library which helps to develop web servers or frameworks.
  *
- * Copyright (C) 2016-2020 Silvio Clecio <[email protected]>
+ * Copyright (C) 2016-2021 Silvio Clecio <[email protected]>
  *
  * Sagui library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -30,11 +30,35 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #ifndef NDEBUG
 #include <unistd.h>
 #include <errno.h>
 #endif /* NDEBUG */
 #include "sagui.h"
+#ifdef _WIN32
+#include <wchar.h>
+
+#ifndef SG__STAT
+#define SG__STAT wstat
+#endif /* SG_STAT */
+
+#ifndef SG__OPEN
+#define SG__OPEN _wopen
+#endif /* SG__OPEN */
+
+#else /* _WIN32 */
+
+#ifndef SG__STAT
+#define SG__STAT stat
+#endif /* SG_STAT */
+
+#ifndef SG__OPEN
+#define SG__OPEN open
+#endif /* SG__OPEN */
+
+#endif /* _WIN32 */
 
 /* used by utstring library */
 #ifndef utstring_oom

+ 3 - 3
src/sg_utils.c

@@ -7,7 +7,7 @@
  *
  * Cross-platform library which helps to develop web servers or frameworks.
  *
- * Copyright (C) 2016-2020 Silvio Clecio <[email protected]>
+ * Copyright (C) 2016-2021 Silvio Clecio <[email protected]>
  *
  * Sagui library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -70,7 +70,7 @@ char *strndup(const char *s, size_t n) {
 }
 
 /* Maps a character string to a UTF-16 (wide character) string. */
-static wchar_t *stow(const char *str) {
+wchar_t *stow(const char *str) {
   wchar_t *res = NULL;
   int len;
   if (str) {
@@ -89,7 +89,7 @@ static wchar_t *stow(const char *str) {
 }
 
 /* Maps a UTF-16 (wide character) string to a character string. */
-static char *wtos(const wchar_t *str) {
+char *wtos(const wchar_t *str) {
   char *res = NULL;
   int len;
   if (str) {

+ 5 - 1
src/sg_utils.h

@@ -7,7 +7,7 @@
  *
  * Cross-platform library which helps to develop web servers or frameworks.
  *
- * Copyright (C) 2016-2020 Silvio Clecio <[email protected]>
+ * Copyright (C) 2016-2021 Silvio Clecio <[email protected]>
  *
  * Sagui library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -55,6 +55,10 @@ struct sg__math_manager {
 
 SG__EXTERN char *strndup(const char *s, size_t n);
 
+SG__EXTERN wchar_t *stow(const char *str);
+
+SG__EXTERN char *wtos(const wchar_t *str);
+
 SG__EXTERN int sg__rename(const char *old, const char *new);
 
 #else /* _WIN32 */