libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

authorization_example.c (4596B)


      1 /*
      2      This file is part of libmicrohttpd
      3      Copyright (C) 2008 Christian Grothoff (and other contributing authors)
      4      Copyright (C) 2014-2022 Evgeny Grin (Karlson2k)
      5 
      6      This library is free software; you can redistribute it and/or
      7      modify it under the terms of the GNU Lesser General Public
      8      License as published by the Free Software Foundation; either
      9      version 2.1 of the License, or (at your option) any later version.
     10 
     11      This library is distributed in the hope that it will be useful,
     12      but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14      Lesser General Public License for more details.
     15 
     16      You should have received a copy of the GNU Lesser General Public
     17      License along with this library; if not, write to the Free Software
     18      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     19 */
     20 
     21 /**
     22  * @file authorization_example.c
     23  * @brief example for how to use libmicrohttpd with HTTP authentication
     24  * @author Christian Grothoff
     25  * @author Karlson2k (Evgeny Grin)
     26  */
     27 
     28 #include "platform.h"
     29 #include <microhttpd.h>
     30 #ifdef _WIN32
     31 #ifndef WIN32_LEAN_AND_MEAN
     32 #define WIN32_LEAN_AND_MEAN 1
     33 #endif /* !WIN32_LEAN_AND_MEAN */
     34 #include <windows.h>
     35 #endif
     36 
     37 #define PAGE \
     38   "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>"
     39 
     40 #define DENIED \
     41   "<html><head><title>Access denied</title></head><body>Access denied</body></html>"
     42 
     43 
     44 static enum MHD_Result
     45 ahc_echo (void *cls,
     46           struct MHD_Connection *connection,
     47           const char *url,
     48           const char *method,
     49           const char *version,
     50           const char *upload_data, size_t *upload_data_size, void **req_cls)
     51 {
     52   static int aptr;
     53   struct MHD_Response *response;
     54   enum MHD_Result ret;
     55   struct MHD_BasicAuthInfo *auth_info;
     56   int fail;
     57   (void) cls;               /* Unused. Silent compiler warning. */
     58   (void) url;               /* Unused. Silent compiler warning. */
     59   (void) version;           /* Unused. Silent compiler warning. */
     60   (void) upload_data;       /* Unused. Silent compiler warning. */
     61   (void) upload_data_size;  /* Unused. Silent compiler warning. */
     62 
     63   if (0 != strcmp (method, "GET"))
     64     return MHD_NO;              /* unexpected method */
     65   if (&aptr != *req_cls)
     66   {
     67     /* do never respond on first call */
     68     *req_cls = &aptr;
     69     return MHD_YES;
     70   }
     71   *req_cls = NULL;                  /* reset when done */
     72 
     73   /* require: "Aladdin" with password "open sesame" */
     74   auth_info = MHD_basic_auth_get_username_password3 (connection);
     75   fail = ( (NULL == auth_info) ||
     76            (strlen ("Aladdin") != auth_info->username_len) ||
     77            (0 != memcmp (auth_info->username, "Aladdin",
     78                          auth_info->username_len)) ||
     79            /* The next check against NULL is optional,
     80             * if 'password' is NULL then 'password_len' is always zero. */
     81            (NULL == auth_info->password) ||
     82            (strlen ("open sesame") != auth_info->password_len) ||
     83            (0 != memcmp (auth_info->password, "open sesame",
     84                          auth_info->password_len)) );
     85   if (fail)
     86   {
     87     response =
     88       MHD_create_response_from_buffer_static (strlen (DENIED),
     89                                               (const void *) DENIED);
     90     ret = MHD_queue_basic_auth_required_response3 (connection,
     91                                                    "TestRealm",
     92                                                    MHD_NO,
     93                                                    response);
     94   }
     95   else
     96   {
     97     response =
     98       MHD_create_response_from_buffer_static (strlen (PAGE),
     99                                               (const void *) PAGE);
    100     ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
    101   }
    102   if (NULL != auth_info)
    103     MHD_free (auth_info);
    104   MHD_destroy_response (response);
    105   return ret;
    106 }
    107 
    108 
    109 int
    110 main (int argc, char *const *argv)
    111 {
    112   struct MHD_Daemon *d;
    113   unsigned int port;
    114 
    115   if ( (argc != 2) ||
    116        (1 != sscanf (argv[1], "%u", &port)) ||
    117        (65535 < port) )
    118   {
    119     fprintf (stderr,
    120              "%s PORT\n", argv[0]);
    121     return 1;
    122   }
    123 
    124   d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
    125                         | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
    126                         (uint16_t) port,
    127                         NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
    128   if (d == NULL)
    129     return 1;
    130   fprintf (stderr, "HTTP server running. Press ENTER to stop the server.\n");
    131   (void) getc (stdin);
    132   MHD_stop_daemon (d);
    133   return 0;
    134 }