1This is libmicrohttpd-tutorial.info, produced by makeinfo version 4.13
2from libmicrohttpd-tutorial.texi.
3
4INFO-DIR-SECTION Software libraries
5START-INFO-DIR-ENTRY
6* libmicrohttpdtutorial: (libmicrohttpd).       A tutorial for GNU libmicrohttpd.
7END-INFO-DIR-ENTRY
8
9   This tutorial documents GNU libmicrohttpd version 0.9.23, last
10updated 17 November 2013.
11
12   Copyright (c)  2008  Sebastian Gerhardt.
13
14   Copyright (c)  2010, 2011, 2012, 2013  Christian Grothoff.
15
16     Permission is granted to copy, distribute and/or modify this
17     document under the terms of the GNU Free Documentation License,
18     Version 1.3 or any later version published by the Free Software
19     Foundation; with no Invariant Sections, no Front-Cover Texts, and
20     no Back-Cover Texts.  A copy of the license is included in the
21     section entitled "GNU Free Documentation License".
22
23
24File: libmicrohttpd-tutorial.info,  Node: Top,  Next: Introduction,  Up: (dir)
25
26A Tutorial for GNU libmicrohttpd
27********************************
28
29This tutorial documents GNU libmicrohttpd version 0.9.23, last updated
3017 November 2013.
31
32   Copyright (c)  2008  Sebastian Gerhardt.
33
34   Copyright (c)  2010, 2011, 2012, 2013  Christian Grothoff.
35
36     Permission is granted to copy, distribute and/or modify this
37     document under the terms of the GNU Free Documentation License,
38     Version 1.3 or any later version published by the Free Software
39     Foundation; with no Invariant Sections, no Front-Cover Texts, and
40     no Back-Cover Texts.  A copy of the license is included in the
41     section entitled "GNU Free Documentation License".
42
43* Menu:
44
45* Introduction::
46* Hello browser example::
47* Exploring requests::
48* Response headers::
49* Supporting basic authentication::
50* Processing POST data::
51* Improved processing of POST data::
52* Session management::
53* Adding a layer of security::
54* Bibliography::
55* License text::
56* Example programs::
57
58
59File: libmicrohttpd-tutorial.info,  Node: Introduction,  Next: Hello browser example,  Prev: Top,  Up: Top
60
611 Introduction
62**************
63
64This tutorial is for developers who want to learn how they can add HTTP
65serving capabilities to their applications with the _GNU libmicrohttpd_
66library, abbreviated _MHD_.  The reader will learn how to implement
67basic HTTP functions from simple executable sample programs that
68implement various features.
69
70   The text is supposed to be a supplement to the API reference manual
71of _GNU libmicrohttpd_ and for that reason does not explain many of the
72parameters.  Therefore, the reader should always consult the manual to
73find the exact meaning of the functions used in the tutorial.
74Furthermore, the reader is encouraged to study the relevant _RFCs_,
75which document the HTTP standard.
76
77   _GNU libmicrohttpd_ is assumed to be already installed.  This
78tutorial is written for version 0.9.23.  At the time being, this
79tutorial has only been tested on _GNU/Linux_ machines even though
80efforts were made not to rely on anything that would prevent the
81samples from being built on similar systems.
82
831.1 History
84===========
85
86This tutorial was originally written by Sebastian Gerhardt for MHD
870.4.0.  It was slighly polished and updated to MHD 0.9.0 by Christian
88Grothoff.
89
90
91File: libmicrohttpd-tutorial.info,  Node: Hello browser example,  Next: Exploring requests,  Prev: Introduction,  Up: Top
92
932 Hello browser example
94***********************
95
96The most basic task for a HTTP server is to deliver a static text
97message to any client connecting to it.  Given that this is also easy
98to implement, it is an excellent problem to start with.
99
100   For now, the particular URI the client asks for shall have no effect
101on the message that will be returned. In addition, the server shall end
102the connection after the message has been sent so that the client will
103know there is nothing more to expect.
104
105   The C program `hellobrowser.c', which is to be found in the examples
106section, does just that.  If you are very eager, you can compile and
107start it right away but it is advisable to type the lines in by
108yourself as they will be discussed and explained in detail.
109
110   After the necessary includes and the definition of the port which
111our server should listen on
112#include <sys/types.h>
113#include <sys/select.h>
114#include <sys/socket.h>
115#include <microhttpd.h>
116
117#define PORT 8888
118
119the desired behaviour of our server when HTTP request arrive has to be
120implemented. We already have agreed that it should not care about the
121particular details of the request, such as who is requesting what. The
122server will respond merely with the same small HTML page to every
123request.
124
125   The function we are going to write now will be called by _GNU
126libmicrohttpd_ every time an appropriate request comes in. While the
127name of this callback function is arbitrary, its parameter list has to
128follow a certain layout. So please, ignore the lot of parameters for
129now, they will be explained at the point they are needed. We have to
130use only one of them, `struct MHD_Connection *connection', for the
131minimalistic functionality we want to archive at the moment.
132
133   This parameter is set by the _libmicrohttpd_ daemon and holds the
134necessary information to relate the call with a certain connection.
135Keep in mind that a server might have to satisfy hundreds of concurrent
136connections and we have to make sure that the correct data is sent to
137the destined client. Therefore, this variable is a means to refer to a
138particular connection if we ask the daemon to sent the reply.
139
140   Talking about the reply, it is defined as a string right after the
141function header
142int answer_to_connection (void *cls, struct MHD_Connection *connection,
143                          const char *url,
144                          const char *method, const char *version,
145                          const char *upload_data,
146                          size_t *upload_data_size, void **con_cls)
147{
148  const char *page  = "<html><body>Hello, browser!</body></html>";
149
150HTTP is a rather strict protocol and the client would certainly
151consider it "inappropriate" if we just sent the answer string "as is".
152Instead, it has to be wrapped with additional information stored in
153so-called headers and footers.  Most of the work in this area is done
154by the library for us--we just have to ask. Our reply string packed in
155the necessary layers will be called a "response".  To obtain such a
156response we hand our data (the reply-string) and its size over to the
157`MHD_create_response_from_buffer' function. The last two parameters
158basically tell _MHD_ that we do not want it to dispose the message data
159for us when it has been sent and there also needs no internal copy to
160be done because the _constant_ string won't change anyway.
161
162  struct MHD_Response *response;
163  int ret;
164
165  response = MHD_create_response_from_buffer (strlen (page),
166                                            (void*) page, MHD_RESPMEM_PERSISTENT);
167
168Now that the the response has been laced up, it is ready for delivery
169and can be queued for sending.  This is done by passing it to another
170_GNU libmicrohttpd_ function. As all our work was done in the scope of
171one function, the recipient is without doubt the one associated with the
172local variable `connection' and consequently this variable is given to
173the queue function.  Every HTTP response is accompanied by a status
174code, here "OK", so that the client knows this response is the intended
175result of his request and not due to some error or malfunction.
176
177   Finally, the packet is destroyed and the return value from the queue
178returned, already being set at this point to either MHD_YES or MHD_NO
179in case of success or failure.
180
181  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
182  MHD_destroy_response (response);
183
184  return ret;
185}
186
187With the primary task of our server implemented, we can start the
188actual server daemon which will listen on `PORT' for connections. This
189is done in the main function.
190int main ()
191{
192  struct MHD_Daemon *daemon;
193
194  daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
195                             &answer_to_connection, NULL, MHD_OPTION_END);
196  if (NULL == daemon) return 1;
197
198The first parameter is one of three possible modes of operation. Here
199we want the daemon to run in a separate thread and to manage all
200incoming connections in the same thread. This means that while
201producing the response for one connection, the other connections will
202be put on hold. In this example, where the reply is already known and
203therefore the request is served quickly, this poses no problem.
204
205   We will allow all clients to connect regardless of their name or
206location, therefore we do not check them on connection and set the
207forth and fifth parameter to NULL.
208
209   Parameter six is the address of the function we want to be called
210whenever a new connection has been established. Our
211`answer_to_connection' knows best what the client wants and needs no
212additional information (which could be passed via the next parameter)
213so the next parameter is NULL. Likewise, we do not need to pass extra
214options to the daemon so we just write the MHD_OPTION_END as the last
215parameter.
216
217   As the server daemon runs in the background in its own thread, the
218execution flow in our main function will contine right after the call.
219Because of this, we must delay the execution flow in the main thread or
220else the program will terminate prematurely. We let it pause in a
221processing-time friendly manner by waiting for the enter key to be
222pressed. In the end, we stop the daemon so it can do its cleanup tasks.
223  getchar ();
224
225  MHD_stop_daemon (daemon);
226  return 0;
227}
228
229The first example is now complete.
230
231   Compile it with
232cc hellobrowser.c -o hellobrowser -I$PATH_TO_LIBMHD_INCLUDES
233  -L$PATH_TO_LIBMHD_LIBS -lmicrohttpd
234 with the two paths set accordingly and run it.
235
236   Now open your favorite Internet browser and go to the address
237`http://localhost:8888/', provided that 8888 is the port you chose. If
238everything works as expected, the browser will present the message of
239the static HTML page it got from our minimal server.
240
241Remarks
242=======
243
244To keep this first example as small as possible, some drastic shortcuts
245were taken and are to be discussed now.
246
247   Firstly, there is no distinction made between the kinds of requests
248a client could send. We implied that the client sends a GET request,
249that means, that he actually asked for some data. Even when it is not
250intended to accept POST requests, a good server should at least
251recognize that this request does not constitute a legal request and
252answer with an error code. This can be easily implemented by checking
253if the parameter `method' equals the string "GET" and returning a
254`MHD_NO' if not so.
255
256   Secondly, the above practice of queuing a response upon the first
257call of the callback function brings with it some limitations.  This is
258because the content of the message body will not be received if a
259response is queued in the first iteration.  Furthermore, the connection
260will be closed right after the response has been transferred then.
261This is typically not what you want as it disables HTTP pipelining.
262The correct approach is to simply not queue a message on the first
263callback unless there is an error.  The `void**' argument to the
264callback provides a location for storing information about the history
265of the connection; for the first call, the pointer will point to NULL.
266A simplistic way to differenciate the first call from others is to check
267if the pointer is NULL and set it to a non-NULL value during the first
268call.
269
270   Both of these issues you will find addressed in the official
271`minimal_example.c' residing in the `src/examples' directory of the
272_MHD_ package.  The source code of this program should look very
273familiar to you by now and easy to understand.
274
275   For our example, the `must_copy' and `must_free' parameter at the
276response construction function could be set to `MHD_NO'. In the usual
277case, responses cannot be sent immediately after being queued. For
278example, there might be other data on the system that needs to be sent
279with a higher priority. Nevertheless, the queue function will return
280successfully--raising the problem that the data we have pointed to may
281be invalid by the time it is about being sent. This is not an issue
282here because we can expect the `page' string, which is a constant
283_string literal_ here, to be static. That means it will be present and
284unchanged for as long as the program runs.  For dynamic data, one could
285choose to either have _MHD_ free the memory `page' points to itself
286when it is not longer needed or, alternatively, have the library to
287make and manage its own copy of it.
288
289Exercises
290=========
291
292   * While the server is running, use a program like `telnet' or
293     `netcat' to connect to it. Try to form a valid HTTP 1.1 request
294     yourself like GET /dontcare HTTP/1.1
295     Host: itsme
296     <enter>
297      and see what the server returns to you.
298
299   * Also, try other requests, like POST, and see how our server does
300     not mind and why.  How far in malforming a request can you go
301     before the builtin functionality of _MHD_ intervenes and an
302     altered response is sent? Make sure you read about the status
303     codes in the _RFC_.
304
305   * Add the option `MHD_USE_PEDANTIC_CHECKS' to the start function of
306     the daemon in `main'.  Mind the special format of the parameter
307     list here which is described in the manual. How indulgent is the
308     server now to your input?
309
310   * Let the main function take a string as the first command line
311     argument and pass `argv[1]' to the `MHD_start_daemon' function as
312     the sixth parameter. The address of this string will be passed to
313     the callback function via the `cls' variable. Decorate the text
314     given at the command line when the server is started with proper
315     HTML tags and send it as the response instead of the former static
316     string.
317
318   * _Demanding:_ Write a separate function returning a string
319     containing some useful information, for example, the time. Pass
320     the function's address as the sixth parameter and evaluate this
321     function on every request anew in `answer_to_connection'. Remember
322     to free the memory of the string every time after satisfying the
323     request.
324
325
326
327File: libmicrohttpd-tutorial.info,  Node: Exploring requests,  Next: Response headers,  Prev: Hello browser example,  Up: Top
328
3293 Exploring requests
330********************
331
332This chapter will deal with the information which the client sends to
333the server at every request. We are going to examine the most useful
334fields of such an request and print them out in a readable manner. This
335could be useful for logging facilities.
336
337   The starting point is the _hellobrowser_ program with the former
338response removed.
339
340   This time, we just want to collect information in the callback
341function, thus we will just return MHD_NO after we have probed the
342request. This way, the connection is closed without much ado by the
343server.
344
345static int
346answer_to_connection (void *cls, struct MHD_Connection *connection,
347                      const char *url,
348		      const char *method, const char *version,
349		      const char *upload_data,
350                      size_t *upload_data_size, void **con_cls)
351{
352  ...
353  return MHD_NO;
354}
355 The ellipsis marks the position where the following instructions shall
356be inserted.
357
358   We begin with the most obvious information available to the server,
359the request line. You should already have noted that a request consists
360of a command (or "HTTP method") and a URI (e.g. a filename).  It also
361contains a string for the version of the protocol which can be found in
362`version'.  To call it a "new request" is justified because we return
363only `MHD_NO', thus ensuring the function will not be called again for
364this connection.
365printf ("New %s request for %s using version %s\n", method, url, version);
366 The rest of the information is a bit more hidden. Nevertheless, there
367is lot of it sent from common Internet browsers. It is stored in
368"key-value" pairs and we want to list what we find in the header.  As
369there is no mandatory set of keys a client has to send, each key-value
370pair is printed out one by one until there are no more left. We do this
371by writing a separate function which will be called for each pair just
372like the above function is called for each HTTP request.  It can then
373print out the content of this pair.
374int print_out_key (void *cls, enum MHD_ValueKind kind,
375                   const char *key, const char *value)
376{
377  printf ("%s: %s\n", key, value);
378  return MHD_YES;
379}
380 To start the iteration process that calls our new function for every
381key, the line
382MHD_get_connection_values (connection, MHD_HEADER_KIND, &print_out_key, NULL);
383 needs to be inserted in the connection callback function too. The
384second parameter tells the function that we are only interested in keys
385from the general HTTP header of the request. Our iterating function
386`print_out_key' does not rely on any additional information to fulfill
387its duties so the last parameter can be NULL.
388
389   All in all, this constitutes the complete `logging.c' program for
390this chapter which can be found in the `examples' section.
391
392   Connecting with any modern Internet browser should yield a handful
393of keys. You should try to interpret them with the aid of _RFC 2616_.
394Especially worth mentioning is the "Host" key which is often used to
395serve several different websites hosted under one single IP address but
396reachable by different domain names (this is called virtual hosting).
397
398Conclusion
399==========
400
401The introduced capabilities to itemize the content of a simple GET
402request--especially the URI--should already allow the server to satisfy
403clients' requests for small specific resources (e.g. files) or even
404induce alteration of server state. However, the latter is not
405recommended as the GET method (including its header data) is by
406convention considered a "safe" operation, which should not change the
407server's state in a significant way.  By convention, GET operations can
408thus be performed by crawlers and other automatic software.  Naturally
409actions like searching for a passed string are fine.
410
411   Of course, no transmission can occur while the return value is still
412set to `MHD_NO' in the callback function.
413
414Exercises
415=========
416
417   * By parsing the `url' string and delivering responses accordingly,
418     implement a small server for "virtual" files. When asked for
419     `/index.htm{l}', let the response consist of a HTML page
420     containing a link to `/another.html' page which is also to be
421     created "on the fly" in case of being requested. If neither of
422     these two pages are requested, `MHD_HTTP_NOT_FOUND' shall be
423     returned accompanied by an informative message.
424
425   * A very interesting information has still been ignored by our
426     logger--the client's IP address.  Implement a callback function static int on_client_connect (void *cls,
427                                   const struct sockaddr *addr,
428     			      socklen_t addrlen)
429      that prints out the IP address in an appropriate format. You
430     might want to use the POSIX function `inet_ntoa' but bear in mind
431     that `addr' is actually just a structure containing other
432     substructures and is _not_ the variable this function expects.
433     Make sure to return `MHD_YES' so that the library knows the client
434     is allowed to connect (and to then process the request). If one
435     wanted to limit access basing on IP addresses, this would be the
436     place to do it. The address of your `on_client_connect' function
437     must be passed as the third parameter to the `MHD_start_daemon'
438     call.
439
440
441
442File: libmicrohttpd-tutorial.info,  Node: Response headers,  Next: Supporting basic authentication,  Prev: Exploring requests,  Up: Top
443
4444 Response headers
445******************
446
447Now that we are able to inspect the incoming request in great detail,
448this chapter discusses the means to enrich the outgoing responses
449likewise.
450
451   As you have learned in the _Hello, Browser_ chapter, some obligatory
452header fields are added and set automatically for simple responses by
453the library itself but if more advanced features are desired,
454additional fields have to be created.  One of the possible fields is
455the content type field and an example will be developed around it.
456This will lead to an application capable of correctly serving different
457types of files.
458
459   When we responded with HTML page packed in the static string
460previously, the client had no choice but guessing about how to handle
461the response, because the server had not told him.  What if we had sent
462a picture or a sound file?  Would the message have been understood or
463merely been displayed as an endless stream of random characters in the
464browser?  This is what the mime content types are for. The header of
465the response is extended by certain information about how the data is
466to be interpreted.
467
468   To introduce the concept, a picture of the format _PNG_ will be sent
469to the client and labeled accordingly with `image/png'.  Once again, we
470can base the new example on the `hellobrowser' program.
471
472#define FILENAME "picture.png"
473#define MIMETYPE "image/png"
474
475static int
476answer_to_connection (void *cls, struct MHD_Connection *connection,
477		      const char *url,
478                      const char *method, const char *version,
479		      const char *upload_data,
480              	      size_t *upload_data_size, void **con_cls)
481{
482  unsigned char *buffer = NULL;
483  struct MHD_Response *response;
484 We want the program to open the file for reading and determine its
485size:
486  int fd;
487  int ret;
488  struct stat sbuf;
489
490  if (0 != strcmp (method, "GET"))
491    return MHD_NO;
492  if ( (-1 == (fd = open (FILENAME, O_RDONLY))) ||
493       (0 != fstat (fd, &sbuf)) )
494    {
495     /* error accessing file */
496      /* ... (see below) */
497    }
498 /* ... (see below) */
499 When dealing with files, there is a lot that could go wrong on the
500server side and if so, the client should be informed with
501`MHD_HTTP_INTERNAL_SERVER_ERROR'.
502
503      /* error accessing file */
504     if (fd != -1) close (fd);
505      const char *errorstr =
506        "<html><body>An internal server error has occured!\
507                              </body></html>";
508      response =
509	MHD_create_response_from_buffer (strlen (errorstr),
510				         (void *) errorstr,
511				         MHD_RESPMEM_PERSISTENT);
512      if (response)
513        {
514          ret =
515            MHD_queue_response (connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
516                                response);
517          MHD_destroy_response (response);
518
519          return MHD_YES;
520        }
521      else
522        return MHD_NO;
523  if (!ret)
524    {
525      const char *errorstr = "<html><body>An internal server error has occured!\
526                              </body></html>";
527
528      if (buffer) free(buffer);
529
530      response = MHD_create_response_from_buffer (strlen(errorstr), (void*) errorstr,
531                                                  MHD_RESPMEM_PERSISTENT);
532
533      if (response)
534        {
535          ret = MHD_queue_response (connection,
536	      			    MHD_HTTP_INTERNAL_SERVER_ERROR,
537				    response);
538          MHD_destroy_response (response);
539
540          return MHD_YES;
541        }
542      else return MHD_NO;
543    }
544 Note that we nevertheless have to create a response object even for
545sending a simple error code.  Otherwise, the connection would just be
546closed without comment, leaving the client curious about what has
547happened.
548
549   But in the case of success a response will be constructed directly
550from the file descriptor:
551
552     /* error accessing file */
553     /* ... (see above) */
554    }
555
556  response =
557    MHD_create_response_from_fd_at_offset (sbuf.st_size, fd, 0);
558  MHD_add_response_header (response, "Content-Type", MIMETYPE);
559  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
560  MHD_destroy_response (response);
561 Note that the response object will take care of closing the file
562desciptor for us.
563
564   Up to this point, there was little new. The actual novelty is that
565we enhance the header with the meta data about the content. Aware of
566the field's name we want to add, it is as easy as that:
567MHD_add_response_header(response, "Content-Type", MIMETYPE);
568 We do not have to append a colon expected by the protocol behind the
569first field--_GNU libhttpdmicro_ will take care of this.
570
571   The function finishes with the well-known lines
572  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
573  MHD_destroy_response (response);
574  return ret;
575}
576 The complete program `responseheaders.c' is in the `examples' section
577as usual.  Find a _PNG_ file you like and save it to the directory the
578example is run from under the name `picture.png'. You should find the
579image displayed on your browser if everything worked well.
580
581Remarks
582=======
583
584The include file of the _MHD_ library comes with the header types
585mentioned in _RFC 2616_ already defined as macros. Thus, we could have
586written `MHD_HTTP_HEADER_CONTENT_TYPE' instead of `"Content-Type"' as
587well. However, one is not limited to these standard headers and could
588add custom response headers without violating the protocol. Whether,
589and how, the client would react to these custom header is up to the
590receiver. Likewise, the client is allowed to send custom request
591headers to the server as well, opening up yet more possibilities how
592client and server could communicate with each other.
593
594   The method of creating the response from a file on disk only works
595for static content.  Serving dynamically created responses will be a
596topic of a future chapter.
597
598Exercises
599=========
600
601   * Remember that the original program was written under a few
602     assumptions--a static response using a local file being one of
603     them. In order to simulate a very large or hard to reach file that
604     cannot be provided instantly, postpone the queuing in the callback
605     with the `sleep' function for 30 seconds _if_ the file `/big.png'
606     is requested (but deliver the same as above). A request for
607     `/picture.png' should provide just the same but without any
608     artificial delays.
609
610     Now start two instances of your browser (or even use two machines)
611     and see how the second client is put on hold while the first waits
612     for his request on the slow file to be fulfilled.
613
614     Finally, change the sourcecode to use
615     `MHD_USE_THREAD_PER_CONNECTION' when the daemon is started and try
616     again.
617
618   * Did you succeed in implementing the clock exercise yet? This time,
619     let the server save the program's start time `t' and implement a
620     response simulating a countdown that reaches 0 at `t+60'.
621     Returning a message saying on which point the countdown is, the
622     response should ultimately be to reply "Done" if the program has
623     been running long enough,
624
625     An unofficial, but widely understood, response header line is
626     `Refresh: DELAY; url=URL' with the uppercase words substituted to
627     tell the client it should request the given resource after the
628     given delay again. Improve your program in that the browser (any
629     modern browser should work) automatically reconnects and asks for
630     the status again every 5 seconds or so. The URL would have to be
631     composed so that it begins with "http://", followed by the _URI_
632     the server is reachable from the client's point of view.
633
634     Maybe you want also to visualize the countdown as a status bar by
635     creating a `<table>' consisting of one row and `n' columns whose
636     fields contain small images of either a red or a green light.
637
638
639
640File: libmicrohttpd-tutorial.info,  Node: Supporting basic authentication,  Next: Processing POST data,  Prev: Response headers,  Up: Top
641
6425 Supporting basic authentication
643*********************************
644
645With the small exception of IP address based access control, requests
646from all connecting clients where served equally until now.  This
647chapter discusses a first method of client's authentication and its
648limits.
649
650   A very simple approach feasible with the means already discussed
651would be to expect the password in the _URI_ string before granting
652access to the secured areas. The password could be separated from the
653actual resource identifier by a certain character, thus the request
654line might look like
655GET /picture.png?mypassword
656 In the rare situation where the client is customized enough and the
657connection occurs through secured lines (e.g., a embedded device
658directly attached to another via wire) and where the ability to embedd
659a password in the URI or to pass on a URI with a password are desired,
660this can be a reasonable choice.
661
662   But when it is assumed that the user connecting does so with an
663ordinary Internet browser, this implementation brings some problems
664about. For example, the URI including the password stays in the address
665field or at least in the history of the browser for anybody near enough
666to see.  It will also be inconvenient to add the password manually to
667any new URI when the browser does not know how to compose this
668automatically.
669
670   At least the convenience issue can be addressed by employing the
671simplest built-in password facilities of HTTP compliant browsers, hence
672we want to start there. It will however turn out to have still severe
673weaknesses in terms of security which need consideration.
674
675   Before we will start implementing _Basic Authentication_ as
676described in _RFC 2617_, we should finally abandon the bad practice of
677responding every request the first time our callback is called for a
678given connection. This is becoming more important now because the
679client and the server will have to talk in a more bi-directional way
680than before to
681
682   But how can we tell whether the callback has been called before for
683the particular connection?  Initially, the pointer this parameter
684references is set by _MHD_ in the callback. But it will also be
685"remembered" on the next call (for the same connection).  Thus, we will
686generate no response until the parameter is non-null--implying the
687callback was called before at least once. We do not need to share
688information between different calls of the callback, so we can set the
689parameter to any adress that is assured to be not null. The pointer to
690the `connection' structure will be pointing to a legal address, so we
691take this.
692
693   The first time `answer_to_connection' is called, we will not even
694look at the headers.
695
696static int
697answer_to_connection (void *cls, struct MHD_Connection *connection,
698                      const char *url, const char *method, const char *version,
699                      const char *upload_data, size_t *upload_data_size,
700                      void **con_cls)
701{
702  if (0 != strcmp(method, "GET")) return MHD_NO;
703  if (NULL == *con_cls) {*con_cls = connection; return MHD_YES;}
704
705  ...
706  /* else respond accordingly */
707  ...
708}
709 Note how we lop off the connection on the first condition (no "GET"
710request), but return asking for more on the other one with `MHD_YES'.
711With this minor change, we can proceed to implement the actual
712authentication process.
713
714Request for authentication
715==========================
716
717Let us assume we had only files not intended to be handed out without
718the correct username/password, so every "GET" request will be
719challenged.  _RFC 2617_ describes how the server shall ask for
720authentication by adding a _WWW-Authenticate_ response header with the
721name of the _realm_ protected.  MHD can generate and queue such a
722failure response for you using the `MHD_queue_basic_auth_fail_response'
723API.  The only thing you need to do is construct a response with the
724error page to be shown to the user if he aborts basic authentication.
725But first, you should check if the proper credentials were already
726supplied using the `MHD_basic_auth_get_username_password' call.
727
728   Your code would then look like this:
729static int
730answer_to_connection (void *cls, struct MHD_Connection *connection,
731                      const char *url, const char *method,
732                      const char *version, const char *upload_data,
733                      size_t *upload_data_size, void **con_cls)
734{
735  char *user;
736  char *pass;
737  int fail;
738  struct MHD_Response *response;
739
740  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
741    return MHD_NO;
742  if (NULL == *con_cls)
743    {
744      *con_cls = connection;
745      return MHD_YES;
746    }
747  pass = NULL;
748  user = MHD_basic_auth_get_username_password (connection, &pass);
749  fail = ( (user == NULL) ||
750	   (0 != strcmp (user, "root")) ||
751	   (0 != strcmp (pass, "pa$$w0rd") ) );
752  if (user != NULL) free (user);
753  if (pass != NULL) free (pass);
754  if (fail)
755    {
756      const char *page = "<html><body>Go away.</body></html>";
757      response =
758	MHD_create_response_from_buffer (strlen (page), (void *) page,
759				       MHD_RESPMEM_PERSISTENT);
760      ret = MHD_queue_basic_auth_fail_response (connection,
761						"my realm",
762						response);
763    }
764  else
765    {
766      const char *page = "<html><body>A secret.</body></html>";
767      response =
768	MHD_create_response_from_buffer (strlen (page), (void *) page,
769				       MHD_RESPMEM_PERSISTENT);
770      ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
771    }
772  MHD_destroy_response (response);
773  return ret;
774}
775
776   See the `examples' directory for the complete example file.
777
778Remarks
779=======
780
781For a proper server, the conditional statements leading to a return of
782`MHD_NO' should yield a response with a more precise status code
783instead of silently closing the connection. For example, failures of
784memory allocation are best reported as _internal server error_ and
785unexpected authentication methods as _400 bad request_.
786
787Exercises
788=========
789
790   * Make the server respond to wrong credentials (but otherwise
791     well-formed requests) with the recommended _401 unauthorized_
792     status code. If the client still does not authenticate correctly
793     within the same connection, close it and store the client's IP
794     address for a certain time. (It is OK to check for expiration not
795     until the main thread wakes up again on the next connection.) If
796     the client fails authenticating three times during this period,
797     add it to another list for which the `AcceptPolicyCallback'
798     function denies connection (temporally).
799
800   * With the network utility `netcat' connect and log the response of
801     a "GET" request as you did in the exercise of the first example,
802     this time to a file. Now stop the server and let _netcat_ listen
803     on the same port the server used to listen on and have it fake
804     being the proper server by giving the file's content as the
805     response (e.g. `cat log | nc -l -p 8888'). Pretending to think
806     your were connecting to the actual server, browse to the
807     eavesdropper and give the correct credentials.
808
809     Copy and paste the encoded string you see in `netcat''s output to
810     some of the Base64 decode tools available online and see how both
811     the user's name and password could be completely restored.
812
813
814
815File: libmicrohttpd-tutorial.info,  Node: Processing POST data,  Next: Improved processing of POST data,  Prev: Supporting basic authentication,  Up: Top
816
8176 Processing POST data
818**********************
819
820The previous chapters already have demonstrated a variety of
821possibilities to send information to the HTTP server, but it is not
822recommended that the _GET_ method is used to alter the way the server
823operates. To induce changes on the server, the _POST_ method is
824preferred over and is much more powerful than _GET_ and will be
825introduced in this chapter.
826
827   We are going to write an application that asks for the visitor's
828name and, after the user has posted it, composes an individual response
829text. Even though it was not mandatory to use the _POST_ method here,
830as there is no permanent change caused by the POST, it is an
831illustrative example on how to share data between different functions
832for the same connection. Furthermore, the reader should be able to
833extend it easily.
834
835GET request
836===========
837
838When the first _GET_ request arrives, the server shall respond with a
839HTML page containing an edit field for the name.
840
841const char* askpage = "<html><body>\
842                       What's your name, Sir?<br>\
843                       <form action=\"/namepost\" method=\"post\">\
844                       <input name=\"name\" type=\"text\"\
845                       <input type=\"submit\" value=\" Send \"></form>\
846                       </body></html>";
847 The `action' entry is the _URI_ to be called by the browser when
848posting, and the `name' will be used later to be sure it is the
849editbox's content that has been posted.
850
851   We also prepare the answer page, where the name is to be filled in
852later, and an error page as the response for anything but proper _GET_
853and _POST_ requests:
854
855const char* greatingpage="<html><body><h1>Welcome, %s!</center></h1></body></html>";
856
857const char* errorpage="<html><body>This doesn't seem to be right.</body></html>";
858 Whenever we need to send a page, we use an extra function `int
859send_page(struct MHD_Connection *connection, const char* page)' for
860this, which does not contain anything new and whose implementation is
861therefore not discussed further in the tutorial.
862
863POST request
864============
865
866Posted data can be of arbitrary and considerable size; for example, if
867a user uploads a big image to the server. Similar to the case of the
868header fields, there may also be different streams of posted data, such
869as one containing the text of an editbox and another the state of a
870button.  Likewise, we will have to register an iterator function that
871is going to be called maybe several times not only if there are
872different POSTs but also if one POST has only been received partly yet
873and needs processing before another chunk can be received.
874
875   Such an iterator function is called by a _postprocessor_, which must
876be created upon arriving of the post request.  We want the iterator
877function to read the first post data which is tagged `name' and to
878create an individual greeting string based on the template and the name.
879But in order to pass this string to other functions and still be able
880to differentiate different connections, we must first define a
881structure to share the information, holding the most import entries.
882
883struct connection_info_struct
884{
885  int connectiontype;
886  char *answerstring;
887  struct MHD_PostProcessor *postprocessor;
888};
889 With these information available to the iterator function, it is able
890to fulfill its task.  Once it has composed the greeting string, it
891returns `MHD_NO' to inform the post processor that it does not need to
892be called again. Note that this function does not handle processing of
893data for the same `key'. If we were to expect that the name will be
894posted in several chunks, we had to expand the namestring dynamically
895as additional parts of it with the same `key' came in. But in this
896example, the name is assumed to fit entirely inside one single packet.
897
898static int
899iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
900              const char *filename, const char *content_type,
901              const char *transfer_encoding, const char *data,
902	      uint64_t off, size_t size)
903{
904  struct connection_info_struct *con_info = coninfo_cls;
905
906  if (0 == strcmp (key, "name"))
907    {
908      if ((size > 0) && (size <= MAXNAMESIZE))
909        {
910          char *answerstring;
911          answerstring = malloc (MAXANSWERSIZE);
912          if (!answerstring) return MHD_NO;
913
914          snprintf (answerstring, MAXANSWERSIZE, greatingpage, data);
915          con_info->answerstring = answerstring;
916        }
917      else con_info->answerstring = NULL;
918
919      return MHD_NO;
920    }
921
922  return MHD_YES;
923}
924 Once a connection has been established, it can be terminated for many
925reasons. As these reasons include unexpected events, we have to
926register another function that cleans up any resources that might have
927been allocated for that connection by us, namely the post processor and
928the greetings string. This cleanup function must take into account that
929it will also be called for finished requests other than _POST_ requests.
930
931void request_completed (void *cls, struct MHD_Connection *connection,
932     		        void **con_cls,
933                        enum MHD_RequestTerminationCode toe)
934{
935  struct connection_info_struct *con_info = *con_cls;
936
937  if (NULL == con_info) return;
938  if (con_info->connectiontype == POST)
939    {
940      MHD_destroy_post_processor (con_info->postprocessor);
941      if (con_info->answerstring) free (con_info->answerstring);
942    }
943
944  free (con_info);
945  *con_cls = NULL;
946}
947 _GNU libmicrohttpd_ is informed that it shall call the above function
948when the daemon is started in the main function.
949
950...
951daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
952                           &answer_to_connection, NULL,
953			   MHD_OPTION_NOTIFY_COMPLETED, &request_completed, NULL,
954			   MHD_OPTION_END);
955...
956
957Request handling
958================
959
960With all other functions prepared, we can now discuss the actual
961request handling.
962
963   On the first iteration for a new request, we start by allocating a
964new instance of a `struct connection_info_struct' structure, which will
965store all necessary information for later iterations and other
966functions.
967
968static int
969answer_to_connection (void *cls, struct MHD_Connection *connection,
970		      const char *url,
971                      const char *method, const char *version,
972		      const char *upload_data,
973                      size_t *upload_data_size, void **con_cls)
974{
975  if(NULL == *con_cls)
976    {
977      struct connection_info_struct *con_info;
978
979      con_info = malloc (sizeof (struct connection_info_struct));
980      if (NULL == con_info) return MHD_NO;
981      con_info->answerstring = NULL;
982 If the new request is a _POST_, the postprocessor must be created now.
983In addition, the type of the request is stored for convenience.
984      if (0 == strcmp (method, "POST"))
985        {
986          con_info->postprocessor
987	    = MHD_create_post_processor (connection, POSTBUFFERSIZE,
988                                         iterate_post, (void*) con_info);
989
990          if (NULL == con_info->postprocessor)
991            {
992              free (con_info);
993              return MHD_NO;
994            }
995          con_info->connectiontype = POST;
996        }
997      else con_info->connectiontype = GET;
998 The address of our structure will both serve as the indicator for
999successive iterations and to remember the particular details about the
1000connection.
1001      *con_cls = (void*) con_info;
1002      return MHD_YES;
1003    }
1004 The rest of the function will not be executed on the first iteration.
1005A _GET_ request is easily satisfied by sending the question form.
1006  if (0 == strcmp (method, "GET"))
1007    {
1008      return send_page (connection, askpage);
1009    }
1010 In case of _POST_, we invoke the post processor for as long as data
1011keeps incoming, setting `*upload_data_size' to zero in order to
1012indicate that we have processed--or at least have considered--all of it.
1013  if (0 == strcmp (method, "POST"))
1014    {
1015      struct connection_info_struct *con_info = *con_cls;
1016
1017      if (*upload_data_size != 0)
1018        {
1019          MHD_post_process (con_info->postprocessor, upload_data,
1020	                    *upload_data_size);
1021          *upload_data_size = 0;
1022
1023          return MHD_YES;
1024        }
1025      else if (NULL != con_info->answerstring)
1026        return send_page (connection, con_info->answerstring);
1027    }
1028 Finally, if they are neither _GET_ nor _POST_ requests, the error page
1029is returned.
1030  return send_page(connection, errorpage);
1031}
1032 These were the important parts of the program `simplepost.c'.
1033
1034
1035File: libmicrohttpd-tutorial.info,  Node: Improved processing of POST data,  Next: Session management,  Prev: Processing POST data,  Up: Top
1036
10377 Improved processing of POST data
1038**********************************
1039
1040The previous chapter introduced a way to upload data to the server, but
1041the developed example program has some shortcomings, such as not being
1042able to handle larger chunks of data. In this chapter, we are going to
1043discuss a more advanced server program that allows clients to upload a
1044file in order to have it stored on the server's filesystem. The server
1045shall also watch and limit the number of clients concurrently
1046uploading, responding with a proper busy message if necessary.
1047
1048Prepared answers
1049================
1050
1051We choose to operate the server with the `SELECT_INTERNALLY' method.
1052This makes it easier to synchronize the global states at the cost of
1053possible delays for other connections if the processing of a request is
1054too slow. One of these variables that needs to be shared for all
1055connections is the total number of clients that are uploading.
1056
1057#define MAXCLIENTS      2
1058static unsigned int    nr_of_uploading_clients = 0;
1059 If there are too many clients uploading, we want the server to respond
1060to all requests with a busy message.
1061const char* busypage =
1062  "<html><body>This server is busy, please try again later.</body></html>";
1063 Otherwise, the server will send a _form_ that informs the user of the
1064current number of uploading clients, and ask her to pick a file on her
1065local filesystem which is to be uploaded.
1066const char* askpage = "<html><body>\n\
1067                       Upload a file, please!<br>\n\
1068                       There are %u clients uploading at the moment.<br>\n\
1069                       <form action=\"/filepost\" method=\"post\" \
1070                         enctype=\"multipart/form-data\">\n\
1071                       <input name=\"file\" type=\"file\">\n\
1072                       <input type=\"submit\" value=\" Send \"></form>\n\
1073                       </body></html>";
1074 If the upload has succeeded, the server will respond with a message
1075saying so.
1076const char* completepage = "<html><body>The upload has been completed.</body></html>";
1077 We want the server to report internal errors, such as memory shortage
1078or file access problems, adequately.
1079const char* servererrorpage
1080  = "<html><body>An internal server error has occured.</body></html>";
1081const char* fileexistspage
1082  = "<html><body>This file already exists.</body></html>";
1083 It would be tolerable to send all these responses undifferentiated
1084with a `200 HTTP_OK' status code but in order to improve the `HTTP'
1085conformance of our server a bit, we extend the `send_page' function so
1086that it accepts individual status codes.
1087
1088static int
1089send_page (struct MHD_Connection *connection,
1090	   const char* page, int status_code)
1091{
1092  int ret;
1093  struct MHD_Response *response;
1094
1095  response = MHD_create_response_from_buffer (strlen (page), (void*) page,
1096  	     				      MHD_RESPMEM_MUST_COPY);
1097  if (!response) return MHD_NO;
1098
1099  ret = MHD_queue_response (connection, status_code, response);
1100  MHD_destroy_response (response);
1101
1102  return ret;
1103}
1104 Note how we ask _MHD_ to make its own copy of the message data. The
1105reason behind this will become clear later.
1106
1107Connection cycle
1108================
1109
1110The decision whether the server is busy or not is made right at the
1111beginning of the connection. To do that at this stage is especially
1112important for _POST_ requests because if no response is queued at this
1113point, and `MHD_YES' returned, _MHD_ will not sent any queued messages
1114until a postprocessor has been created and the post iterator is called
1115at least once.
1116
1117static int
1118answer_to_connection (void *cls, struct MHD_Connection *connection,
1119		      const char *url,
1120                      const char *method, const char *version,
1121		      const char *upload_data,
1122                      size_t *upload_data_size, void **con_cls)
1123{
1124  if (NULL == *con_cls)
1125    {
1126      struct connection_info_struct *con_info;
1127
1128      if (nr_of_uploading_clients >= MAXCLIENTS)
1129        return send_page(connection, busypage, MHD_HTTP_SERVICE_UNAVAILABLE);
1130 If the server is not busy, the `connection_info' structure is
1131initialized as usual, with the addition of a filepointer for each
1132connection.
1133
1134      con_info = malloc (sizeof (struct connection_info_struct));
1135      if (NULL == con_info) return MHD_NO;
1136      con_info->fp = 0;
1137
1138      if (0 == strcmp (method, "POST"))
1139        {
1140          ...
1141        }
1142      else con_info->connectiontype = GET;
1143
1144      *con_cls = (void*) con_info;
1145
1146      return MHD_YES;
1147    }
1148 For _POST_ requests, the postprocessor is created and we register a
1149new uploading client. From this point on, there are many possible
1150places for errors to occur that make it necessary to interrupt the
1151uploading process. We need a means of having the proper response
1152message ready at all times.  Therefore, the `connection_info' structure
1153is extended to hold the most current response message so that whenever
1154a response is sent, the client will get the most informative message.
1155Here, the structure is initialized to "no error".
1156      if (0 == strcmp (method, "POST"))
1157        {
1158          con_info->postprocessor
1159	    = MHD_create_post_processor (connection, POSTBUFFERSIZE,
1160                                         iterate_post, (void*) con_info);
1161
1162          if (NULL == con_info->postprocessor)
1163            {
1164              free (con_info);
1165              return MHD_NO;
1166            }
1167
1168          nr_of_uploading_clients++;
1169
1170          con_info->connectiontype = POST;
1171          con_info->answercode = MHD_HTTP_OK;
1172          con_info->answerstring = completepage;
1173        }
1174      else con_info->connectiontype = GET;
1175 If the connection handler is called for the second time, _GET_
1176requests will be answered with the _form_. We can keep the buffer under
1177function scope, because we asked _MHD_ to make its own copy of it for
1178as long as it is needed.
1179  if (0 == strcmp (method, "GET"))
1180    {
1181      int ret;
1182      char buffer[1024];
1183
1184      sprintf (buffer, askpage, nr_of_uploading_clients);
1185      return send_page (connection, buffer, MHD_HTTP_OK);
1186    }
1187 The rest of the `answer_to_connection' function is very similar to the
1188`simplepost.c' example, except the more flexible content of the
1189responses. The _POST_ data is processed until there is none left and
1190the execution falls through to return an error page if the connection
1191constituted no expected request method.
1192  if (0 == strcmp (method, "POST"))
1193    {
1194      struct connection_info_struct *con_info = *con_cls;
1195
1196      if (0 != *upload_data_size)
1197        {
1198          MHD_post_process (con_info->postprocessor,
1199	                    upload_data, *upload_data_size);
1200          *upload_data_size = 0;
1201
1202          return MHD_YES;
1203        }
1204      else
1205        return send_page (connection, con_info->answerstring,
1206	       		  con_info->answercode);
1207    }
1208
1209  return send_page(connection, errorpage, MHD_HTTP_BAD_REQUEST);
1210}
1211
1212Storing to data
1213===============
1214
1215Unlike the `simplepost.c' example, here it is to be expected that post
1216iterator will be called several times now. This means that for any
1217given connection (there might be several concurrent of them) the posted
1218data has to be written to the correct file. That is why we store a file
1219handle in every `connection_info', so that the it is preserved between
1220successive iterations.
1221static int
1222iterate_post (void *coninfo_cls, enum MHD_ValueKind kind,
1223	      const char *key,
1224	      const char *filename, const char *content_type,
1225              const char *transfer_encoding, const char *data,
1226	      uint64_t off, size_t size)
1227{
1228  struct connection_info_struct *con_info = coninfo_cls;
1229 Because the following actions depend heavily on correct file
1230processing, which might be error prone, we default to reporting
1231internal errors in case anything will go wrong.
1232
1233con_info->answerstring = servererrorpage;
1234con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
1235 In the "askpage" _form_, we told the client to label its post data
1236with the "file" key. Anything else would be an error.
1237
1238  if (0 != strcmp (key, "file")) return MHD_NO;
1239 If the iterator is called for the first time, no file will have been
1240opened yet. The `filename' string contains the name of the file
1241(without any paths) the user selected on his system. We want to take
1242this as the name the file will be stored on the server and make sure no
1243file of that name exists (or is being uploaded) before we create one
1244(note that the code below technically contains a race between the two
1245"fopen" calls, but we will overlook this for portability sake).
1246  if (!con_info->fp)
1247    {
1248      if (NULL != (fp = fopen (filename, "rb")) )
1249        {
1250          fclose (fp);
1251          con_info->answerstring = fileexistspage;
1252          con_info->answercode = MHD_HTTP_FORBIDDEN;
1253          return MHD_NO;
1254        }
1255
1256      con_info->fp = fopen (filename, "ab");
1257      if (!con_info->fp) return MHD_NO;
1258    }
1259 Occasionally, the iterator function will be called even when there are
12600 new bytes to process. The server only needs to write data to the file
1261if there is some.
1262if (size > 0)
1263    {
1264      if (!fwrite (data, size, sizeof(char), con_info->fp))
1265        return MHD_NO;
1266    }
1267 If this point has been reached, everything worked well for this
1268iteration and the response can be set to success again. If the upload
1269has finished, this iterator function will not be called again.
1270  con_info->answerstring = completepage;
1271  con_info->answercode = MHD_HTTP_OK;
1272
1273  return MHD_YES;
1274}
1275 The new client was registered when the postprocessor was created.
1276Likewise, we unregister the client on destroying the postprocessor when
1277the request is completed.
1278void request_completed (void *cls, struct MHD_Connection *connection,
1279     		        void **con_cls,
1280                        enum MHD_RequestTerminationCode toe)
1281{
1282  struct connection_info_struct *con_info = *con_cls;
1283
1284  if (NULL == con_info) return;
1285
1286  if (con_info->connectiontype == POST)
1287    {
1288      if (NULL != con_info->postprocessor)
1289        {
1290          MHD_destroy_post_processor (con_info->postprocessor);
1291          nr_of_uploading_clients--;
1292        }
1293
1294      if (con_info->fp) fclose (con_info->fp);
1295    }
1296
1297  free (con_info);
1298  *con_cls = NULL;
1299}
1300 This is essentially the whole example `largepost.c'.
1301
1302Remarks
1303=======
1304
1305Now that the clients are able to create files on the server, security
1306aspects are becoming even more important than before. Aside from proper
1307client authentication, the server should always make sure explicitly
1308that no files will be created outside of a dedicated upload directory.
1309In particular, filenames must be checked to not contain strings like
1310"../".
1311
1312
1313File: libmicrohttpd-tutorial.info,  Node: Session management,  Next: Adding a layer of security,  Prev: Improved processing of POST data,  Up: Top
1314
13158 Session management
1316********************
1317
1318This chapter discusses how one should manage sessions, that is, share
1319state between multiple HTTP requests from the same user.  We use a
1320simple example where the user submits multiple forms and the server is
1321supposed to accumulate state from all of these forms.  Naturally, as
1322this is a network protocol, our session mechanism must support having
1323many users with many concurrent sessions at the same time.
1324
1325   In order to track users, we use a simple session cookie.  A session
1326cookie expires when the user closes the browser.  Changing from session
1327cookies to persistent cookies only requires adding an expiration time
1328to the cookie.  The server creates a fresh session cookie whenever a
1329request without a cookie is received, or if the supplied session cookie
1330is not known to the server.
1331
1332Looking up the cookie
1333=====================
1334
1335Since MHD parses the HTTP cookie header for us, looking up an existing
1336cookie is straightforward:
1337
1338FIXME.
1339
1340   Here, FIXME is the name we chose for our session cookie.
1341
1342Setting the cookie header
1343=========================
1344
1345MHD requires the user to provide the full cookie format string in order
1346to set cookies.  In order to generate a unique cookie, our example
1347creates a random 64-character text string to be used as the value of
1348the cookie:
1349
1350FIXME.
1351
1352   Given this cookie value, we can then set the cookie header in our
1353HTTP response as follows:
1354
1355FIXME.
1356
1357Remark: Session expiration
1358==========================
1359
1360It is of course possible that clients stop their interaction with the
1361server at any time.  In order to avoid using too much storage, the
1362server must thus discard inactive sessions at some point.  Our example
1363implements this by discarding inactive sessions after a certain amount
1364of time.  Alternatively, the implementation may limit the total number
1365of active sessions.  Which bounds are used for idle sessions or the
1366total number of sessions obviously depends largely on the type of the
1367application and available server resources.
1368
1369Example code
1370============
1371
1372A sample application implementing a website with multiple forms (which
1373are dynamically created using values from previous POST requests from
1374the same session) is available as the example `sessions.c'.
1375
1376   Note that the example uses a simple, $O(n)$ linked list traversal to
1377look up sessions and to expire old sessions.  Using a hash table and a
1378heap would be more appropriate if a large number of concurrent sessions
1379is expected.
1380
1381Remarks
1382=======
1383
1384Naturally, it is quite conceivable to store session data in a database
1385instead of in memory.  Still, having mechanisms to expire data
1386associated with long-time idle sessions (where the business process has
1387still not finished) is likely a good idea.
1388
1389
1390File: libmicrohttpd-tutorial.info,  Node: Adding a layer of security,  Next: Bibliography,  Prev: Session management,  Up: Top
1391
13929 Adding a layer of security
1393****************************
1394
1395We left the basic authentication chapter with the unsatisfactory
1396conclusion that any traffic, including the credentials, could be
1397intercepted by anyone between the browser client and the server.
1398Protecting the data while it is sent over unsecured lines will be the
1399goal of this chapter.
1400
1401   Since version 0.4, the _MHD_ library includes support for encrypting
1402the traffic by employing SSL/TSL. If _GNU libmicrohttpd_ has been
1403configured to support these, encryption and decryption can be applied
1404transparently on the data being sent, with only minimal changes to the
1405actual source code of the example.
1406
1407Preparation
1408===========
1409
1410First, a private key for the server will be generated. With this key,
1411the server will later be able to authenticate itself to the
1412client--preventing anyone else from stealing the password by faking its
1413identity. The _OpenSSL_ suite, which is available on many operating
1414systems, can generate such a key. For the scope of this tutorial, we
1415will be content with a 1024 bit key:
1416> openssl genrsa -out server.key 1024
1417 In addition to the key, a certificate describing the server in human
1418readable tokens is also needed. This certificate will be attested with
1419our aforementioned key. In this way, we obtain a self-signed
1420certificate, valid for one year.
1421
1422> openssl req -days 365 -out server.pem -new -x509 -key server.key
1423 To avoid unnecessary error messages in the browser, the certificate
1424needs to have a name that matches the _URI_, for example, "localhost"
1425or the domain.  If you plan to have a publicly reachable server, you
1426will need to ask a trusted third party, called _Certificate Authority_,
1427or _CA_, to attest the certificate for you. This way, any visitor can
1428make sure the server's identity is real.
1429
1430   Whether the server's certificate is signed by us or a third party,
1431once it has been accepted by the client, both sides will be
1432communicating over encrypted channels. From this point on, it is the
1433client's turn to authenticate itself. But this has already been
1434implemented in the basic authentication scheme.
1435
1436Changing the source code
1437========================
1438
1439We merely have to extend the server program so that it loads the two
1440files into memory,
1441
1442int
1443main ()
1444{
1445  struct MHD_Daemon *daemon;
1446  char *key_pem;
1447  char *cert_pem;
1448
1449  key_pem = load_file (SERVERKEYFILE);
1450  cert_pem = load_file (SERVERCERTFILE);
1451
1452  if ((key_pem == NULL) || (cert_pem == NULL))
1453  {
1454    printf ("The key/certificate files could not be read.\n");
1455    return 1;
1456  }
1457 and then we point the _MHD_ daemon to it upon initalization.
1458
1459  daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL,
1460  	   		     PORT, NULL, NULL,
1461                             &answer_to_connection, NULL,
1462                             MHD_OPTION_HTTPS_MEM_KEY, key_pem,
1463                             MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
1464                             MHD_OPTION_END);
1465
1466  if (NULL == daemon)
1467    {
1468      printf ("%s\n", cert_pem);
1469
1470      free (key_pem);
1471      free (cert_pem);
1472
1473      return 1;
1474    }
1475 The rest consists of little new besides some additional memory
1476cleanups.
1477
1478  getchar ();
1479
1480  MHD_stop_daemon (daemon);
1481  free (key_pem);
1482  free (cert_pem);
1483
1484  return 0;
1485}
1486 The rather unexciting file loader can be found in the complete example
1487`tlsauthentication.c'.
1488
1489Remarks
1490=======
1491
1492   * While the standard _HTTP_ port is 80, it is 443 for _HTTPS_. The
1493     common internet browsers assume standard _HTTP_ if they are asked
1494     to access other ports than these. Therefore, you will have to type
1495     `https://localhost:8888' explicitly when you test the example, or
1496     the browser will not know how to handle the answer properly.
1497
1498   * The remaining weak point is the question how the server will be
1499     trusted initially. Either a _CA_ signs the certificate or the
1500     client obtains the key over secure means. Anyway, the clients have
1501     to be aware (or configured) that they should not accept
1502     certificates of unknown origin.
1503
1504   * The introduced method of certificates makes it mandatory to set an
1505     expiration date--making it less feasible to hardcode certificates
1506     in embedded devices.
1507
1508   * The cryptographic facilities consume memory space and computing
1509     time. For this reason, websites usually consists both of
1510     uncritically _HTTP_ parts and secured _HTTPS_.
1511
1512
1513Client authentication
1514=====================
1515
1516You can also use MHD to authenticate the client via SSL/TLS certificates
1517(as an alternative to using the password-based Basic or Digest
1518authentication).  To do this, you will need to link your application
1519against _gnutls_.  Next, when you start the MHD daemon, you must
1520specify the root CA that you're willing to trust:
1521  daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL,
1522  	   		     PORT, NULL, NULL,
1523                             &answer_to_connection, NULL,
1524                             MHD_OPTION_HTTPS_MEM_KEY, key_pem,
1525                             MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
1526			     MHD_OPTION_HTTPS_MEM_TRUST, root_ca_pem,
1527                             MHD_OPTION_END);
1528
1529   With this, you can then obtain client certificates for each session.
1530In order to obtain the identity of the client, you first need to obtain
1531the raw GnuTLS session handle from _MHD_ using
1532`MHD_get_connection_info'.
1533
1534#include <gnutls/gnutls.h>
1535#include <gnutls/x509.h>
1536
1537gnutls_session_t tls_session;
1538union MHD_ConnectionInfo *ci;
1539
1540ci = MHD_get_connection_info (connection,
1541                              MHD_CONNECTION_INFO_GNUTLS_SESSION);
1542tls_session = ci->tls_session;
1543
1544   You can then extract the client certificate:
1545
1546/**
1547 * Get the client's certificate
1548 *
1549 * @param tls_session the TLS session
1550 * @return NULL if no valid client certificate could be found, a pointer
1551 *  	to the certificate if found
1552 */
1553static gnutls_x509_crt_t
1554get_client_certificate (gnutls_session_t tls_session)
1555{
1556  unsigned int listsize;
1557  const gnutls_datum_t * pcert;
1558  gnutls_certificate_status_t client_cert_status;
1559  gnutls_x509_crt_t client_cert;
1560
1561  if (tls_session == NULL)
1562    return NULL;
1563  if (gnutls_certificate_verify_peers2(tls_session,
1564				       &client_cert_status))
1565    return NULL;
1566  pcert = gnutls_certificate_get_peers(tls_session,
1567				       &listsize);
1568  if ( (pcert == NULL) ||
1569       (listsize == 0))
1570    {
1571      fprintf (stderr,
1572	       "Failed to retrieve client certificate chain\n");
1573      return NULL;
1574    }
1575  if (gnutls_x509_crt_init(&client_cert))
1576    {
1577      fprintf (stderr,
1578	       "Failed to initialize client certificate\n");
1579      return NULL;
1580    }
1581  /* Note that by passing values between 0 and listsize here, you
1582     can get access to the CA's certs */
1583  if (gnutls_x509_crt_import(client_cert,
1584			     &pcert[0],
1585			     GNUTLS_X509_FMT_DER))
1586    {
1587      fprintf (stderr,
1588	       "Failed to import client certificate\n");
1589      gnutls_x509_crt_deinit(client_cert);
1590      return NULL;
1591    }
1592  return client_cert;
1593}
1594
1595   Using the client certificate, you can then get the client's
1596distinguished name and alternative names:
1597
1598/**
1599 * Get the distinguished name from the client's certificate
1600 *
1601 * @param client_cert the client certificate
1602 * @return NULL if no dn or certificate could be found, a pointer
1603 * 			to the dn if found
1604 */
1605char *
1606cert_auth_get_dn(gnutls_x509_crt_c client_cert)
1607{
1608  char* buf;
1609  size_t lbuf;
1610
1611  lbuf = 0;
1612  gnutls_x509_crt_get_dn(client_cert, NULL, &lbuf);
1613  buf = malloc(lbuf);
1614  if (buf == NULL)
1615    {
1616      fprintf (stderr,
1617	       "Failed to allocate memory for certificate dn\n");
1618      return NULL;
1619    }
1620  gnutls_x509_crt_get_dn(client_cert, buf, &lbuf);
1621  return buf;
1622}
1623
1624
1625/**
1626 * Get the alternative name of specified type from the client's certificate
1627 *
1628 * @param client_cert the client certificate
1629 * @param nametype The requested name type
1630 * @param index The position of the alternative name if multiple names are
1631 * 			matching the requested type, 0 for the first matching name
1632 * @return NULL if no matching alternative name could be found, a pointer
1633 * 			to the alternative name if found
1634 */
1635char *
1636MHD_cert_auth_get_alt_name(gnutls_x509_crt_t client_cert,
1637			   int nametype,
1638			   unsigned int index)
1639{
1640  char* buf;
1641  size_t lbuf;
1642  unsigned int seq;
1643  unsigned int subseq;
1644  unsigned int type;
1645  int result;
1646
1647  subseq = 0;
1648  for (seq=0;;seq++)
1649    {
1650      lbuf = 0;
1651      result = gnutls_x509_crt_get_subject_alt_name2(client_cert, seq, NULL, &lbuf,
1652						     &type, NULL);
1653      if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1654	return NULL;
1655      if (nametype != (int) type)
1656	continue;
1657      if (subseq == index)
1658	break;
1659      subseq++;
1660    }
1661  buf = malloc(lbuf);
1662  if (buf == NULL)
1663    {
1664      fprintf (stderr,
1665	       "Failed to allocate memory for certificate alt name\n");
1666      return NULL;
1667    }
1668  result = gnutls_x509_crt_get_subject_alt_name2(client_cert,
1669						 seq,
1670						 buf,
1671						 &lbuf,
1672						 NULL, NULL);
1673  if (result != nametype)
1674    {
1675      fprintf (stderr,
1676	       "Unexpected return value from gnutls: %d\n",
1677	       result);
1678      free (buf);
1679      return NULL;
1680    }
1681  return buf;
1682}
1683
1684   Finally, you should release the memory associated with the client
1685certificate:
1686
1687gnutls_x509_crt_deinit (client_cert);
1688
1689Using TLS Server Name Indication (SNI)
1690======================================
1691
1692SNI enables hosting multiple domains under one IP address with TLS.  So
1693SNI is the TLS-equivalent of virtual hosting.  To use SNI with MHD, you
1694need at least GnuTLS 3.0.  The main change compared to the simple
1695hosting of one domain is that you need to provide a callback instead of
1696the key and certificate.  For example, when you start the MHD daemon,
1697you could do this:
1698  daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL,
1699  	   		     PORT, NULL, NULL,
1700                             &answer_to_connection, NULL,
1701                             MHD_OPTION_HTTPS_CERT_CALLBACK, &sni_callback,
1702                             MHD_OPTION_END);
1703 Here, `sni_callback' is the name of a function that you will have to
1704implement to retrieve the X.509 certificate for an incoming connection.
1705The callback has type `gnutls_certificate_retrieve_function2' and is
1706documented in the GnuTLS API for the
1707`gnutls_certificate_set_retrieve_function2' as follows:
1708
1709 -- Function Pointer: int *gnutls_certificate_retrieve_function2
1710          (gnutls_session_t, const gnutls_datum_t* req_ca_dn, int
1711          nreqs, const gnutls_pk_algorithm_t* pk_algos, int
1712          pk_algos_length, gnutls_pcert_st** pcert, unsigned int
1713          *pcert_length, gnutls_privkey_t * pkey)
1714    REQ_CA_CERT
1715          is only used in X.509 certificates. Contains a list with the
1716          CA names that the server considers trusted. Normally we
1717          should send a certificate that is signed by one of these CAs.
1718          These names are DER encoded. To get a more meaningful value
1719          use the function `gnutls_x509_rdn_get()'.
1720
1721    PK_ALGOS
1722          contains a list with server’s acceptable signature
1723          algorithms. The certificate returned should support the
1724          server’s given algorithms.
1725
1726    PCERT
1727          should contain a single certificate and public or a list of
1728          them.
1729
1730    PCERT_LENGTH
1731          is the size of the previous list.
1732
1733    PKEY
1734          is the private key.
1735
1736   A possible implementation of this callback would look like this:
1737
1738struct Hosts
1739{
1740  struct Hosts *next;
1741  const char *hostname;
1742  gnutls_pcert_st pcrt;
1743  gnutls_privkey_t key;
1744};
1745
1746static struct Hosts *hosts;
1747
1748int
1749sni_callback (gnutls_session_t session,
1750              const gnutls_datum_t* req_ca_dn,
1751              int nreqs,
1752              const gnutls_pk_algorithm_t* pk_algos,
1753              int pk_algos_length,
1754              gnutls_pcert_st** pcert,
1755              unsigned int *pcert_length,
1756              gnutls_privkey_t * pkey)
1757{
1758  char name[256];
1759  size_t name_len;
1760  struct Hosts *host;
1761  unsigned int type;
1762
1763  name_len = sizeof (name);
1764  if (GNUTLS_E_SUCCESS !=
1765      gnutls_server_name_get (session,
1766                              name,
1767                              &name_len,
1768                              &type,
1769                              0 /* index */))
1770    return -1;
1771  for (host = hosts; NULL != host; host = host->next)
1772    if (0 == strncmp (name, host->hostname, name_len))
1773      break;
1774  if (NULL == host)
1775    {
1776      fprintf (stderr,
1777               "Need certificate for %.*s\n",
1778               (int) name_len,
1779               name);
1780      return -1;
1781    }
1782  fprintf (stderr,
1783           "Returning certificate for %.*s\n",
1784           (int) name_len,
1785           name);
1786  *pkey = host->key;
1787  *pcert_length = 1;
1788  *pcert = &host->pcrt;
1789  return 0;
1790}
1791
1792   Note that MHD cannot offer passing a closure or any other additional
1793information to this callback, as the GnuTLS API unfortunately does not
1794permit this at this point.
1795
1796   The `hosts' list can be initialized by loading the private keys and
1797X.509 certificats from disk as follows:
1798
1799static void
1800load_keys(const char *hostname,
1801          const char *CERT_FILE,
1802          const char *KEY_FILE)
1803{
1804  int ret;
1805  gnutls_datum_t data;
1806  struct Hosts *host;
1807
1808  host = malloc (sizeof (struct Hosts));
1809  host->hostname = hostname;
1810  host->next = hosts;
1811  hosts = host;
1812
1813  ret = gnutls_load_file (CERT_FILE, &data);
1814  if (ret < 0)
1815  {
1816    fprintf (stderr,
1817             "*** Error loading certificate file %s.\n",
1818             CERT_FILE);
1819    exit(1);
1820  }
1821  ret =
1822    gnutls_pcert_import_x509_raw (&host->pcrt, &data, GNUTLS_X509_FMT_PEM,
1823                                  0);
1824  if (ret < 0)
1825  {
1826    fprintf(stderr,
1827            "*** Error loading certificate file: %s\n",
1828            gnutls_strerror (ret));
1829    exit(1);
1830  }
1831  gnutls_free (data.data);
1832
1833  ret = gnutls_load_file (KEY_FILE, &data);
1834  if (ret < 0)
1835  {
1836    fprintf (stderr,
1837             "*** Error loading key file %s.\n",
1838             KEY_FILE);
1839    exit(1);
1840  }
1841
1842  gnutls_privkey_init (&host->key);
1843  ret =
1844    gnutls_privkey_import_x509_raw (host->key,
1845                                    &data, GNUTLS_X509_FMT_PEM,
1846                                    NULL, 0);
1847  if (ret < 0)
1848  {
1849    fprintf (stderr,
1850             "*** Error loading key file: %s\n",
1851             gnutls_strerror (ret));
1852    exit(1);
1853  }
1854  gnutls_free (data.data);
1855}
1856
1857   The code above was largely lifted from GnuTLS.  You can find other
1858methods for initializing certificates and keys in the GnuTLS manual and
1859source code.
1860
1861
1862File: libmicrohttpd-tutorial.info,  Node: Bibliography,  Next: License text,  Prev: Adding a layer of security,  Up: Top
1863
1864Appendix A Bibliography
1865***********************
1866
1867API reference
1868=============
1869
1870   * The _GNU libmicrohttpd_ manual by Marco Maggi and Christian
1871     Grothoff 2008 `http://gnunet.org/libmicrohttpd/microhttpd.html'
1872
1873   * All referenced RFCs can be found on the website of _The Internet
1874     Engineering Task Force_ `http://www.ietf.org/'
1875
1876   * _RFC 2616_: Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and
1877     T. Berners-Lee, "Hypertext Transfer Protocol - HTTP/1.1", RFC
1878     2016, January 1997.
1879
1880   * _RFC 2617_: Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence,
1881     S., Leach, P., Luotonen, A., and L. Stewart, "HTTP Authentication:
1882     Basic and Digest Access Authentication", RFC 2617, June 1999.
1883
1884   * A well-structured _HTML_ reference can be found on
1885     `http://www.echoecho.com/html.htm'
1886
1887     For those readers understanding German or French, there is an
1888     excellent document both for learning _HTML_ and for reference,
1889     whose English version unfortunately has been discontinued.
1890     `http://de.selfhtml.org/' and `http://fr.selfhtml.org/'
1891
1892
1893
1894File: libmicrohttpd-tutorial.info,  Node: License text,  Next: Example programs,  Prev: Bibliography,  Up: Top
1895
1896Appendix B GNU Free Documentation License
1897*****************************************
1898
1899                     Version 1.3, 3 November 2008
1900
1901     Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
1902     `http://fsf.org/'
1903
1904     Everyone is permitted to copy and distribute verbatim copies
1905     of this license document, but changing it is not allowed.
1906
1907  0. PREAMBLE
1908
1909     The purpose of this License is to make a manual, textbook, or other
1910     functional and useful document "free" in the sense of freedom: to
1911     assure everyone the effective freedom to copy and redistribute it,
1912     with or without modifying it, either commercially or
1913     noncommercially.  Secondarily, this License preserves for the
1914     author and publisher a way to get credit for their work, while not
1915     being considered responsible for modifications made by others.
1916
1917     This License is a kind of "copyleft", which means that derivative
1918     works of the document must themselves be free in the same sense.
1919     It complements the GNU General Public License, which is a copyleft
1920     license designed for free software.
1921
1922     We have designed this License in order to use it for manuals for
1923     free software, because free software needs free documentation: a
1924     free program should come with manuals providing the same freedoms
1925     that the software does.  But this License is not limited to
1926     software manuals; it can be used for any textual work, regardless
1927     of subject matter or whether it is published as a printed book.
1928     We recommend this License principally for works whose purpose is
1929     instruction or reference.
1930
1931  1. APPLICABILITY AND DEFINITIONS
1932
1933     This License applies to any manual or other work, in any medium,
1934     that contains a notice placed by the copyright holder saying it
1935     can be distributed under the terms of this License.  Such a notice
1936     grants a world-wide, royalty-free license, unlimited in duration,
1937     to use that work under the conditions stated herein.  The
1938     "Document", below, refers to any such manual or work.  Any member
1939     of the public is a licensee, and is addressed as "you".  You
1940     accept the license if you copy, modify or distribute the work in a
1941     way requiring permission under copyright law.
1942
1943     A "Modified Version" of the Document means any work containing the
1944     Document or a portion of it, either copied verbatim, or with
1945     modifications and/or translated into another language.
1946
1947     A "Secondary Section" is a named appendix or a front-matter section
1948     of the Document that deals exclusively with the relationship of the
1949     publishers or authors of the Document to the Document's overall
1950     subject (or to related matters) and contains nothing that could
1951     fall directly within that overall subject.  (Thus, if the Document
1952     is in part a textbook of mathematics, a Secondary Section may not
1953     explain any mathematics.)  The relationship could be a matter of
1954     historical connection with the subject or with related matters, or
1955     of legal, commercial, philosophical, ethical or political position
1956     regarding them.
1957
1958     The "Invariant Sections" are certain Secondary Sections whose
1959     titles are designated, as being those of Invariant Sections, in
1960     the notice that says that the Document is released under this
1961     License.  If a section does not fit the above definition of
1962     Secondary then it is not allowed to be designated as Invariant.
1963     The Document may contain zero Invariant Sections.  If the Document
1964     does not identify any Invariant Sections then there are none.
1965
1966     The "Cover Texts" are certain short passages of text that are
1967     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
1968     that says that the Document is released under this License.  A
1969     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
1970     be at most 25 words.
1971
1972     A "Transparent" copy of the Document means a machine-readable copy,
1973     represented in a format whose specification is available to the
1974     general public, that is suitable for revising the document
1975     straightforwardly with generic text editors or (for images
1976     composed of pixels) generic paint programs or (for drawings) some
1977     widely available drawing editor, and that is suitable for input to
1978     text formatters or for automatic translation to a variety of
1979     formats suitable for input to text formatters.  A copy made in an
1980     otherwise Transparent file format whose markup, or absence of
1981     markup, has been arranged to thwart or discourage subsequent
1982     modification by readers is not Transparent.  An image format is
1983     not Transparent if used for any substantial amount of text.  A
1984     copy that is not "Transparent" is called "Opaque".
1985
1986     Examples of suitable formats for Transparent copies include plain
1987     ASCII without markup, Texinfo input format, LaTeX input format,
1988     SGML or XML using a publicly available DTD, and
1989     standard-conforming simple HTML, PostScript or PDF designed for
1990     human modification.  Examples of transparent image formats include
1991     PNG, XCF and JPG.  Opaque formats include proprietary formats that
1992     can be read and edited only by proprietary word processors, SGML or
1993     XML for which the DTD and/or processing tools are not generally
1994     available, and the machine-generated HTML, PostScript or PDF
1995     produced by some word processors for output purposes only.
1996
1997     The "Title Page" means, for a printed book, the title page itself,
1998     plus such following pages as are needed to hold, legibly, the
1999     material this License requires to appear in the title page.  For
2000     works in formats which do not have any title page as such, "Title
2001     Page" means the text near the most prominent appearance of the
2002     work's title, preceding the beginning of the body of the text.
2003
2004     The "publisher" means any person or entity that distributes copies
2005     of the Document to the public.
2006
2007     A section "Entitled XYZ" means a named subunit of the Document
2008     whose title either is precisely XYZ or contains XYZ in parentheses
2009     following text that translates XYZ in another language.  (Here XYZ
2010     stands for a specific section name mentioned below, such as
2011     "Acknowledgements", "Dedications", "Endorsements", or "History".)
2012     To "Preserve the Title" of such a section when you modify the
2013     Document means that it remains a section "Entitled XYZ" according
2014     to this definition.
2015
2016     The Document may include Warranty Disclaimers next to the notice
2017     which states that this License applies to the Document.  These
2018     Warranty Disclaimers are considered to be included by reference in
2019     this License, but only as regards disclaiming warranties: any other
2020     implication that these Warranty Disclaimers may have is void and
2021     has no effect on the meaning of this License.
2022
2023  2. VERBATIM COPYING
2024
2025     You may copy and distribute the Document in any medium, either
2026     commercially or noncommercially, provided that this License, the
2027     copyright notices, and the license notice saying this License
2028     applies to the Document are reproduced in all copies, and that you
2029     add no other conditions whatsoever to those of this License.  You
2030     may not use technical measures to obstruct or control the reading
2031     or further copying of the copies you make or distribute.  However,
2032     you may accept compensation in exchange for copies.  If you
2033     distribute a large enough number of copies you must also follow
2034     the conditions in section 3.
2035
2036     You may also lend copies, under the same conditions stated above,
2037     and you may publicly display copies.
2038
2039  3. COPYING IN QUANTITY
2040
2041     If you publish printed copies (or copies in media that commonly
2042     have printed covers) of the Document, numbering more than 100, and
2043     the Document's license notice requires Cover Texts, you must
2044     enclose the copies in covers that carry, clearly and legibly, all
2045     these Cover Texts: Front-Cover Texts on the front cover, and
2046     Back-Cover Texts on the back cover.  Both covers must also clearly
2047     and legibly identify you as the publisher of these copies.  The
2048     front cover must present the full title with all words of the
2049     title equally prominent and visible.  You may add other material
2050     on the covers in addition.  Copying with changes limited to the
2051     covers, as long as they preserve the title of the Document and
2052     satisfy these conditions, can be treated as verbatim copying in
2053     other respects.
2054
2055     If the required texts for either cover are too voluminous to fit
2056     legibly, you should put the first ones listed (as many as fit
2057     reasonably) on the actual cover, and continue the rest onto
2058     adjacent pages.
2059
2060     If you publish or distribute Opaque copies of the Document
2061     numbering more than 100, you must either include a
2062     machine-readable Transparent copy along with each Opaque copy, or
2063     state in or with each Opaque copy a computer-network location from
2064     which the general network-using public has access to download
2065     using public-standard network protocols a complete Transparent
2066     copy of the Document, free of added material.  If you use the
2067     latter option, you must take reasonably prudent steps, when you
2068     begin distribution of Opaque copies in quantity, to ensure that
2069     this Transparent copy will remain thus accessible at the stated
2070     location until at least one year after the last time you
2071     distribute an Opaque copy (directly or through your agents or
2072     retailers) of that edition to the public.
2073
2074     It is requested, but not required, that you contact the authors of
2075     the Document well before redistributing any large number of
2076     copies, to give them a chance to provide you with an updated
2077     version of the Document.
2078
2079  4. MODIFICATIONS
2080
2081     You may copy and distribute a Modified Version of the Document
2082     under the conditions of sections 2 and 3 above, provided that you
2083     release the Modified Version under precisely this License, with
2084     the Modified Version filling the role of the Document, thus
2085     licensing distribution and modification of the Modified Version to
2086     whoever possesses a copy of it.  In addition, you must do these
2087     things in the Modified Version:
2088
2089       A. Use in the Title Page (and on the covers, if any) a title
2090          distinct from that of the Document, and from those of
2091          previous versions (which should, if there were any, be listed
2092          in the History section of the Document).  You may use the
2093          same title as a previous version if the original publisher of
2094          that version gives permission.
2095
2096       B. List on the Title Page, as authors, one or more persons or
2097          entities responsible for authorship of the modifications in
2098          the Modified Version, together with at least five of the
2099          principal authors of the Document (all of its principal
2100          authors, if it has fewer than five), unless they release you
2101          from this requirement.
2102
2103       C. State on the Title page the name of the publisher of the
2104          Modified Version, as the publisher.
2105
2106       D. Preserve all the copyright notices of the Document.
2107
2108       E. Add an appropriate copyright notice for your modifications
2109          adjacent to the other copyright notices.
2110
2111       F. Include, immediately after the copyright notices, a license
2112          notice giving the public permission to use the Modified
2113          Version under the terms of this License, in the form shown in
2114          the Addendum below.
2115
2116       G. Preserve in that license notice the full lists of Invariant
2117          Sections and required Cover Texts given in the Document's
2118          license notice.
2119
2120       H. Include an unaltered copy of this License.
2121
2122       I. Preserve the section Entitled "History", Preserve its Title,
2123          and add to it an item stating at least the title, year, new
2124          authors, and publisher of the Modified Version as given on
2125          the Title Page.  If there is no section Entitled "History" in
2126          the Document, create one stating the title, year, authors,
2127          and publisher of the Document as given on its Title Page,
2128          then add an item describing the Modified Version as stated in
2129          the previous sentence.
2130
2131       J. Preserve the network location, if any, given in the Document
2132          for public access to a Transparent copy of the Document, and
2133          likewise the network locations given in the Document for
2134          previous versions it was based on.  These may be placed in
2135          the "History" section.  You may omit a network location for a
2136          work that was published at least four years before the
2137          Document itself, or if the original publisher of the version
2138          it refers to gives permission.
2139
2140       K. For any section Entitled "Acknowledgements" or "Dedications",
2141          Preserve the Title of the section, and preserve in the
2142          section all the substance and tone of each of the contributor
2143          acknowledgements and/or dedications given therein.
2144
2145       L. Preserve all the Invariant Sections of the Document,
2146          unaltered in their text and in their titles.  Section numbers
2147          or the equivalent are not considered part of the section
2148          titles.
2149
2150       M. Delete any section Entitled "Endorsements".  Such a section
2151          may not be included in the Modified Version.
2152
2153       N. Do not retitle any existing section to be Entitled
2154          "Endorsements" or to conflict in title with any Invariant
2155          Section.
2156
2157       O. Preserve any Warranty Disclaimers.
2158
2159     If the Modified Version includes new front-matter sections or
2160     appendices that qualify as Secondary Sections and contain no
2161     material copied from the Document, you may at your option
2162     designate some or all of these sections as invariant.  To do this,
2163     add their titles to the list of Invariant Sections in the Modified
2164     Version's license notice.  These titles must be distinct from any
2165     other section titles.
2166
2167     You may add a section Entitled "Endorsements", provided it contains
2168     nothing but endorsements of your Modified Version by various
2169     parties--for example, statements of peer review or that the text
2170     has been approved by an organization as the authoritative
2171     definition of a standard.
2172
2173     You may add a passage of up to five words as a Front-Cover Text,
2174     and a passage of up to 25 words as a Back-Cover Text, to the end
2175     of the list of Cover Texts in the Modified Version.  Only one
2176     passage of Front-Cover Text and one of Back-Cover Text may be
2177     added by (or through arrangements made by) any one entity.  If the
2178     Document already includes a cover text for the same cover,
2179     previously added by you or by arrangement made by the same entity
2180     you are acting on behalf of, you may not add another; but you may
2181     replace the old one, on explicit permission from the previous
2182     publisher that added the old one.
2183
2184     The author(s) and publisher(s) of the Document do not by this
2185     License give permission to use their names for publicity for or to
2186     assert or imply endorsement of any Modified Version.
2187
2188  5. COMBINING DOCUMENTS
2189
2190     You may combine the Document with other documents released under
2191     this License, under the terms defined in section 4 above for
2192     modified versions, provided that you include in the combination
2193     all of the Invariant Sections of all of the original documents,
2194     unmodified, and list them all as Invariant Sections of your
2195     combined work in its license notice, and that you preserve all
2196     their Warranty Disclaimers.
2197
2198     The combined work need only contain one copy of this License, and
2199     multiple identical Invariant Sections may be replaced with a single
2200     copy.  If there are multiple Invariant Sections with the same name
2201     but different contents, make the title of each such section unique
2202     by adding at the end of it, in parentheses, the name of the
2203     original author or publisher of that section if known, or else a
2204     unique number.  Make the same adjustment to the section titles in
2205     the list of Invariant Sections in the license notice of the
2206     combined work.
2207
2208     In the combination, you must combine any sections Entitled
2209     "History" in the various original documents, forming one section
2210     Entitled "History"; likewise combine any sections Entitled
2211     "Acknowledgements", and any sections Entitled "Dedications".  You
2212     must delete all sections Entitled "Endorsements."
2213
2214  6. COLLECTIONS OF DOCUMENTS
2215
2216     You may make a collection consisting of the Document and other
2217     documents released under this License, and replace the individual
2218     copies of this License in the various documents with a single copy
2219     that is included in the collection, provided that you follow the
2220     rules of this License for verbatim copying of each of the
2221     documents in all other respects.
2222
2223     You may extract a single document from such a collection, and
2224     distribute it individually under this License, provided you insert
2225     a copy of this License into the extracted document, and follow
2226     this License in all other respects regarding verbatim copying of
2227     that document.
2228
2229  7. AGGREGATION WITH INDEPENDENT WORKS
2230
2231     A compilation of the Document or its derivatives with other
2232     separate and independent documents or works, in or on a volume of
2233     a storage or distribution medium, is called an "aggregate" if the
2234     copyright resulting from the compilation is not used to limit the
2235     legal rights of the compilation's users beyond what the individual
2236     works permit.  When the Document is included in an aggregate, this
2237     License does not apply to the other works in the aggregate which
2238     are not themselves derivative works of the Document.
2239
2240     If the Cover Text requirement of section 3 is applicable to these
2241     copies of the Document, then if the Document is less than one half
2242     of the entire aggregate, the Document's Cover Texts may be placed
2243     on covers that bracket the Document within the aggregate, or the
2244     electronic equivalent of covers if the Document is in electronic
2245     form.  Otherwise they must appear on printed covers that bracket
2246     the whole aggregate.
2247
2248  8. TRANSLATION
2249
2250     Translation is considered a kind of modification, so you may
2251     distribute translations of the Document under the terms of section
2252     4.  Replacing Invariant Sections with translations requires special
2253     permission from their copyright holders, but you may include
2254     translations of some or all Invariant Sections in addition to the
2255     original versions of these Invariant Sections.  You may include a
2256     translation of this License, and all the license notices in the
2257     Document, and any Warranty Disclaimers, provided that you also
2258     include the original English version of this License and the
2259     original versions of those notices and disclaimers.  In case of a
2260     disagreement between the translation and the original version of
2261     this License or a notice or disclaimer, the original version will
2262     prevail.
2263
2264     If a section in the Document is Entitled "Acknowledgements",
2265     "Dedications", or "History", the requirement (section 4) to
2266     Preserve its Title (section 1) will typically require changing the
2267     actual title.
2268
2269  9. TERMINATION
2270
2271     You may not copy, modify, sublicense, or distribute the Document
2272     except as expressly provided under this License.  Any attempt
2273     otherwise to copy, modify, sublicense, or distribute it is void,
2274     and will automatically terminate your rights under this License.
2275
2276     However, if you cease all violation of this License, then your
2277     license from a particular copyright holder is reinstated (a)
2278     provisionally, unless and until the copyright holder explicitly
2279     and finally terminates your license, and (b) permanently, if the
2280     copyright holder fails to notify you of the violation by some
2281     reasonable means prior to 60 days after the cessation.
2282
2283     Moreover, your license from a particular copyright holder is
2284     reinstated permanently if the copyright holder notifies you of the
2285     violation by some reasonable means, this is the first time you have
2286     received notice of violation of this License (for any work) from
2287     that copyright holder, and you cure the violation prior to 30 days
2288     after your receipt of the notice.
2289
2290     Termination of your rights under this section does not terminate
2291     the licenses of parties who have received copies or rights from
2292     you under this License.  If your rights have been terminated and
2293     not permanently reinstated, receipt of a copy of some or all of
2294     the same material does not give you any rights to use it.
2295
2296 10. FUTURE REVISIONS OF THIS LICENSE
2297
2298     The Free Software Foundation may publish new, revised versions of
2299     the GNU Free Documentation License from time to time.  Such new
2300     versions will be similar in spirit to the present version, but may
2301     differ in detail to address new problems or concerns.  See
2302     `http://www.gnu.org/copyleft/'.
2303
2304     Each version of the License is given a distinguishing version
2305     number.  If the Document specifies that a particular numbered
2306     version of this License "or any later version" applies to it, you
2307     have the option of following the terms and conditions either of
2308     that specified version or of any later version that has been
2309     published (not as a draft) by the Free Software Foundation.  If
2310     the Document does not specify a version number of this License,
2311     you may choose any version ever published (not as a draft) by the
2312     Free Software Foundation.  If the Document specifies that a proxy
2313     can decide which future versions of this License can be used, that
2314     proxy's public statement of acceptance of a version permanently
2315     authorizes you to choose that version for the Document.
2316
2317 11. RELICENSING
2318
2319     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
2320     World Wide Web server that publishes copyrightable works and also
2321     provides prominent facilities for anybody to edit those works.  A
2322     public wiki that anybody can edit is an example of such a server.
2323     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
2324     site means any set of copyrightable works thus published on the MMC
2325     site.
2326
2327     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
2328     license published by Creative Commons Corporation, a not-for-profit
2329     corporation with a principal place of business in San Francisco,
2330     California, as well as future copyleft versions of that license
2331     published by that same organization.
2332
2333     "Incorporate" means to publish or republish a Document, in whole or
2334     in part, as part of another Document.
2335
2336     An MMC is "eligible for relicensing" if it is licensed under this
2337     License, and if all works that were first published under this
2338     License somewhere other than this MMC, and subsequently
2339     incorporated in whole or in part into the MMC, (1) had no cover
2340     texts or invariant sections, and (2) were thus incorporated prior
2341     to November 1, 2008.
2342
2343     The operator of an MMC Site may republish an MMC contained in the
2344     site under CC-BY-SA on the same site at any time before August 1,
2345     2009, provided the MMC is eligible for relicensing.
2346
2347
2348ADDENDUM: How to use this License for your documents
2349====================================================
2350
2351To use this License in a document you have written, include a copy of
2352the License in the document and put the following copyright and license
2353notices just after the title page:
2354
2355       Copyright (C)  YEAR  YOUR NAME.
2356       Permission is granted to copy, distribute and/or modify this document
2357       under the terms of the GNU Free Documentation License, Version 1.3
2358       or any later version published by the Free Software Foundation;
2359       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
2360       Texts.  A copy of the license is included in the section entitled ``GNU
2361       Free Documentation License''.
2362
2363   If you have Invariant Sections, Front-Cover Texts and Back-Cover
2364Texts, replace the "with...Texts." line with this:
2365
2366         with the Invariant Sections being LIST THEIR TITLES, with
2367         the Front-Cover Texts being LIST, and with the Back-Cover Texts
2368         being LIST.
2369
2370   If you have Invariant Sections without Cover Texts, or some other
2371combination of the three, merge those two alternatives to suit the
2372situation.
2373
2374   If your document contains nontrivial examples of program code, we
2375recommend releasing these examples in parallel under your choice of
2376free software license, such as the GNU General Public License, to
2377permit their use in free software.
2378
2379
2380File: libmicrohttpd-tutorial.info,  Node: Example programs,  Prev: License text,  Up: Top
2381
2382Appendix C Example programs
2383***************************
2384
2385* Menu:
2386
2387* hellobrowser.c::
2388* logging.c::
2389* responseheaders.c::
2390* basicauthentication.c::
2391* simplepost.c::
2392* largepost.c::
2393* sessions.c::
2394* tlsauthentication.c::
2395
2396
2397File: libmicrohttpd-tutorial.info,  Node: hellobrowser.c,  Next: logging.c,  Up: Example programs
2398
2399C.1 hellobrowser.c
2400==================
2401
2402     /* Feel free to use this example code in any way
2403        you see fit (Public Domain) */
2404
2405     #include <sys/types.h>
2406     #ifndef _WIN32
2407     #include <sys/select.h>
2408     #include <sys/socket.h>
2409     #else
2410     #include <winsock2.h>
2411     #endif
2412     #include <string.h>
2413     #include <microhttpd.h>
2414     #include <stdio.h>
2415
2416     #define PORT 8888
2417
2418     static int
2419     answer_to_connection (void *cls, struct MHD_Connection *connection,
2420                           const char *url, const char *method,
2421                           const char *version, const char *upload_data,
2422                           size_t *upload_data_size, void **con_cls)
2423     {
2424       const char *page = "<html><body>Hello, browser!</body></html>";
2425       struct MHD_Response *response;
2426       int ret;
2427
2428       response =
2429         MHD_create_response_from_buffer (strlen (page), (void *) page,
2430     				     MHD_RESPMEM_PERSISTENT);
2431       ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
2432       MHD_destroy_response (response);
2433
2434       return ret;
2435     }
2436
2437
2438     int
2439     main ()
2440     {
2441       struct MHD_Daemon *daemon;
2442
2443       daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
2444                                  &answer_to_connection, NULL, MHD_OPTION_END);
2445       if (NULL == daemon)
2446         return 1;
2447
2448       (void) getchar ();
2449
2450       MHD_stop_daemon (daemon);
2451       return 0;
2452     }
2453
2454
2455File: libmicrohttpd-tutorial.info,  Node: logging.c,  Next: responseheaders.c,  Prev: hellobrowser.c,  Up: Example programs
2456
2457C.2 logging.c
2458=============
2459
2460     /* Feel free to use this example code in any way
2461        you see fit (Public Domain) */
2462
2463     #include <sys/types.h>
2464     #ifndef _WIN32
2465     #include <sys/select.h>
2466     #include <sys/socket.h>
2467     #else
2468     #include <winsock2.h>
2469     #endif
2470     #include <microhttpd.h>
2471     #include <stdio.h>
2472
2473     #define PORT 8888
2474
2475
2476     static int
2477     print_out_key (void *cls, enum MHD_ValueKind kind, const char *key,
2478                    const char *value)
2479     {
2480       printf ("%s: %s\n", key, value);
2481       return MHD_YES;
2482     }
2483
2484
2485     static int
2486     answer_to_connection (void *cls, struct MHD_Connection *connection,
2487                           const char *url, const char *method,
2488                           const char *version, const char *upload_data,
2489                           size_t *upload_data_size, void **con_cls)
2490     {
2491       printf ("New %s request for %s using version %s\n", method, url, version);
2492
2493       MHD_get_connection_values (connection, MHD_HEADER_KIND, print_out_key,
2494                                  NULL);
2495
2496       return MHD_NO;
2497     }
2498
2499
2500     int
2501     main ()
2502     {
2503       struct MHD_Daemon *daemon;
2504
2505       daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
2506                                  &answer_to_connection, NULL, MHD_OPTION_END);
2507       if (NULL == daemon)
2508         return 1;
2509
2510       (void) getchar ();
2511
2512       MHD_stop_daemon (daemon);
2513       return 0;
2514     }
2515
2516
2517File: libmicrohttpd-tutorial.info,  Node: responseheaders.c,  Next: basicauthentication.c,  Prev: logging.c,  Up: Example programs
2518
2519C.3 responseheaders.c
2520=====================
2521
2522     /* Feel free to use this example code in any way
2523        you see fit (Public Domain) */
2524
2525     #include <sys/types.h>
2526     #ifndef _WIN32
2527     #include <sys/select.h>
2528     #include <sys/socket.h>
2529     #else
2530     #include <winsock2.h>
2531     #endif
2532     #include <microhttpd.h>
2533     #include <time.h>
2534     #include <sys/stat.h>
2535     #include <fcntl.h>
2536     #include <string.h>
2537     #include <stdio.h>
2538
2539     #define PORT 8888
2540     #define FILENAME "picture.png"
2541     #define MIMETYPE "image/png"
2542
2543     static int
2544     answer_to_connection (void *cls, struct MHD_Connection *connection,
2545                           const char *url, const char *method,
2546                           const char *version, const char *upload_data,
2547                           size_t *upload_data_size, void **con_cls)
2548     {
2549       struct MHD_Response *response;
2550       int fd;
2551       int ret;
2552       struct stat sbuf;
2553
2554       if (0 != strcmp (method, "GET"))
2555         return MHD_NO;
2556
2557       if ( (-1 == (fd = open (FILENAME, O_RDONLY))) ||
2558            (0 != fstat (fd, &sbuf)) )
2559         {
2560           /* error accessing file */
2561           if (fd != -1)
2562     	(void) close (fd);
2563           const char *errorstr =
2564             "<html><body>An internal server error has occured!\
2565                                   </body></html>";
2566           response =
2567     	MHD_create_response_from_buffer (strlen (errorstr),
2568     					 (void *) errorstr,
2569     					 MHD_RESPMEM_PERSISTENT);
2570           if (NULL != response)
2571             {
2572               ret =
2573                 MHD_queue_response (connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
2574                                     response);
2575               MHD_destroy_response (response);
2576
2577               return ret;
2578             }
2579           else
2580             return MHD_NO;
2581         }
2582       response =
2583         MHD_create_response_from_fd_at_offset (sbuf.st_size, fd, 0);
2584       MHD_add_response_header (response, "Content-Type", MIMETYPE);
2585       ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
2586       MHD_destroy_response (response);
2587
2588       return ret;
2589     }
2590
2591
2592     int
2593     main ()
2594     {
2595       struct MHD_Daemon *daemon;
2596
2597       daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
2598                                  &answer_to_connection, NULL, MHD_OPTION_END);
2599       if (NULL == daemon)
2600         return 1;
2601
2602       (void) getchar ();
2603
2604       MHD_stop_daemon (daemon);
2605
2606       return 0;
2607     }
2608
2609
2610File: libmicrohttpd-tutorial.info,  Node: basicauthentication.c,  Next: simplepost.c,  Prev: responseheaders.c,  Up: Example programs
2611
2612C.4 basicauthentication.c
2613=========================
2614
2615     /* Feel free to use this example code in any way
2616        you see fit (Public Domain) */
2617
2618     #include <sys/types.h>
2619     #ifndef _WIN32
2620     #include <sys/select.h>
2621     #include <sys/socket.h>
2622     #else
2623     #include <winsock2.h>
2624     #endif
2625     #include <microhttpd.h>
2626     #include <time.h>
2627     #include <string.h>
2628     #include <stdlib.h>
2629     #include <stdio.h>
2630
2631     #define PORT 8888
2632
2633
2634     static int
2635     answer_to_connection (void *cls, struct MHD_Connection *connection,
2636                           const char *url, const char *method,
2637                           const char *version, const char *upload_data,
2638                           size_t *upload_data_size, void **con_cls)
2639     {
2640       char *user;
2641       char *pass;
2642       int fail;
2643       int ret;
2644       struct MHD_Response *response;
2645
2646       if (0 != strcmp (method, "GET"))
2647         return MHD_NO;
2648       if (NULL == *con_cls)
2649         {
2650           *con_cls = connection;
2651           return MHD_YES;
2652         }
2653       pass = NULL;
2654       user = MHD_basic_auth_get_username_password (connection, &pass);
2655       fail = ( (user == NULL) ||
2656     	   (0 != strcmp (user, "root")) ||
2657     	   (0 != strcmp (pass, "pa$$w0rd") ) );
2658       if (user != NULL) free (user);
2659       if (pass != NULL) free (pass);
2660       if (fail)
2661         {
2662           const char *page = "<html><body>Go away.</body></html>";
2663           response =
2664     	MHD_create_response_from_buffer (strlen (page), (void *) page,
2665     					 MHD_RESPMEM_PERSISTENT);
2666           ret = MHD_queue_basic_auth_fail_response (connection,
2667     						"my realm",
2668     						response);
2669         }
2670       else
2671         {
2672           const char *page = "<html><body>A secret.</body></html>";
2673           response =
2674     	MHD_create_response_from_buffer (strlen (page), (void *) page,
2675     					 MHD_RESPMEM_PERSISTENT);
2676           ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
2677         }
2678       MHD_destroy_response (response);
2679       return ret;
2680     }
2681
2682
2683     int
2684     main ()
2685     {
2686       struct MHD_Daemon *daemon;
2687
2688       daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
2689                                  &answer_to_connection, NULL, MHD_OPTION_END);
2690       if (NULL == daemon)
2691         return 1;
2692
2693       (void) getchar ();
2694
2695       MHD_stop_daemon (daemon);
2696       return 0;
2697     }
2698
2699
2700File: libmicrohttpd-tutorial.info,  Node: simplepost.c,  Next: largepost.c,  Prev: basicauthentication.c,  Up: Example programs
2701
2702C.5 simplepost.c
2703================
2704
2705     /* Feel free to use this example code in any way
2706        you see fit (Public Domain) */
2707
2708     #include <sys/types.h>
2709     #ifndef _WIN32
2710     #include <sys/select.h>
2711     #include <sys/socket.h>
2712     #else
2713     #include <winsock2.h>
2714     #endif
2715     #include <microhttpd.h>
2716     #include <stdio.h>
2717     #include <string.h>
2718     #include <stdlib.h>
2719
2720     #define PORT            8888
2721     #define POSTBUFFERSIZE  512
2722     #define MAXNAMESIZE     20
2723     #define MAXANSWERSIZE   512
2724
2725     #define GET             0
2726     #define POST            1
2727
2728     struct connection_info_struct
2729     {
2730       int connectiontype;
2731       char *answerstring;
2732       struct MHD_PostProcessor *postprocessor;
2733     };
2734
2735     const char *askpage = "<html><body>\
2736                            What's your name, Sir?<br>\
2737                            <form action=\"/namepost\" method=\"post\">\
2738                            <input name=\"name\" type=\"text\"\
2739                            <input type=\"submit\" value=\" Send \"></form>\
2740                            </body></html>";
2741
2742     const char *greetingpage =
2743       "<html><body><h1>Welcome, %s!</center></h1></body></html>";
2744
2745     const char *errorpage =
2746       "<html><body>This doesn't seem to be right.</body></html>";
2747
2748
2749     static int
2750     send_page (struct MHD_Connection *connection, const char *page)
2751     {
2752       int ret;
2753       struct MHD_Response *response;
2754
2755
2756       response =
2757         MHD_create_response_from_buffer (strlen (page), (void *) page,
2758     				     MHD_RESPMEM_PERSISTENT);
2759       if (!response)
2760         return MHD_NO;
2761
2762       ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
2763       MHD_destroy_response (response);
2764
2765       return ret;
2766     }
2767
2768
2769     static int
2770     iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
2771                   const char *filename, const char *content_type,
2772                   const char *transfer_encoding, const char *data, uint64_t off,
2773                   size_t size)
2774     {
2775       struct connection_info_struct *con_info = coninfo_cls;
2776
2777       if (0 == strcmp (key, "name"))
2778         {
2779           if ((size > 0) && (size <= MAXNAMESIZE))
2780             {
2781               char *answerstring;
2782               answerstring = malloc (MAXANSWERSIZE);
2783               if (!answerstring)
2784                 return MHD_NO;
2785
2786               snprintf (answerstring, MAXANSWERSIZE, greetingpage, data);
2787               con_info->answerstring = answerstring;
2788             }
2789           else
2790             con_info->answerstring = NULL;
2791
2792           return MHD_NO;
2793         }
2794
2795       return MHD_YES;
2796     }
2797
2798     static void
2799     request_completed (void *cls, struct MHD_Connection *connection,
2800                        void **con_cls, enum MHD_RequestTerminationCode toe)
2801     {
2802       struct connection_info_struct *con_info = *con_cls;
2803
2804       if (NULL == con_info)
2805         return;
2806
2807       if (con_info->connectiontype == POST)
2808         {
2809           MHD_destroy_post_processor (con_info->postprocessor);
2810           if (con_info->answerstring)
2811             free (con_info->answerstring);
2812         }
2813
2814       free (con_info);
2815       *con_cls = NULL;
2816     }
2817
2818
2819     static int
2820     answer_to_connection (void *cls, struct MHD_Connection *connection,
2821                           const char *url, const char *method,
2822                           const char *version, const char *upload_data,
2823                           size_t *upload_data_size, void **con_cls)
2824     {
2825       if (NULL == *con_cls)
2826         {
2827           struct connection_info_struct *con_info;
2828
2829           con_info = malloc (sizeof (struct connection_info_struct));
2830           if (NULL == con_info)
2831             return MHD_NO;
2832           con_info->answerstring = NULL;
2833
2834           if (0 == strcmp (method, "POST"))
2835             {
2836               con_info->postprocessor =
2837                 MHD_create_post_processor (connection, POSTBUFFERSIZE,
2838                                            iterate_post, (void *) con_info);
2839
2840               if (NULL == con_info->postprocessor)
2841                 {
2842                   free (con_info);
2843                   return MHD_NO;
2844                 }
2845
2846               con_info->connectiontype = POST;
2847             }
2848           else
2849             con_info->connectiontype = GET;
2850
2851           *con_cls = (void *) con_info;
2852
2853           return MHD_YES;
2854         }
2855
2856       if (0 == strcmp (method, "GET"))
2857         {
2858           return send_page (connection, askpage);
2859         }
2860
2861       if (0 == strcmp (method, "POST"))
2862         {
2863           struct connection_info_struct *con_info = *con_cls;
2864
2865           if (*upload_data_size != 0)
2866             {
2867               MHD_post_process (con_info->postprocessor, upload_data,
2868                                 *upload_data_size);
2869               *upload_data_size = 0;
2870
2871               return MHD_YES;
2872             }
2873           else if (NULL != con_info->answerstring)
2874             return send_page (connection, con_info->answerstring);
2875         }
2876
2877       return send_page (connection, errorpage);
2878     }
2879
2880     int
2881     main ()
2882     {
2883       struct MHD_Daemon *daemon;
2884
2885       daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
2886                                  &answer_to_connection, NULL,
2887                                  MHD_OPTION_NOTIFY_COMPLETED, request_completed,
2888                                  NULL, MHD_OPTION_END);
2889       if (NULL == daemon)
2890         return 1;
2891
2892       (void) getchar ();
2893
2894       MHD_stop_daemon (daemon);
2895
2896       return 0;
2897     }
2898
2899
2900File: libmicrohttpd-tutorial.info,  Node: largepost.c,  Next: sessions.c,  Prev: simplepost.c,  Up: Example programs
2901
2902C.6 largepost.c
2903===============
2904
2905     /* Feel free to use this example code in any way
2906        you see fit (Public Domain) */
2907
2908     #include <sys/types.h>
2909     #ifndef _WIN32
2910     #include <sys/select.h>
2911     #include <sys/socket.h>
2912     #else
2913     #include <winsock2.h>
2914     #endif
2915     #include <stdio.h>
2916     #include <stdlib.h>
2917     #include <string.h>
2918     #include <microhttpd.h>
2919
2920     #define PORT            8888
2921     #define POSTBUFFERSIZE  512
2922     #define MAXCLIENTS      2
2923
2924     #define GET             0
2925     #define POST            1
2926
2927     static unsigned int nr_of_uploading_clients = 0;
2928
2929     struct connection_info_struct
2930     {
2931       int connectiontype;
2932       struct MHD_PostProcessor *postprocessor;
2933       FILE *fp;
2934       const char *answerstring;
2935       int answercode;
2936     };
2937
2938     const char *askpage = "<html><body>\n\
2939                            Upload a file, please!<br>\n\
2940                            There are %u clients uploading at the moment.<br>\n\
2941                            <form action=\"/filepost\" method=\"post\" enctype=\"multipart/form-data\">\n\
2942                            <input name=\"file\" type=\"file\">\n\
2943                            <input type=\"submit\" value=\" Send \"></form>\n\
2944                            </body></html>";
2945
2946     const char *busypage =
2947       "<html><body>This server is busy, please try again later.</body></html>";
2948
2949     const char *completepage =
2950       "<html><body>The upload has been completed.</body></html>";
2951
2952     const char *errorpage =
2953       "<html><body>This doesn't seem to be right.</body></html>";
2954     const char *servererrorpage =
2955       "<html><body>An internal server error has occured.</body></html>";
2956     const char *fileexistspage =
2957       "<html><body>This file already exists.</body></html>";
2958
2959
2960     static int
2961     send_page (struct MHD_Connection *connection, const char *page,
2962                int status_code)
2963     {
2964       int ret;
2965       struct MHD_Response *response;
2966
2967       response =
2968         MHD_create_response_from_buffer (strlen (page), (void *) page,
2969     				     MHD_RESPMEM_MUST_COPY);
2970       if (!response)
2971         return MHD_NO;
2972       MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE, "text/html");
2973       ret = MHD_queue_response (connection, status_code, response);
2974       MHD_destroy_response (response);
2975
2976       return ret;
2977     }
2978
2979
2980     static int
2981     iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
2982                   const char *filename, const char *content_type,
2983                   const char *transfer_encoding, const char *data, uint64_t off,
2984                   size_t size)
2985     {
2986       struct connection_info_struct *con_info = coninfo_cls;
2987       FILE *fp;
2988
2989       con_info->answerstring = servererrorpage;
2990       con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
2991
2992       if (0 != strcmp (key, "file"))
2993         return MHD_NO;
2994
2995       if (!con_info->fp)
2996         {
2997           if (NULL != (fp = fopen (filename, "rb")))
2998             {
2999               fclose (fp);
3000               con_info->answerstring = fileexistspage;
3001               con_info->answercode = MHD_HTTP_FORBIDDEN;
3002               return MHD_NO;
3003             }
3004
3005           con_info->fp = fopen (filename, "ab");
3006           if (!con_info->fp)
3007             return MHD_NO;
3008         }
3009
3010       if (size > 0)
3011         {
3012           if (!fwrite (data, size, sizeof (char), con_info->fp))
3013             return MHD_NO;
3014         }
3015
3016       con_info->answerstring = completepage;
3017       con_info->answercode = MHD_HTTP_OK;
3018
3019       return MHD_YES;
3020     }
3021
3022
3023     static void
3024     request_completed (void *cls, struct MHD_Connection *connection,
3025                        void **con_cls, enum MHD_RequestTerminationCode toe)
3026     {
3027       struct connection_info_struct *con_info = *con_cls;
3028
3029       if (NULL == con_info)
3030         return;
3031
3032       if (con_info->connectiontype == POST)
3033         {
3034           if (NULL != con_info->postprocessor)
3035             {
3036               MHD_destroy_post_processor (con_info->postprocessor);
3037               nr_of_uploading_clients--;
3038             }
3039
3040           if (con_info->fp)
3041             fclose (con_info->fp);
3042         }
3043
3044       free (con_info);
3045       *con_cls = NULL;
3046     }
3047
3048
3049     static int
3050     answer_to_connection (void *cls, struct MHD_Connection *connection,
3051                           const char *url, const char *method,
3052                           const char *version, const char *upload_data,
3053                           size_t *upload_data_size, void **con_cls)
3054     {
3055       if (NULL == *con_cls)
3056         {
3057           struct connection_info_struct *con_info;
3058
3059           if (nr_of_uploading_clients >= MAXCLIENTS)
3060             return send_page (connection, busypage, MHD_HTTP_SERVICE_UNAVAILABLE);
3061
3062           con_info = malloc (sizeof (struct connection_info_struct));
3063           if (NULL == con_info)
3064             return MHD_NO;
3065
3066           con_info->fp = NULL;
3067
3068           if (0 == strcmp (method, "POST"))
3069             {
3070               con_info->postprocessor =
3071                 MHD_create_post_processor (connection, POSTBUFFERSIZE,
3072                                            iterate_post, (void *) con_info);
3073
3074               if (NULL == con_info->postprocessor)
3075                 {
3076                   free (con_info);
3077                   return MHD_NO;
3078                 }
3079
3080               nr_of_uploading_clients++;
3081
3082               con_info->connectiontype = POST;
3083               con_info->answercode = MHD_HTTP_OK;
3084               con_info->answerstring = completepage;
3085             }
3086           else
3087             con_info->connectiontype = GET;
3088
3089           *con_cls = (void *) con_info;
3090
3091           return MHD_YES;
3092         }
3093
3094       if (0 == strcmp (method, "GET"))
3095         {
3096           char buffer[1024];
3097
3098           snprintf (buffer, sizeof (buffer), askpage, nr_of_uploading_clients);
3099           return send_page (connection, buffer, MHD_HTTP_OK);
3100         }
3101
3102       if (0 == strcmp (method, "POST"))
3103         {
3104           struct connection_info_struct *con_info = *con_cls;
3105
3106           if (0 != *upload_data_size)
3107             {
3108               MHD_post_process (con_info->postprocessor, upload_data,
3109                                 *upload_data_size);
3110               *upload_data_size = 0;
3111
3112               return MHD_YES;
3113             }
3114           else
3115     	{
3116     	  if (NULL != con_info->fp)
3117     	  {
3118     	    fclose (con_info->fp);
3119     	    con_info->fp = NULL;
3120     	  }
3121     	  /* Now it is safe to open and inspect the file before calling send_page with a response */
3122     	  return send_page (connection, con_info->answerstring,
3123     			    con_info->answercode);
3124     	}
3125
3126         }
3127
3128       return send_page (connection, errorpage, MHD_HTTP_BAD_REQUEST);
3129     }
3130
3131
3132     int
3133     main ()
3134     {
3135       struct MHD_Daemon *daemon;
3136
3137       daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
3138                                  &answer_to_connection, NULL,
3139                                  MHD_OPTION_NOTIFY_COMPLETED, request_completed,
3140                                  NULL, MHD_OPTION_END);
3141       if (NULL == daemon)
3142         return 1;
3143       (void) getchar ();
3144       MHD_stop_daemon (daemon);
3145       return 0;
3146     }
3147
3148
3149File: libmicrohttpd-tutorial.info,  Node: sessions.c,  Next: tlsauthentication.c,  Prev: largepost.c,  Up: Example programs
3150
3151C.7 sessions.c
3152==============
3153
3154     /* Feel free to use this example code in any way
3155        you see fit (Public Domain) */
3156
3157     /* needed for asprintf */
3158     #define _GNU_SOURCE
3159
3160     #include <stdlib.h>
3161     #include <string.h>
3162     #include <stdio.h>
3163     #include <errno.h>
3164     #include <time.h>
3165     #include <microhttpd.h>
3166
3167     #if defined _WIN32 && !defined(__MINGW64_VERSION_MAJOR)
3168     static int
3169     asprintf (char **resultp, const char *format, ...)
3170     {
3171       va_list argptr;
3172       char *result = NULL;
3173       int len = 0;
3174
3175       if (format == NULL)
3176         return -1;
3177
3178       va_start (argptr, format);
3179
3180       len = _vscprintf ((char *) format, argptr);
3181       if (len >= 0)
3182       {
3183         len += 1;
3184         result = (char *) malloc (sizeof (char *) * len);
3185         if (result != NULL)
3186         {
3187           int len2 = _vscprintf ((char *) format, argptr);
3188           if (len2 != len - 1 || len2 <= 0)
3189           {
3190             free (result);
3191             result = NULL;
3192             len = -1;
3193           }
3194           else
3195           {
3196             len = len2;
3197             if (resultp)
3198               *resultp = result;
3199           }
3200         }
3201       }
3202       va_end (argptr);
3203       return len;
3204     }
3205     #endif
3206
3207     /**
3208      * Invalid method page.
3209      */
3210     #define METHOD_ERROR "<html><head><title>Illegal request</title></head><body>Go away.</body></html>"
3211
3212     /**
3213      * Invalid URL page.
3214      */
3215     #define NOT_FOUND_ERROR "<html><head><title>Not found</title></head><body>Go away.</body></html>"
3216
3217     /**
3218      * Front page. (/)
3219      */
3220     #define MAIN_PAGE "<html><head><title>Welcome</title></head><body><form action=\"/2\" method=\"post\">What is your name? <input type=\"text\" name=\"v1\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
3221
3222     /**
3223      * Second page. (/2)
3224      */
3225     #define SECOND_PAGE "<html><head><title>Tell me more</title></head><body><a href=\"/\">previous</a> <form action=\"/S\" method=\"post\">%s, what is your job? <input type=\"text\" name=\"v2\" value=\"%s\" /><input type=\"submit\" value=\"Next\" /></body></html>"
3226
3227     /**
3228      * Second page (/S)
3229      */
3230     #define SUBMIT_PAGE "<html><head><title>Ready to submit?</title></head><body><form action=\"/F\" method=\"post\"><a href=\"/2\">previous </a> <input type=\"hidden\" name=\"DONE\" value=\"yes\" /><input type=\"submit\" value=\"Submit\" /></body></html>"
3231
3232     /**
3233      * Last page.
3234      */
3235     #define LAST_PAGE "<html><head><title>Thank you</title></head><body>Thank you.</body></html>"
3236
3237     /**
3238      * Name of our cookie.
3239      */
3240     #define COOKIE_NAME "session"
3241
3242
3243     /**
3244      * State we keep for each user/session/browser.
3245      */
3246     struct Session
3247     {
3248       /**
3249        * We keep all sessions in a linked list.
3250        */
3251       struct Session *next;
3252
3253       /**
3254        * Unique ID for this session.
3255        */
3256       char sid[33];
3257
3258       /**
3259        * Reference counter giving the number of connections
3260        * currently using this session.
3261        */
3262       unsigned int rc;
3263
3264       /**
3265        * Time when this session was last active.
3266        */
3267       time_t start;
3268
3269       /**
3270        * String submitted via form.
3271        */
3272       char value_1[64];
3273
3274       /**
3275        * Another value submitted via form.
3276        */
3277       char value_2[64];
3278
3279     };
3280
3281
3282     /**
3283      * Data kept per request.
3284      */
3285     struct Request
3286     {
3287
3288       /**
3289        * Associated session.
3290        */
3291       struct Session *session;
3292
3293       /**
3294        * Post processor handling form data (IF this is
3295        * a POST request).
3296        */
3297       struct MHD_PostProcessor *pp;
3298
3299       /**
3300        * URL to serve in response to this POST (if this request
3301        * was a 'POST')
3302        */
3303       const char *post_url;
3304
3305     };
3306
3307
3308     /**
3309      * Linked list of all active sessions.  Yes, O(n) but a
3310      * hash table would be overkill for a simple example...
3311      */
3312     static struct Session *sessions;
3313
3314
3315
3316
3317     /**
3318      * Return the session handle for this connection, or
3319      * create one if this is a new user.
3320      */
3321     static struct Session *
3322     get_session (struct MHD_Connection *connection)
3323     {
3324       struct Session *ret;
3325       const char *cookie;
3326
3327       cookie = MHD_lookup_connection_value (connection,
3328     					MHD_COOKIE_KIND,
3329     					COOKIE_NAME);
3330       if (cookie != NULL)
3331         {
3332           /* find existing session */
3333           ret = sessions;
3334           while (NULL != ret)
3335     	{
3336     	  if (0 == strcmp (cookie, ret->sid))
3337     	    break;
3338     	  ret = ret->next;
3339     	}
3340           if (NULL != ret)
3341     	{
3342     	  ret->rc++;
3343     	  return ret;
3344     	}
3345         }
3346       /* create fresh session */
3347       ret = calloc (1, sizeof (struct Session));
3348       if (NULL == ret)
3349         {
3350           fprintf (stderr, "calloc error: %s\n", strerror (errno));
3351           return NULL;
3352         }
3353       /* not a super-secure way to generate a random session ID,
3354          but should do for a simple example... */
3355       snprintf (ret->sid,
3356     	    sizeof (ret->sid),
3357     	    "%X%X%X%X",
3358     	    (unsigned int) rand (),
3359     	    (unsigned int) rand (),
3360     	    (unsigned int) rand (),
3361     	    (unsigned int) rand ());
3362       ret->rc++;
3363       ret->start = time (NULL);
3364       ret->next = sessions;
3365       sessions = ret;
3366       return ret;
3367     }
3368
3369
3370     /**
3371      * Type of handler that generates a reply.
3372      *
3373      * @param cls content for the page (handler-specific)
3374      * @param mime mime type to use
3375      * @param session session information
3376      * @param connection connection to process
3377      * @param MHD_YES on success, MHD_NO on failure
3378      */
3379     typedef int (*PageHandler)(const void *cls,
3380     			   const char *mime,
3381     			   struct Session *session,
3382     			   struct MHD_Connection *connection);
3383
3384
3385     /**
3386      * Entry we generate for each page served.
3387      */
3388     struct Page
3389     {
3390       /**
3391        * Acceptable URL for this page.
3392        */
3393       const char *url;
3394
3395       /**
3396        * Mime type to set for the page.
3397        */
3398       const char *mime;
3399
3400       /**
3401        * Handler to call to generate response.
3402        */
3403       PageHandler handler;
3404
3405       /**
3406        * Extra argument to handler.
3407        */
3408       const void *handler_cls;
3409     };
3410
3411
3412     /**
3413      * Add header to response to set a session cookie.
3414      *
3415      * @param session session to use
3416      * @param response response to modify
3417      */
3418     static void
3419     add_session_cookie (struct Session *session,
3420     		    struct MHD_Response *response)
3421     {
3422       char cstr[256];
3423       snprintf (cstr,
3424     	    sizeof (cstr),
3425     	    "%s=%s",
3426     	    COOKIE_NAME,
3427     	    session->sid);
3428       if (MHD_NO ==
3429           MHD_add_response_header (response,
3430     			       MHD_HTTP_HEADER_SET_COOKIE,
3431     			       cstr))
3432         {
3433           fprintf (stderr,
3434     	       "Failed to set session cookie header!\n");
3435         }
3436     }
3437
3438
3439     /**
3440      * Handler that returns a simple static HTTP page that
3441      * is passed in via 'cls'.
3442      *
3443      * @param cls a 'const char *' with the HTML webpage to return
3444      * @param mime mime type to use
3445      * @param session session handle
3446      * @param connection connection to use
3447      */
3448     static int
3449     serve_simple_form (const void *cls,
3450     		   const char *mime,
3451     		   struct Session *session,
3452     		   struct MHD_Connection *connection)
3453     {
3454       int ret;
3455       const char *form = cls;
3456       struct MHD_Response *response;
3457
3458       /* return static form */
3459       response = MHD_create_response_from_buffer (strlen (form),
3460     					      (void *) form,
3461     					      MHD_RESPMEM_PERSISTENT);
3462       add_session_cookie (session, response);
3463       MHD_add_response_header (response,
3464     			   MHD_HTTP_HEADER_CONTENT_ENCODING,
3465     			   mime);
3466       ret = MHD_queue_response (connection,
3467     			    MHD_HTTP_OK,
3468     			    response);
3469       MHD_destroy_response (response);
3470       return ret;
3471     }
3472
3473
3474     /**
3475      * Handler that adds the 'v1' value to the given HTML code.
3476      *
3477      * @param cls a 'const char *' with the HTML webpage to return
3478      * @param mime mime type to use
3479      * @param session session handle
3480      * @param connection connection to use
3481      */
3482     static int
3483     fill_v1_form (const void *cls,
3484     	      const char *mime,
3485     	      struct Session *session,
3486     	      struct MHD_Connection *connection)
3487     {
3488       int ret;
3489       const char *form = cls;
3490       char *reply;
3491       struct MHD_Response *response;
3492
3493       if (-1 == asprintf (&reply,
3494     		      form,
3495     		      session->value_1))
3496         {
3497           /* oops */
3498           return MHD_NO;
3499         }
3500       /* return static form */
3501       response = MHD_create_response_from_buffer (strlen (reply),
3502     					      (void *) reply,
3503     					      MHD_RESPMEM_MUST_FREE);
3504       add_session_cookie (session, response);
3505       MHD_add_response_header (response,
3506     			   MHD_HTTP_HEADER_CONTENT_ENCODING,
3507     			   mime);
3508       ret = MHD_queue_response (connection,
3509     			    MHD_HTTP_OK,
3510     			    response);
3511       MHD_destroy_response (response);
3512       return ret;
3513     }
3514
3515
3516     /**
3517      * Handler that adds the 'v1' and 'v2' values to the given HTML code.
3518      *
3519      * @param cls a 'const char *' with the HTML webpage to return
3520      * @param mime mime type to use
3521      * @param session session handle
3522      * @param connection connection to use
3523      */
3524     static int
3525     fill_v1_v2_form (const void *cls,
3526     		 const char *mime,
3527     		 struct Session *session,
3528     		 struct MHD_Connection *connection)
3529     {
3530       int ret;
3531       const char *form = cls;
3532       char *reply;
3533       struct MHD_Response *response;
3534
3535       if (-1 == asprintf (&reply,
3536     		      form,
3537     		      session->value_1,
3538     		      session->value_2))
3539         {
3540           /* oops */
3541           return MHD_NO;
3542         }
3543       /* return static form */
3544       response = MHD_create_response_from_buffer (strlen (reply),
3545     					      (void *) reply,
3546     					      MHD_RESPMEM_MUST_FREE);
3547       add_session_cookie (session, response);
3548       MHD_add_response_header (response,
3549     			   MHD_HTTP_HEADER_CONTENT_ENCODING,
3550     			   mime);
3551       ret = MHD_queue_response (connection,
3552     			    MHD_HTTP_OK,
3553     			    response);
3554       MHD_destroy_response (response);
3555       return ret;
3556     }
3557
3558
3559     /**
3560      * Handler used to generate a 404 reply.
3561      *
3562      * @param cls a 'const char *' with the HTML webpage to return
3563      * @param mime mime type to use
3564      * @param session session handle
3565      * @param connection connection to use
3566      */
3567     static int
3568     not_found_page (const void *cls,
3569     		const char *mime,
3570     		struct Session *session,
3571     		struct MHD_Connection *connection)
3572     {
3573       int ret;
3574       struct MHD_Response *response;
3575
3576       /* unsupported HTTP method */
3577       response = MHD_create_response_from_buffer (strlen (NOT_FOUND_ERROR),
3578     					      (void *) NOT_FOUND_ERROR,
3579     					      MHD_RESPMEM_PERSISTENT);
3580       ret = MHD_queue_response (connection,
3581     			    MHD_HTTP_NOT_FOUND,
3582     			    response);
3583       MHD_add_response_header (response,
3584     			   MHD_HTTP_HEADER_CONTENT_ENCODING,
3585     			   mime);
3586       MHD_destroy_response (response);
3587       return ret;
3588     }
3589
3590
3591     /**
3592      * List of all pages served by this HTTP server.
3593      */
3594     static struct Page pages[] =
3595       {
3596         { "/", "text/html",  &fill_v1_form, MAIN_PAGE },
3597         { "/2", "text/html", &fill_v1_v2_form, SECOND_PAGE },
3598         { "/S", "text/html", &serve_simple_form, SUBMIT_PAGE },
3599         { "/F", "text/html", &serve_simple_form, LAST_PAGE },
3600         { NULL, NULL, &not_found_page, NULL } /* 404 */
3601       };
3602
3603
3604
3605     /**
3606      * Iterator over key-value pairs where the value
3607      * maybe made available in increments and/or may
3608      * not be zero-terminated.  Used for processing
3609      * POST data.
3610      *
3611      * @param cls user-specified closure
3612      * @param kind type of the value
3613      * @param key 0-terminated key for the value
3614      * @param filename name of the uploaded file, NULL if not known
3615      * @param content_type mime-type of the data, NULL if not known
3616      * @param transfer_encoding encoding of the data, NULL if not known
3617      * @param data pointer to size bytes of data at the
3618      *              specified offset
3619      * @param off offset of data in the overall value
3620      * @param size number of bytes in data available
3621      * @return MHD_YES to continue iterating,
3622      *         MHD_NO to abort the iteration
3623      */
3624     static int
3625     post_iterator (void *cls,
3626     	       enum MHD_ValueKind kind,
3627     	       const char *key,
3628     	       const char *filename,
3629     	       const char *content_type,
3630     	       const char *transfer_encoding,
3631     	       const char *data, uint64_t off, size_t size)
3632     {
3633       struct Request *request = cls;
3634       struct Session *session = request->session;
3635
3636       if (0 == strcmp ("DONE", key))
3637         {
3638           fprintf (stdout,
3639     	       "Session `%s' submitted `%s', `%s'\n",
3640     	       session->sid,
3641     	       session->value_1,
3642     	       session->value_2);
3643           return MHD_YES;
3644         }
3645       if (0 == strcmp ("v1", key))
3646         {
3647           if (size + off > sizeof(session->value_1))
3648     	size = sizeof (session->value_1) - off;
3649           memcpy (&session->value_1[off],
3650     	      data,
3651     	      size);
3652           if (size + off < sizeof (session->value_1))
3653     	session->value_1[size+off] = '\0';
3654           return MHD_YES;
3655         }
3656       if (0 == strcmp ("v2", key))
3657         {
3658           if (size + off > sizeof(session->value_2))
3659     	size = sizeof (session->value_2) - off;
3660           memcpy (&session->value_2[off],
3661     	      data,
3662     	      size);
3663           if (size + off < sizeof (session->value_2))
3664     	session->value_2[size+off] = '\0';
3665           return MHD_YES;
3666         }
3667       fprintf (stderr, "Unsupported form value `%s'\n", key);
3668       return MHD_YES;
3669     }
3670
3671
3672     /**
3673      * Main MHD callback for handling requests.
3674      *
3675      *
3676      * @param cls argument given together with the function
3677      *        pointer when the handler was registered with MHD
3678      * @param connection handle to connection which is being processed
3679      * @param url the requested url
3680      * @param method the HTTP method used ("GET", "PUT", etc.)
3681      * @param version the HTTP version string (i.e. "HTTP/1.1")
3682      * @param upload_data the data being uploaded (excluding HEADERS,
3683      *        for a POST that fits into memory and that is encoded
3684      *        with a supported encoding, the POST data will NOT be
3685      *        given in upload_data and is instead available as
3686      *        part of MHD_get_connection_values; very large POST
3687      *        data *will* be made available incrementally in
3688      *        upload_data)
3689      * @param upload_data_size set initially to the size of the
3690      *        upload_data provided; the method must update this
3691      *        value to the number of bytes NOT processed;
3692      * @param ptr pointer that the callback can set to some
3693      *        address and that will be preserved by MHD for future
3694      *        calls for this request; since the access handler may
3695      *        be called many times (i.e., for a PUT/POST operation
3696      *        with plenty of upload data) this allows the application
3697      *        to easily associate some request-specific state.
3698      *        If necessary, this state can be cleaned up in the
3699      *        global "MHD_RequestCompleted" callback (which
3700      *        can be set with the MHD_OPTION_NOTIFY_COMPLETED).
3701      *        Initially, <tt>*con_cls</tt> will be NULL.
3702      * @return MHS_YES if the connection was handled successfully,
3703      *         MHS_NO if the socket must be closed due to a serios
3704      *         error while handling the request
3705      */
3706     static int
3707     create_response (void *cls,
3708     		 struct MHD_Connection *connection,
3709     		 const char *url,
3710     		 const char *method,
3711     		 const char *version,
3712     		 const char *upload_data,
3713     		 size_t *upload_data_size,
3714     		 void **ptr)
3715     {
3716       struct MHD_Response *response;
3717       struct Request *request;
3718       struct Session *session;
3719       int ret;
3720       unsigned int i;
3721
3722       request = *ptr;
3723       if (NULL == request)
3724         {
3725           request = calloc (1, sizeof (struct Request));
3726           if (NULL == request)
3727     	{
3728     	  fprintf (stderr, "calloc error: %s\n", strerror (errno));
3729     	  return MHD_NO;
3730     	}
3731           *ptr = request;
3732           if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
3733     	{
3734     	  request->pp = MHD_create_post_processor (connection, 1024,
3735     						   &post_iterator, request);
3736     	  if (NULL == request->pp)
3737     	    {
3738     	      fprintf (stderr, "Failed to setup post processor for `%s'\n",
3739     		       url);
3740     	      return MHD_NO; /* internal error */
3741     	    }
3742     	}
3743           return MHD_YES;
3744         }
3745       if (NULL == request->session)
3746         {
3747           request->session = get_session (connection);
3748           if (NULL == request->session)
3749     	{
3750     	  fprintf (stderr, "Failed to setup session for `%s'\n",
3751     		   url);
3752     	  return MHD_NO; /* internal error */
3753     	}
3754         }
3755       session = request->session;
3756       session->start = time (NULL);
3757       if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
3758         {
3759           /* evaluate POST data */
3760           MHD_post_process (request->pp,
3761     			upload_data,
3762     			*upload_data_size);
3763           if (0 != *upload_data_size)
3764     	{
3765     	  *upload_data_size = 0;
3766     	  return MHD_YES;
3767     	}
3768           /* done with POST data, serve response */
3769           MHD_destroy_post_processor (request->pp);
3770           request->pp = NULL;
3771           method = MHD_HTTP_METHOD_GET; /* fake 'GET' */
3772           if (NULL != request->post_url)
3773     	url = request->post_url;
3774         }
3775
3776       if ( (0 == strcmp (method, MHD_HTTP_METHOD_GET)) ||
3777            (0 == strcmp (method, MHD_HTTP_METHOD_HEAD)) )
3778         {
3779           /* find out which page to serve */
3780           i=0;
3781           while ( (pages[i].url != NULL) &&
3782     	      (0 != strcmp (pages[i].url, url)) )
3783     	i++;
3784           ret = pages[i].handler (pages[i].handler_cls,
3785     			      pages[i].mime,
3786     			      session, connection);
3787           if (ret != MHD_YES)
3788     	fprintf (stderr, "Failed to create page for `%s'\n",
3789     		 url);
3790           return ret;
3791         }
3792       /* unsupported HTTP method */
3793       response = MHD_create_response_from_buffer (strlen (METHOD_ERROR),
3794     					      (void *) METHOD_ERROR,
3795     					      MHD_RESPMEM_PERSISTENT);
3796       ret = MHD_queue_response (connection,
3797     			    MHD_HTTP_METHOD_NOT_ACCEPTABLE,
3798     			    response);
3799       MHD_destroy_response (response);
3800       return ret;
3801     }
3802
3803
3804     /**
3805      * Callback called upon completion of a request.
3806      * Decrements session reference counter.
3807      *
3808      * @param cls not used
3809      * @param connection connection that completed
3810      * @param con_cls session handle
3811      * @param toe status code
3812      */
3813     static void
3814     request_completed_callback (void *cls,
3815     			    struct MHD_Connection *connection,
3816     			    void **con_cls,
3817     			    enum MHD_RequestTerminationCode toe)
3818     {
3819       struct Request *request = *con_cls;
3820
3821       if (NULL == request)
3822         return;
3823       if (NULL != request->session)
3824         request->session->rc--;
3825       if (NULL != request->pp)
3826         MHD_destroy_post_processor (request->pp);
3827       free (request);
3828     }
3829
3830
3831     /**
3832      * Clean up handles of sessions that have been idle for
3833      * too long.
3834      */
3835     static void
3836     expire_sessions ()
3837     {
3838       struct Session *pos;
3839       struct Session *prev;
3840       struct Session *next;
3841       time_t now;
3842
3843       now = time (NULL);
3844       prev = NULL;
3845       pos = sessions;
3846       while (NULL != pos)
3847         {
3848           next = pos->next;
3849           if (now - pos->start > 60 * 60)
3850     	{
3851     	  /* expire sessions after 1h */
3852     	  if (NULL == prev)
3853     	    sessions = pos->next;
3854     	  else
3855     	    prev->next = next;
3856     	  free (pos);
3857     	}
3858           else
3859             prev = pos;
3860           pos = next;
3861         }
3862     }
3863
3864
3865     /**
3866      * Call with the port number as the only argument.
3867      * Never terminates (other than by signals, such as CTRL-C).
3868      */
3869     int
3870     main (int argc, char *const *argv)
3871     {
3872       struct MHD_Daemon *d;
3873       struct timeval tv;
3874       struct timeval *tvp;
3875       fd_set rs;
3876       fd_set ws;
3877       fd_set es;
3878       int max;
3879       MHD_UNSIGNED_LONG_LONG mhd_timeout;
3880
3881       if (argc != 2)
3882         {
3883           printf ("%s PORT\n", argv[0]);
3884           return 1;
3885         }
3886       /* initialize PRNG */
3887       srand ((unsigned int) time (NULL));
3888       d = MHD_start_daemon (MHD_USE_DEBUG,
3889                             atoi (argv[1]),
3890                             NULL, NULL,
3891     			&create_response, NULL,
3892     			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 15,
3893     			MHD_OPTION_NOTIFY_COMPLETED, &request_completed_callback, NULL,
3894     			MHD_OPTION_END);
3895       if (NULL == d)
3896         return 1;
3897       while (1)
3898         {
3899           expire_sessions ();
3900           max = 0;
3901           FD_ZERO (&rs);
3902           FD_ZERO (&ws);
3903           FD_ZERO (&es);
3904           if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
3905     	break; /* fatal internal error */
3906           if (MHD_get_timeout (d, &mhd_timeout) == MHD_YES)
3907     	{
3908     	  tv.tv_sec = mhd_timeout / 1000;
3909     	  tv.tv_usec = (mhd_timeout - (tv.tv_sec * 1000)) * 1000;
3910     	  tvp = &tv;
3911     	}
3912           else
3913     	tvp = NULL;
3914           if (-1 == select (max + 1, &rs, &ws, &es, tvp))
3915     	{
3916     	  if (EINTR != errno)
3917     	    fprintf (stderr,
3918     		     "Aborting due to error during select: %s\n",
3919     		     strerror (errno));
3920     	  break;
3921     	}
3922           MHD_run (d);
3923         }
3924       MHD_stop_daemon (d);
3925       return 0;
3926     }
3927
3928
3929File: libmicrohttpd-tutorial.info,  Node: tlsauthentication.c,  Prev: sessions.c,  Up: Example programs
3930
3931C.8 tlsauthentication.c
3932=======================
3933
3934     /* Feel free to use this example code in any way
3935        you see fit (Public Domain) */
3936
3937     #include <sys/types.h>
3938     #ifndef _WIN32
3939     #include <sys/select.h>
3940     #include <sys/socket.h>
3941     #else
3942     #include <winsock2.h>
3943     #endif
3944     #include <microhttpd.h>
3945     #include <string.h>
3946     #include <stdio.h>
3947     #include <stdlib.h>
3948
3949     #define PORT 8888
3950
3951     #define REALM     "\"Maintenance\""
3952     #define USER      "a legitimate user"
3953     #define PASSWORD  "and his password"
3954
3955     #define SERVERKEYFILE "server.key"
3956     #define SERVERCERTFILE "server.pem"
3957
3958
3959     static char *
3960     string_to_base64 (const char *message)
3961     {
3962       const char *lookup =
3963         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3964       unsigned long l;
3965       int i;
3966       char *tmp;
3967       size_t length = strlen (message);
3968
3969       tmp = malloc (length * 2);
3970       if (NULL == tmp)
3971         return tmp;
3972
3973       tmp[0] = 0;
3974
3975       for (i = 0; i < length; i += 3)
3976         {
3977           l = (((unsigned long) message[i]) << 16)
3978             | (((i + 1) < length) ? (((unsigned long) message[i + 1]) << 8) : 0)
3979             | (((i + 2) < length) ? ((unsigned long) message[i + 2]) : 0);
3980
3981
3982           strncat (tmp, &lookup[(l >> 18) & 0x3F], 1);
3983           strncat (tmp, &lookup[(l >> 12) & 0x3F], 1);
3984
3985           if (i + 1 < length)
3986             strncat (tmp, &lookup[(l >> 6) & 0x3F], 1);
3987           if (i + 2 < length)
3988             strncat (tmp, &lookup[l & 0x3F], 1);
3989         }
3990
3991       if (length % 3)
3992         strncat (tmp, "===", 3 - length % 3);
3993
3994       return tmp;
3995     }
3996
3997
3998     static long
3999     get_file_size (const char *filename)
4000     {
4001       FILE *fp;
4002
4003       fp = fopen (filename, "rb");
4004       if (fp)
4005         {
4006           long size;
4007
4008           if ((0 != fseek (fp, 0, SEEK_END)) || (-1 == (size = ftell (fp))))
4009             size = 0;
4010
4011           fclose (fp);
4012
4013           return size;
4014         }
4015       else
4016         return 0;
4017     }
4018
4019     static char *
4020     load_file (const char *filename)
4021     {
4022       FILE *fp;
4023       char *buffer;
4024       long size;
4025
4026       size = get_file_size (filename);
4027       if (size == 0)
4028         return NULL;
4029
4030       fp = fopen (filename, "rb");
4031       if (!fp)
4032         return NULL;
4033
4034       buffer = malloc (size);
4035       if (!buffer)
4036         {
4037           fclose (fp);
4038           return NULL;
4039         }
4040
4041       if (size != fread (buffer, 1, size, fp))
4042         {
4043           free (buffer);
4044           buffer = NULL;
4045         }
4046
4047       fclose (fp);
4048       return buffer;
4049     }
4050
4051     static int
4052     ask_for_authentication (struct MHD_Connection *connection, const char *realm)
4053     {
4054       int ret;
4055       struct MHD_Response *response;
4056       char *headervalue;
4057       const char *strbase = "Basic realm=";
4058
4059       response = MHD_create_response_from_buffer (0, NULL,
4060     					      MHD_RESPMEM_PERSISTENT);
4061       if (!response)
4062         return MHD_NO;
4063
4064       headervalue = malloc (strlen (strbase) + strlen (realm) + 1);
4065       if (!headervalue)
4066         return MHD_NO;
4067
4068       strcpy (headervalue, strbase);
4069       strcat (headervalue, realm);
4070
4071       ret = MHD_add_response_header (response, "WWW-Authenticate", headervalue);
4072       free (headervalue);
4073       if (!ret)
4074         {
4075           MHD_destroy_response (response);
4076           return MHD_NO;
4077         }
4078
4079       ret = MHD_queue_response (connection, MHD_HTTP_UNAUTHORIZED, response);
4080
4081       MHD_destroy_response (response);
4082
4083       return ret;
4084     }
4085
4086     static int
4087     is_authenticated (struct MHD_Connection *connection,
4088                       const char *username, const char *password)
4089     {
4090       const char *headervalue;
4091       char *expected_b64, *expected;
4092       const char *strbase = "Basic ";
4093       int authenticated;
4094
4095       headervalue =
4096         MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
4097                                      "Authorization");
4098       if (NULL == headervalue)
4099         return 0;
4100       if (0 != strncmp (headervalue, strbase, strlen (strbase)))
4101         return 0;
4102
4103       expected = malloc (strlen (username) + 1 + strlen (password) + 1);
4104       if (NULL == expected)
4105         return 0;
4106
4107       strcpy (expected, username);
4108       strcat (expected, ":");
4109       strcat (expected, password);
4110
4111       expected_b64 = string_to_base64 (expected);
4112       free (expected);
4113       if (NULL == expected_b64)
4114         return 0;
4115
4116       authenticated =
4117         (strcmp (headervalue + strlen (strbase), expected_b64) == 0);
4118
4119       free (expected_b64);
4120
4121       return authenticated;
4122     }
4123
4124
4125     static int
4126     secret_page (struct MHD_Connection *connection)
4127     {
4128       int ret;
4129       struct MHD_Response *response;
4130       const char *page = "<html><body>A secret.</body></html>";
4131
4132       response =
4133         MHD_create_response_from_buffer (strlen (page), (void *) page,
4134     				     MHD_RESPMEM_PERSISTENT);
4135       if (!response)
4136         return MHD_NO;
4137
4138       ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
4139       MHD_destroy_response (response);
4140
4141       return ret;
4142     }
4143
4144
4145     static int
4146     answer_to_connection (void *cls, struct MHD_Connection *connection,
4147                           const char *url, const char *method,
4148                           const char *version, const char *upload_data,
4149                           size_t *upload_data_size, void **con_cls)
4150     {
4151       if (0 != strcmp (method, "GET"))
4152         return MHD_NO;
4153       if (NULL == *con_cls)
4154         {
4155           *con_cls = connection;
4156           return MHD_YES;
4157         }
4158
4159       if (!is_authenticated (connection, USER, PASSWORD))
4160         return ask_for_authentication (connection, REALM);
4161
4162       return secret_page (connection);
4163     }
4164
4165
4166     int
4167     main ()
4168     {
4169       struct MHD_Daemon *daemon;
4170       char *key_pem;
4171       char *cert_pem;
4172
4173       key_pem = load_file (SERVERKEYFILE);
4174       cert_pem = load_file (SERVERCERTFILE);
4175
4176       if ((key_pem == NULL) || (cert_pem == NULL))
4177         {
4178           printf ("The key/certificate files could not be read.\n");
4179           return 1;
4180         }
4181
4182       daemon =
4183         MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL, PORT, NULL,
4184                           NULL, &answer_to_connection, NULL,
4185                           MHD_OPTION_HTTPS_MEM_KEY, key_pem,
4186                           MHD_OPTION_HTTPS_MEM_CERT, cert_pem, MHD_OPTION_END);
4187       if (NULL == daemon)
4188         {
4189           printf ("%s\n", cert_pem);
4190
4191           free (key_pem);
4192           free (cert_pem);
4193
4194           return 1;
4195         }
4196
4197       (void) getchar ();
4198
4199       MHD_stop_daemon (daemon);
4200       free (key_pem);
4201       free (cert_pem);
4202
4203       return 0;
4204     }
4205
4206
4207
4208Tag Table:
4209Node: Top866
4210Node: Introduction1917
4211Node: Hello browser example3223
4212Node: Exploring requests14247
4213Node: Response headers19643
4214Node: Supporting basic authentication27522
4215Node: Processing POST data34913
4216Node: Improved processing of POST data43534
4217Node: Session management54177
4218Node: Adding a layer of security57072
4219Node: Bibliography71602
4220Node: License text72797
4221Node: Example programs97972
4222Node: hellobrowser.c98285
4223Node: logging.c99828
4224Node: responseheaders.c101411
4225Node: basicauthentication.c104035
4226Node: simplepost.c106574
4227Node: largepost.c112254
4228Node: sessions.c119619
4229Node: tlsauthentication.c141964
4230
4231End Tag Table
4232