libmicrohttpd: import fixes from subversion repo
authorDaniel Golle <redacted>
Fri, 5 Jun 2015 01:26:00 +0000 (03:26 +0200)
committerDaniel Golle <redacted>
Thu, 25 Jun 2015 21:28:54 +0000 (23:28 +0200)
Fixes a memleak as well as a bug in digest authentication.

Signed-off-by: Daniel Golle <redacted>
libs/libmicrohttpd/Makefile
libs/libmicrohttpd/patches/001-bump-to-r35864.patch [new file with mode: 0644]

index d47875cecb49f3529d4ce6b49ebd9831525520ee..9c9dcbae59926afe03a28b3e4dd43dc29a2e57ea 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libmicrohttpd
 PKG_VERSION:=0.9.42
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=@GNU/libmicrohttpd
diff --git a/libs/libmicrohttpd/patches/001-bump-to-r35864.patch b/libs/libmicrohttpd/patches/001-bump-to-r35864.patch
new file mode 100644 (file)
index 0000000..6558a96
--- /dev/null
@@ -0,0 +1,754 @@
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,14 @@
++Thu Jun  4 13:37:05 CEST 2015
++      Fixing memory leak in digest authentication. -AW
++
++Wed Jun 03 21:23:47 CEST 2015
++      Add deprecation compiler messages for deprecated functions 
++      and macros. -EG
++
++Fri May 29 12:23:01 CEST 2015
++      Fixing digest authentication when used in combination
++      with escaped characters in URLs. -CG/AW
++
+ Wed May 13 11:49:09 CEST 2015
+       Releasing libmicrohttpd 0.9.42. -CG
+--- a/src/microhttpd/response.c
++++ b/src/microhttpd/response.c
+@@ -24,6 +24,8 @@
+  * @author Christian Grothoff
+  */
++#define MHD_NO_DEPRECATION 1
++
+ #include "internal.h"
+ #include "response.h"
+--- a/src/microhttpd/digestauth.c
++++ b/src/microhttpd/digestauth.c
+@@ -1,6 +1,6 @@
+ /*
+      This file is part of libmicrohttpd
+-     Copyright (C) 2010, 2011, 2012 Daniel Pittman and Christian Grothoff
++     Copyright (C) 2010, 2011, 2012, 2015 Daniel Pittman and Christian Grothoff
+      This library is free software; you can redistribute it and/or
+      modify it under the terms of the GNU Lesser General Public
+@@ -472,8 +472,8 @@ test_header (struct MHD_Connection *conn
+  *
+  * @param connection connections with headers to compare against
+  * @param args argument URI string (after "?" in URI)
+- * @return MHD_YES if the arguments match,
+- *         MHD_NO if not
++ * @return #MHD_YES if the arguments match,
++ *         #MHD_NO if not
+  */
+ static int
+ check_argument_match (struct MHD_Connection *connection,
+@@ -508,7 +508,10 @@ check_argument_match (struct MHD_Connect
+                                                connection,
+                                                argp);
+         if (MHD_YES != test_header (connection, argp, NULL))
+-          return MHD_NO;
++      {
++        free(argb);
++        return MHD_NO;
++      }
+         num_headers++;
+         break;
+       }
+@@ -527,10 +530,16 @@ check_argument_match (struct MHD_Connect
+                                            connection,
+                                            equals);
+       if (! test_header (connection, argp, equals))
+-      return MHD_NO;
++      {
++          free(argb);
++          return MHD_NO;
++      }
++      
+       num_headers++;
+       argp = amper;
+     }
++    
++  free(argb);
+   /* also check that the number of headers matches */
+   for (pos = connection->headers_received; NULL != pos; pos = pos->next)
+@@ -632,10 +641,83 @@ MHD_digest_auth_check (struct MHD_Connec
+        header value. */
+     return MHD_NO;
+   }
++  /* 8 = 4 hexadecimal numbers for the timestamp */
++  nonce_time = strtoul (nonce + len - 8, (char **)NULL, 16);
++  t = (uint32_t) MHD_monotonic_time();
++  /*
++   * First level vetting for the nonce validity: if the timestamp
++   * attached to the nonce exceeds `nonce_timeout', then the nonce is
++   * invalid.
++   */
++  if ( (t > nonce_time + nonce_timeout) ||
++       (nonce_time + nonce_timeout < nonce_time) )
++    {
++      /* too old */
++      return MHD_INVALID_NONCE;
++    }
++
++  calculate_nonce (nonce_time,
++                   connection->method,
++                   connection->daemon->digest_auth_random,
++                   connection->daemon->digest_auth_rand_size,
++                   connection->url,
++                   realm,
++                   noncehashexp);
++  /*
++   * Second level vetting for the nonce validity
++   * if the timestamp attached to the nonce is valid
++   * and possibly fabricated (in case of an attack)
++   * the attacker must also know the random seed to be
++   * able to generate a "sane" nonce, which if he does
++   * not, the nonce fabrication process going to be
++   * very hard to achieve.
++   */
++
++  if (0 != strcmp (nonce, noncehashexp))
++    {
++      return MHD_INVALID_NONCE;
++    }
++  if ( (0 == lookup_sub_value (cnonce,
++                               sizeof (cnonce),
++                               header, "cnonce")) ||
++       (0 == lookup_sub_value (qop, sizeof (qop), header, "qop")) ||
++       ( (0 != strcmp (qop, "auth")) &&
++         (0 != strcmp (qop, "")) ) ||
++       (0 == lookup_sub_value (nc, sizeof (nc), header, "nc"))  ||
++       (0 == lookup_sub_value (response, sizeof (response), header, "response")) )
++    {
++#if HAVE_MESSAGES
++      MHD_DLOG (connection->daemon,
++              "Authentication failed, invalid format.\n");
++#endif
++      return MHD_NO;
++    }
++  nci = strtoul (nc, &end, 16);
++  if ( ('\0' != *end) ||
++       ( (LONG_MAX == nci) &&
++         (ERANGE == errno) ) )
++    {
++#if HAVE_MESSAGES
++      MHD_DLOG (connection->daemon,
++              "Authentication failed, invalid format.\n");
++#endif
++      return MHD_NO; /* invalid nonce format */
++    }
++  /*
++   * Checking if that combination of nonce and nc is sound
++   * and not a replay attack attempt. Also adds the nonce
++   * to the nonce-nc map if it does not exist there.
++   */
++
++  if (MHD_YES != check_nonce_nc (connection, nonce, nci))
++    {
++      return MHD_NO;
++    }
++
+   {
+     char *uri;
+-    
+-    uri = malloc(left + 1);
++
++    uri = malloc (left + 1);
+     if (NULL == uri)
+     {
+ #if HAVE_MESSAGES
+@@ -648,24 +730,31 @@ MHD_digest_auth_check (struct MHD_Connec
+                                left + 1,
+                                header, "uri"))
+     {
+-      free(uri);
++      free (uri);
+       return MHD_NO;
+     }
+-    /* 8 = 4 hexadecimal numbers for the timestamp */
+-    nonce_time = strtoul (nonce + len - 8, (char **)NULL, 16);
+-    t = (uint32_t) MHD_monotonic_time();
+-    /*
+-     * First level vetting for the nonce validity: if the timestamp
+-     * attached to the nonce exceeds `nonce_timeout', then the nonce is
+-     * invalid.
+-     */
+-    if ( (t > nonce_time + nonce_timeout) ||
+-       (nonce_time + nonce_timeout < nonce_time) )
+-    { 
+-      free(uri);
+-      return MHD_INVALID_NONCE;
+-    }
++    digest_calc_ha1("md5",
++                  username,
++                  realm,
++                  password,
++                  nonce,
++                  cnonce,
++                  ha1);
++    digest_calc_response (ha1,
++                        nonce,
++                        nc,
++                        cnonce,
++                        qop,
++                        connection->method,
++                        uri,
++                        hentity,
++                        respexp);
++
++    /* Need to unescape URI before comparing with connection->url */
++    connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls,
++                                           connection,
++                                           uri);
+     if (0 != strncmp (uri,
+                     connection->url,
+                     strlen (connection->url)))
+@@ -674,9 +763,10 @@ MHD_digest_auth_check (struct MHD_Connec
+       MHD_DLOG (connection->daemon,
+               "Authentication failed, URI does not match.\n");
+ #endif
+-      free(uri);
++      free (uri);
+       return MHD_NO;
+     }
++
+     {
+       const char *args = strchr (uri, '?');
+@@ -692,89 +782,11 @@ MHD_digest_auth_check (struct MHD_Connec
+       MHD_DLOG (connection->daemon,
+                 "Authentication failed, arguments do not match.\n");
+ #endif
+-       free(uri);
++       free (uri);
+        return MHD_NO;
+       }
+     }
+-    calculate_nonce (nonce_time,
+-                   connection->method,
+-                   connection->daemon->digest_auth_random,
+-                   connection->daemon->digest_auth_rand_size,
+-                   connection->url,
+-                   realm,
+-                   noncehashexp);
+-    /*
+-     * Second level vetting for the nonce validity
+-     * if the timestamp attached to the nonce is valid
+-     * and possibly fabricated (in case of an attack)
+-     * the attacker must also know the random seed to be
+-     * able to generate a "sane" nonce, which if he does
+-     * not, the nonce fabrication process going to be
+-     * very hard to achieve.
+-     */
+-
+-    if (0 != strcmp (nonce, noncehashexp))
+-    {
+-      free(uri);
+-      return MHD_INVALID_NONCE;
+-    }
+-    if ( (0 == lookup_sub_value (cnonce,
+-                               sizeof (cnonce),
+-                               header, "cnonce")) ||
+-       (0 == lookup_sub_value (qop, sizeof (qop), header, "qop")) ||
+-       ( (0 != strcmp (qop, "auth")) &&
+-         (0 != strcmp (qop, "")) ) ||
+-       (0 == lookup_sub_value (nc, sizeof (nc), header, "nc"))  ||
+-       (0 == lookup_sub_value (response, sizeof (response), header, "response")) )
+-    {
+-#if HAVE_MESSAGES
+-      MHD_DLOG (connection->daemon,
+-              "Authentication failed, invalid format.\n");
+-#endif
+-      free(uri);
+-      return MHD_NO;
+-    }
+-    nci = strtoul (nc, &end, 16);
+-    if ( ('\0' != *end) ||
+-       ( (LONG_MAX == nci) &&
+-         (ERANGE == errno) ) )
+-    {
+-#if HAVE_MESSAGES
+-      MHD_DLOG (connection->daemon,
+-              "Authentication failed, invalid format.\n");
+-#endif
+-      free(uri);
+-      return MHD_NO; /* invalid nonce format */
+-    }
+-    /*
+-     * Checking if that combination of nonce and nc is sound
+-     * and not a replay attack attempt. Also adds the nonce
+-     * to the nonce-nc map if it does not exist there.
+-     */
+-
+-    if (MHD_YES != check_nonce_nc (connection, nonce, nci))
+-    {
+-      free(uri);
+-      return MHD_NO;
+-    }
+-
+-    digest_calc_ha1("md5",
+-                  username,
+-                  realm,
+-                  password,
+-                  nonce,
+-                  cnonce,
+-                  ha1);
+-    digest_calc_response (ha1,
+-                        nonce,
+-                        nc,
+-                        cnonce,
+-                        qop,
+-                        connection->method,
+-                        uri,
+-                        hentity,
+-                        respexp);
+-    free(uri);
++    free (uri);
+     return (0 == strcmp(response, respexp))
+       ? MHD_YES
+       : MHD_NO;
+@@ -835,7 +847,7 @@ MHD_queue_auth_fail_response (struct MHD
+                  : "");
+   {
+     char *header;
+-    
++
+     header = malloc(hlen + 1);
+     if (NULL == header)
+     {
+--- a/src/microhttpd/daemon.c
++++ b/src/microhttpd/daemon.c
+@@ -73,7 +73,7 @@
+ /**
+  * Default connection limit.
+  */
+-#ifndef WINDOWS
++#ifndef MHD_WINSOCK_SOCKETS
+ #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4
+ #else
+ #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
+@@ -1271,7 +1271,7 @@ internal_add_connection (struct MHD_Daem
+       return MHD_NO;
+     }
+-#ifndef WINDOWS
++#ifndef MHD_WINSOCK_SOCKETS
+   if ( (client_socket >= FD_SETSIZE) &&
+        (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) )
+     {
+@@ -1418,7 +1418,7 @@ internal_add_connection (struct MHD_Daem
+ #endif
+       {
+         /* make socket non-blocking */
+-#if !defined(WINDOWS) || defined(CYGWIN)
++#if !defined(MHD_WINSOCK_SOCKETS)
+         int flags = fcntl (connection->socket_fd, F_GETFL);
+         if ( (-1 == flags) ||
+              (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
+@@ -1797,7 +1797,7 @@ static void
+ make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
+                                MHD_socket sock)
+ {
+-#ifdef WINDOWS
++#ifdef MHD_WINSOCK_SOCKETS
+   DWORD dwFlags;
+   unsigned long flags = 1;
+@@ -3611,7 +3611,7 @@ MHD_start_daemon_va (unsigned int flags,
+   daemon->socket_fd = MHD_INVALID_SOCKET;
+   daemon->listening_address_reuse = 0;
+   daemon->options = flags;
+-#if WINDOWS
++#if defined(MHD_WINSOCK_SOCKETS) || defined(CYGWIN)
+   /* Winsock is broken with respect to 'shutdown';
+      this disables us calling 'shutdown' on W32. */
+   daemon->options |= MHD_USE_EPOLL_TURBO;
+@@ -3650,7 +3650,7 @@ MHD_start_daemon_va (unsigned int flags,
+       free (daemon);
+       return NULL;
+     }
+-#ifndef WINDOWS
++#ifndef MHD_WINSOCK_SOCKETS
+   if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) &&
+        (1 == use_pipe) &&
+        (daemon->wpipe[0] >= FD_SETSIZE) )
+@@ -3934,7 +3934,7 @@ MHD_start_daemon_va (unsigned int flags,
+            (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
+            and may also be missing on older POSIX systems; good luck if you have any of those,
+            your IPv6 socket may then also bind against IPv4 anyway... */
+-#ifndef WINDOWS
++#ifndef MHD_WINSOCK_SOCKETS
+         const int
+ #else
+         const char
+@@ -4016,7 +4016,7 @@ MHD_start_daemon_va (unsigned int flags,
+     {
+       socket_fd = daemon->socket_fd;
+     }
+-#ifndef WINDOWS
++#ifndef MHD_WINSOCK_SOCKETS
+   if ( (socket_fd >= FD_SETSIZE) &&
+        (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
+     {
+@@ -4121,7 +4121,7 @@ MHD_start_daemon_va (unsigned int flags,
+   if ( (daemon->worker_pool_size > 0) &&
+        (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
+     {
+-#if !defined(WINDOWS) || defined(CYGWIN)
++#if !defined(MHD_WINSOCK_SOCKETS)
+       int sk_flags;
+ #else
+       unsigned long sk_flags;
+@@ -4140,7 +4140,7 @@ MHD_start_daemon_va (unsigned int flags,
+       /* Accept must be non-blocking. Multiple children may wake up
+        * to handle a new connection, but only one will win the race.
+        * The others must immediately return. */
+-#if !defined(WINDOWS) || defined(CYGWIN)
++#if !defined(MHD_WINSOCK_SOCKETS)
+       sk_flags = fcntl (socket_fd, F_GETFL);
+       if (sk_flags < 0)
+         goto thread_failed;
+@@ -4150,7 +4150,7 @@ MHD_start_daemon_va (unsigned int flags,
+       sk_flags = 1;
+       if (SOCKET_ERROR == ioctlsocket (socket_fd, FIONBIO, &sk_flags))
+         goto thread_failed;
+-#endif /* WINDOWS && !CYGWIN */
++#endif /* MHD_WINSOCK_SOCKETS */
+       /* Allocate memory for pooled objects */
+       daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
+@@ -4182,7 +4182,7 @@ MHD_start_daemon_va (unsigned int flags,
+ #endif
+               goto thread_failed;
+             }
+-#ifndef WINDOWS
++#ifndef MHD_WINSOCK_SOCKETS
+           if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) &&
+                (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
+                (d->wpipe[0] >= FD_SETSIZE) )
+@@ -4343,7 +4343,7 @@ close_all_connections (struct MHD_Daemon
+     {
+       shutdown (pos->socket_fd,
+                 (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
+-#if WINDOWS
++#if MHD_WINSOCK_SOCKETS
+       if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+            (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
+            (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1)) )
+--- a/src/include/microhttpd.h
++++ b/src/include/microhttpd.h
+@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
+  * Current version of the library.
+  * 0x01093001 = 1.9.30-1.
+  */
+-#define MHD_VERSION 0x00094200
++#define MHD_VERSION 0x00094202
+ /**
+  * MHD-internal return code for "YES".
+@@ -194,6 +194,53 @@ typedef SOCKET MHD_socket;
+ #endif /* MHD_SOCKET_DEFINED */
+ /**
++ * Define MHD_NO_DEPRECATION before including "microhttpd.h" to disable deprecation messages
++ */
++#ifdef MHD_NO_DEPRECATION
++#define _MHD_DEPR_MACRO(msg)
++#define _MHD_DEPR_FUNC(msg)
++#endif /* MHD_NO_DEPRECATION */
++
++#ifndef _MHD_DEPR_MACRO
++#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1500
++/* Stringify macros */
++#define _MHD_INSTRMACRO(a) #a
++#define _MHD_STRMACRO(a) _MHD_INSTRMACRO(a)
++#define _MHD_DEPR_MACRO(msg) __pragma(message(__FILE__ "(" _MHD_STRMACRO(__LINE__)"): warning: " msg))
++#elif defined(__clang__) || defined (__GNUC_PATCHLEVEL__)
++#define _MHD_GCC_PRAG(x) _Pragma (#x)
++#if __clang_major__+0 >= 5 || \
++  (!defined(__apple_build_version__) && (__clang_major__+0  > 3 || (__clang_major__+0 == 3 && __clang_minor__ >= 3))) || \
++  __GNUC__+0 > 4 || (__GNUC__+0 == 4 && __GNUC_MINOR__+0 >= 8)
++#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(GCC warning msg)
++#else /* older clang or GCC */
++#define _MHD_DEPR_MACRO(msg) _MHD_GCC_PRAG(message msg)
++#endif 
++/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */
++#else /* other compilers */
++#define _MHD_DEPR_MACRO(msg)
++#endif
++#endif /* _MHD_DEPR_MACRO */
++
++#ifndef _MHD_DEPR_FUNC
++#if defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1400
++#define _MHD_DEPR_FUNC(msg) __declspec(deprecated(msg))
++#elif defined(_MSC_FULL_VER) && _MSC_VER+0 >= 1310
++/* VS .NET 2003 deprecation do not support custom messages */
++#define _MHD_DEPR_FUNC(msg) __declspec(deprecated)
++#elif defined (__clang__) && \
++  (__clang_major__+0 >= 4 || (!defined(__apple_build_version__) && __clang_major__+0 >= 3))
++#define _MHD_DEPR_FUNC(msg) __attribute__((deprecated(msg)))
++#elif defined (__clang__) || __GNUC__+0 > 3 || (__GNUC__+0 == 3 && __GNUC_MINOR__+0 >= 1)
++/* GCC-style deprecation do not support custom messages */
++#define _MHD_DEPR_FUNC(msg) __attribute__((__deprecated__))
++/* #elif defined(SOMEMACRO) */ /* add compiler-specific macros here if required */
++#else /* other compilers */
++#define _MHD_DEPR_FUNC(msg)
++#endif
++#endif /* _MHD_DEPR_FUNC */
++
++/**
+  * Not all architectures and `printf()`'s support the `long long` type.
+  * This gives the ability to replace `long long` with just a `long`,
+  * standard `int` or a `short`.
+@@ -204,6 +251,8 @@ typedef SOCKET MHD_socket;
+  */
+ #define MHD_LONG_LONG long long
+ #define MHD_UNSIGNED_LONG_LONG unsigned long long
++#else /* MHD_LONG_LONG */
++_MHD_DEPR_MACRO("Macro MHD_LONG_LONG is deprecated, use MHD_UNSIGNED_LONG_LONG")
+ #endif
+ /**
+  * Format string for printing a variable of type #MHD_LONG_LONG.
+@@ -215,6 +264,8 @@ typedef SOCKET MHD_socket;
+  */
+ #define MHD_LONG_LONG_PRINTF "ll"
+ #define MHD_UNSIGNED_LONG_LONG_PRINTF "%llu"
++#else /* MHD_LONG_LONG_PRINTF */
++_MHD_DEPR_MACRO("Macro MHD_LONG_LONG_PRINTF is deprecated, use MHD_UNSIGNED_LONG_LONG_PRINTF")
+ #endif
+@@ -253,7 +304,8 @@ typedef SOCKET MHD_socket;
+ #define MHD_HTTP_METHOD_NOT_ALLOWED 405
+ #define MHD_HTTP_NOT_ACCEPTABLE 406
+ /** @deprecated */
+-#define MHD_HTTP_METHOD_NOT_ACCEPTABLE 406
++#define MHD_HTTP_METHOD_NOT_ACCEPTABLE \
++  _MHD_DEPR_MACRO("Value MHD_HTTP_METHOD_NOT_ACCEPTABLE is deprecated, use MHD_HTTP_NOT_ACCEPTABLE") 406
+ #define MHD_HTTP_PROXY_AUTHENTICATION_REQUIRED 407
+ #define MHD_HTTP_REQUEST_TIMEOUT 408
+ #define MHD_HTTP_CONFLICT 409
+@@ -1953,6 +2005,7 @@ MHD_create_response_from_callback (uint6
+  * @deprecated use #MHD_create_response_from_buffer instead
+  * @ingroup response
+  */
++_MHD_DEPR_FUNC("MHD_create_response_from_data() is deprecated, use MHD_create_response_from_buffer()") \
+ _MHD_EXTERN struct MHD_Response *
+ MHD_create_response_from_data (size_t size,
+                              void *data,
+@@ -2023,6 +2076,8 @@ MHD_create_response_from_buffer (size_t
+  * @return NULL on error (i.e. invalid arguments, out of memory)
+  * @ingroup response
+  */
++/* NOTE: this should be 'uint64_t' instead of 'size_t', but changing
++   this would break API compatibility. */
+ _MHD_EXTERN struct MHD_Response *
+ MHD_create_response_from_fd (size_t size,
+                            int fd);
+@@ -2044,6 +2099,8 @@ MHD_create_response_from_fd (size_t size
+  * @return NULL on error (i.e. invalid arguments, out of memory)
+  * @ingroup response
+  */
++/* NOTE: this should be 'uint64_t' instead of 'size_t', but changing
++   this would break API compatibility. */
+ _MHD_EXTERN struct MHD_Response *
+ MHD_create_response_from_fd_at_offset (size_t size,
+                                      int fd,
+--- a/src/include/platform_interface.h
++++ b/src/include/platform_interface.h
+@@ -82,14 +82,14 @@
+ /* MHD_socket_close_(fd) close any FDs (non-W32) / close only socket FDs (W32) */
+-#if !defined(_WIN32) || defined(__CYGWIN__)
++#if !defined(MHD_WINSOCK_SOCKETS)
+ #define MHD_socket_close_(fd) close((fd))
+ #else
+ #define MHD_socket_close_(fd) closesocket((fd))
+ #endif
+ /* MHD_socket_errno_ is errno of last function (non-W32) / errno of last socket function (W32) */
+-#if !defined(_WIN32) || defined(__CYGWIN__)
++#if !defined(MHD_WINSOCK_SOCKETS)
+ #define MHD_socket_errno_ errno
+ #else
+ #define MHD_socket_errno_ MHD_W32_errno_from_winsock_()
+@@ -97,21 +97,21 @@
+ /* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
+  *                            description string of last socket error (W32) */
+-#if !defined(_WIN32) || defined(__CYGWIN__)
++#if !defined(MHD_WINSOCK_SOCKETS)
+ #define MHD_socket_last_strerr_() strerror(errno)
+ #else
+ #define MHD_socket_last_strerr_() MHD_W32_strerror_last_winsock_()
+ #endif
+ /* MHD_strerror_ is strerror (both non-W32/W32) */
+-#if !defined(_WIN32) || defined(__CYGWIN__)
++#if !defined(MHD_WINSOCK_SOCKETS)
+ #define MHD_strerror_(errnum) strerror((errnum))
+ #else
+ #define MHD_strerror_(errnum) MHD_W32_strerror_((errnum))
+ #endif
+ /* MHD_set_socket_errno_ set errno to errnum (non-W32) / set socket last error to errnum (W32) */
+-#if !defined(_WIN32) || defined(__CYGWIN__)
++#if !defined(MHD_WINSOCK_SOCKETS)
+ #define MHD_set_socket_errno_(errnum) errno=(errnum)
+ #else
+ #define MHD_set_socket_errno_(errnum) MHD_W32_set_last_winsock_error_((errnum))
+--- a/src/testcurl/test_digestauth.c
++++ b/src/testcurl/test_digestauth.c
+@@ -73,7 +73,8 @@ ahc_echo (void *cls,
+           const char *url,
+           const char *method,
+           const char *version,
+-          const char *upload_data, size_t *upload_data_size,
++          const char *upload_data,
++          size_t *upload_data_size,
+           void **unused)
+ {
+   struct MHD_Response *response;
+@@ -82,44 +83,47 @@ ahc_echo (void *cls,
+   const char *realm = "test@example.com";
+   int ret;
+-  username = MHD_digest_auth_get_username(connection);
++  username = MHD_digest_auth_get_username (connection);
+   if ( (username == NULL) ||
+        (0 != strcmp (username, "testuser")) )
+     {
+-      response = MHD_create_response_from_buffer(strlen (DENIED), 
+-                                               DENIED,
+-                                               MHD_RESPMEM_PERSISTENT);  
++      response = MHD_create_response_from_buffer (strlen (DENIED),
++                                                  DENIED,
++                                                  MHD_RESPMEM_PERSISTENT);
+       ret = MHD_queue_auth_fail_response(connection, realm,
+                                        MY_OPAQUE,
+                                        response,
+-                                       MHD_NO);    
+-      MHD_destroy_response(response);  
++                                       MHD_NO);
++      MHD_destroy_response(response);
+       return ret;
+     }
+   ret = MHD_digest_auth_check(connection, realm,
+-                            username, 
+-                            password, 
++                            username,
++                            password,
+                             300);
+   free(username);
+   if ( (ret == MHD_INVALID_NONCE) ||
+        (ret == MHD_NO) )
+     {
+-      response = MHD_create_response_from_buffer(strlen (DENIED), 
++      response = MHD_create_response_from_buffer(strlen (DENIED),
+                                                DENIED,
+-                                               MHD_RESPMEM_PERSISTENT);  
+-      if (NULL == response) 
++                                               MHD_RESPMEM_PERSISTENT);
++      if (NULL == response)
+       return MHD_NO;
+       ret = MHD_queue_auth_fail_response(connection, realm,
+                                        MY_OPAQUE,
+                                        response,
+-                                       (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);  
+-      MHD_destroy_response(response);  
++                                       (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
++      MHD_destroy_response(response);
+       return ret;
+     }
+-  response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
+-                                           MHD_RESPMEM_PERSISTENT);
+-  ret = MHD_queue_response(connection, MHD_HTTP_OK, response);  
+-  MHD_destroy_response(response);
++  response = MHD_create_response_from_buffer (strlen(PAGE),
++                                              PAGE,
++                                              MHD_RESPMEM_PERSISTENT);
++  ret = MHD_queue_response (connection,
++                            MHD_HTTP_OK,
++                            response);
++  MHD_destroy_response (response);
+   return ret;
+ }
+@@ -144,24 +148,24 @@ testDigestAuth ()
+   fd = open("/dev/urandom", O_RDONLY);
+   if (-1 == fd)
+     {
+-        fprintf(stderr, "Failed to open `%s': %s\n",
+-             "/dev/urandom",
+-                 strerror(errno));
+-        return 1;
+-      }
++      fprintf(stderr, "Failed to open `%s': %s\n",
++              "/dev/urandom",
++              strerror(errno));
++      return 1;
++    }
+   while (off < 8)
+-      {
+-        len = read(fd, rnd, 8);
+-        if (len == -1)
+-          {
+-                fprintf(stderr, "Failed to read `%s': %s\n",
+-                     "/dev/urandom",
+-                         strerror(errno));
+-                (void) close(fd);
+-                return 1;
+-              }
+-        off += len;
+-      }
++    {
++      len = read(fd, rnd, 8);
++      if (len == -1)
++        {
++          fprintf(stderr, "Failed to read `%s': %s\n",
++                  "/dev/urandom",
++                  strerror(errno));
++          (void) close(fd);
++          return 1;
++        }
++      off += len;
++    }
+   (void) close(fd);
+ #else
+   {
+@@ -193,7 +197,7 @@ testDigestAuth ()
+   if (d == NULL)
+     return 1;
+   c = curl_easy_init ();
+-  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/");
++  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/bar%20 foo?a=bü%20");
+   curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+   curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+   curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
+@@ -225,7 +229,6 @@ testDigestAuth ()
+ }
+-
+ int
+ main (int argc, char *const *argv)
+ {
+--- a/src/testcurl/https/test_https_time_out.c
++++ b/src/testcurl/https/test_https_time_out.c
+@@ -64,7 +64,7 @@ test_tls_session_time_out (gnutls_sessio
+   gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sd);
+-  ret = connect (sd, &sa, sizeof (struct sockaddr_in));
++  ret = connect (sd, (struct sockaddr *) &sa, sizeof (struct sockaddr_in));
+   if (ret < 0)
+     {
git clone https://git.99rst.org/PROJECT