2
0

simplepost.pp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. (* Feel free to use this example code in any way
  2. you see fit (Public Domain) *)
  3. // Original example: https://gnunet.org/svn/libmicrohttpd/doc/examples/simplepost.c
  4. program simplepost;
  5. {$mode objfpc}{$H+}
  6. uses
  7. SysUtils, cmem, cutils, libmicrohttpd;
  8. const
  9. PORT = 8888;
  10. POSTBUFFERSIZE = 512;
  11. MAXNAMESIZE = 20;
  12. MAXANSWERSIZE = 512;
  13. GET = 0;
  14. POST = 1;
  15. askpage: Pcchar =
  16. '<html><body>'+
  17. 'What''s your name, Sir?<br>'+
  18. '<form action="/namepost" method="post">'+
  19. '<input name="name" type="text">'+
  20. '<input type="submit" value=" Send "></form>'+
  21. '</body></html>';
  22. greetingpage: Pcchar = '<html><body><h1>Welcome, %s!</center></h1></body></html>';
  23. errorpage: Pcchar = '<html><body>This doesn''t seem to be right.</body></html>';
  24. type
  25. Tconnection_info_struct = packed record
  26. connectiontype: cint;
  27. answerstring: Pcchar;
  28. postprocessor: PMHD_PostProcessor;
  29. end;
  30. Pconnection_info_struct = ^Tconnection_info_struct;
  31. function send_page(connection: PMHD_Connection; page: Pcchar): cint; cdecl;
  32. var
  33. ret: cint;
  34. response: PMHD_Response;
  35. begin
  36. response := MHD_create_response_from_buffer(Length(page),
  37. Pointer(page), MHD_RESPMEM_PERSISTENT);
  38. if not Assigned(response) then
  39. Exit(MHD_NO);
  40. ret := MHD_queue_response(connection, MHD_HTTP_OK, response);
  41. MHD_destroy_response(response);
  42. Result := ret;
  43. end;
  44. function iterate_post(coninfo_cls: Pointer; kind: MHD_ValueKind;
  45. key: Pcchar; filename: Pcchar; content_type: Pcchar; transfer_encoding: Pcchar;
  46. Data: Pcchar; off: cuint64; size: size_t): cint; cdecl;
  47. var
  48. con_info: Pconnection_info_struct;
  49. answerstring: Pcchar;
  50. begin
  51. con_info := coninfo_cls;
  52. if 0 = strcomp(key, 'name') then
  53. begin
  54. if (size > 0) and (size <= MAXNAMESIZE) then
  55. begin
  56. answerstring := Malloc(MAXANSWERSIZE);
  57. if not Assigned(answerstring) then
  58. Exit(MHD_NO);
  59. snprintf(answerstring, MAXANSWERSIZE, greetingpage, Data);
  60. con_info^.answerstring := answerstring;
  61. end
  62. else
  63. con_info^.answerstring := nil;
  64. Exit(MHD_NO);
  65. end;
  66. Result := MHD_YES;
  67. end;
  68. procedure request_completed(cls: Pointer; connection: PMHD_Connection;
  69. con_cls: PPointer; toe: MHD_RequestTerminationCode); cdecl;
  70. var
  71. con_info: Pconnection_info_struct;
  72. begin
  73. con_info := con_cls^;
  74. if nil = con_info then
  75. Exit;
  76. if con_info^.connectiontype = POST then
  77. begin
  78. MHD_destroy_post_processor(con_info^.postprocessor);
  79. if Assigned(con_info^.answerstring) then
  80. Free(con_info^.answerstring);
  81. end;
  82. Free(con_info);
  83. con_cls^ := nil;
  84. end;
  85. function answer_to_connection(cls: Pointer; connection: PMHD_Connection;
  86. url: Pcchar; method: Pcchar; version: Pcchar; upload_data: Pcchar;
  87. upload_data_size: Psize_t; con_cls: PPointer): cint; cdecl;
  88. var
  89. con_info: Pconnection_info_struct;
  90. begin
  91. if nil = con_cls^ then
  92. begin
  93. con_info := Malloc(SizeOf(Tconnection_info_struct));
  94. if nil = con_info then
  95. Exit(MHD_NO);
  96. con_info^.answerstring := nil;
  97. if 0 = strcomp(method, 'POST') then
  98. begin
  99. con_info^.postprocessor :=
  100. MHD_create_post_processor(connection, POSTBUFFERSIZE,
  101. @iterate_post, Pointer(con_info));
  102. if nil = con_info^.postprocessor then
  103. begin
  104. Free(con_info);
  105. Exit(MHD_NO);
  106. end;
  107. con_info^.connectiontype := POST;
  108. end
  109. else
  110. con_info^.connectiontype := GET;
  111. con_cls^ := Pointer(con_info);
  112. Exit(MHD_YES);
  113. end;
  114. if 0 = strcomp(method, 'GET') then
  115. Exit(send_page(connection, askpage));
  116. if 0 = strcomp(method, 'POST') then
  117. begin
  118. con_info := con_cls^;
  119. if upload_data_size^ <> 0 then
  120. begin
  121. MHD_post_process(con_info^.postprocessor, upload_data, upload_data_size^);
  122. upload_data_size^ := 0;
  123. Exit(MHD_YES);
  124. end
  125. else
  126. if nil <> con_info^.answerstring then
  127. Exit(send_page(connection, con_info^.answerstring));
  128. end;
  129. Result := send_page(connection, errorpage);
  130. end;
  131. var
  132. daemon: PMHD_Daemon;
  133. begin
  134. daemon := MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, PORT, nil, nil,
  135. @answer_to_connection, nil, MHD_OPTION_NOTIFY_COMPLETED, @request_completed,
  136. nil, MHD_OPTION_END);
  137. if nil = daemon then
  138. Halt(1);
  139. ReadLn;
  140. MHD_stop_daemon(daemon);
  141. end.