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