2
0

fileserver_example.pp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. (*
  2. This file is part of libmicrohttpd
  3. Copyright (C) 2007 Christian Grothoff (and other contributing authors)
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  15. *)
  16. (**
  17. * @file fileserver_example.pp (Original: fileserver_example.c)
  18. * @brief minimal example for how to use libmicrohttpd to serve files
  19. * @author Christian Grothoff / Silvio Clécio
  20. *)
  21. program fileserver_example;
  22. {$mode objfpc}{$H+}
  23. uses
  24. sysutils, BaseUnix, cutils, libmicrohttpd;
  25. const
  26. PAGE: Pcchar = '<html><head><title>File not found</title></head><body>File not found</body></html>';
  27. function file_reader(cls: Pointer; pos: cuint64; buf: Pcchar;
  28. max: size_t): ssize_t; cdecl;
  29. var
  30. &file: FILEptr;
  31. begin
  32. &file := cls;
  33. fseek(&file, pos, SEEK_SET);
  34. Result := fread(buf, 1, max, &file);
  35. end;
  36. procedure free_callback(cls: Pointer); cdecl;
  37. var
  38. &file: FILEptr;
  39. begin
  40. &file := cls;
  41. fclose(&file);
  42. end;
  43. function ahc_echo(cls: Pointer; connection: PMHD_Connection; url: Pcchar;
  44. method: Pcchar; version: Pcchar; upload_data: Pcchar;
  45. upload_data_size: Psize_t; ptr: PPointer): cint; cdecl;
  46. const
  47. aptr: cint = 0;
  48. var
  49. response: PMHD_Response;
  50. ret: cint;
  51. &file: FILEptr;
  52. buf: stat;
  53. begin
  54. if (0 <> strcomp(method, MHD_HTTP_METHOD_GET)) and
  55. (0 <> strcomp(method, MHD_HTTP_METHOD_HEAD)) then
  56. Exit(MHD_NO); (* unexpected method *)
  57. if @aptr <> ptr^ then
  58. begin
  59. (* do never respond on first call *)
  60. ptr^ := @aptr;
  61. Exit(MHD_YES);
  62. end;
  63. ptr^ := nil; (* reset when done *)
  64. if 0 = FpStat(@url[1], buf) then
  65. &file := fopen(@url[1], fopenread)
  66. else
  67. &file := nil;
  68. if nil = &file then
  69. begin
  70. response := MHD_create_response_from_buffer(strlen(PAGE), Pointer(PAGE),
  71. MHD_RESPMEM_PERSISTENT);
  72. ret := MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response);
  73. MHD_destroy_response(response);
  74. end
  75. else
  76. begin
  77. response := MHD_create_response_from_callback(buf.st_size, 32 * 1024, (* 32k page size *)
  78. @file_reader, &file, @free_callback);
  79. if nil = response then
  80. begin
  81. fclose(&file);
  82. Exit(MHD_NO);
  83. end;
  84. ret := MHD_queue_response(connection, MHD_HTTP_OK, response);
  85. MHD_destroy_response(response);
  86. end;
  87. Result := ret;
  88. end;
  89. var
  90. d: PMHD_Daemon;
  91. begin
  92. if argc <> 2 then
  93. begin
  94. WriteLn(argv[0], ' PORT');
  95. Halt(1);
  96. end;
  97. d := MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION or MHD_USE_DEBUG,
  98. StrToInt(argv[1]), nil, nil, @ahc_echo, PAGE, MHD_OPTION_END);
  99. if d = nil then
  100. Halt(1);
  101. ReadLn;
  102. MHD_stop_daemon(d);
  103. end.