1 /***************************************************************************
2 https_server.cpp -- test file for an https server
3
4 copyright : (C) 2002-2007 by Ewald Arnold
5 email : ulxmlrpcpp@ewald-arnold.de
6
7 $Id: https_server.cpp 1062 2007-08-19 09:07:58Z ewald-arnold $
8
9 ***************************************************************************/
10
11 /**************************************************************************
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License as
15 * published by the Free Software Foundation; either version 2 of the License,
16 * or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 ***************************************************************************/
28
29 //#define ULXR_DEBUG_OUTPUT
30 //#define ULXR_SHOW_HTTP
31
32 #include <ulxmlrpcpp/ulxmlrpcpp.h> // always first header
33
34 #include <iostream>
35 #include <ctime>
36 #include <cstdio>
37 #include <cstring>
38
39 #include <ulxmlrpcpp/ulxr_ssl_connection.h>// first, don't move: msvc #include bug
40 #include <ulxmlrpcpp/ulxr_htmlform_handler.h>
41 #include <ulxmlrpcpp/ulxr_http_server.h>
42 #include <ulxmlrpcpp/ulxr_http_protocol.h>
43 #include <ulxmlrpcpp/ulxr_dispatcher.h>
44 #include <ulxmlrpcpp/ulxr_except.h>
45 #include <ulxmlrpcpp/ulxr_signature.h>
46
47 #ifndef ULXR_OMIT_REENTRANT_PROTECTOR
48 #include <ulxmlrpcpp/ulxr_mutex.h>
49 #endif
50
51 #ifdef __WIN32__
52 const unsigned num_threads = 10;
53 #else
54 const unsigned num_threads = 10;
55 #endif
56
57 ulxr::HttpServer *my_http_server;
58
59 ////////////////////////////////////////////////////////////////////////////////////
60 // C-style handler, do everything manually
61
62
handle_css_c()63 std::string handle_css_c()
64 {
65 return "H1 { text-align: center; color: blue; }\n"
66 "A { color: green; }\n";
67 }
68
69
get_head_c(const std::string & title)70 std::string get_head_c(const std::string &title)
71 {
72 return std::string("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"
73 "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=iso-8859-1\">"
74 "<title>")
75 + title
76 + std::string("</title>"
77 "<link href=\"ulxr_system.css\" rel=\"stylesheet\" type=\"text/css\">"
78 "</head><body>");
79 }
80
81
get_tail_c()82 std::string get_tail_c()
83 {
84 return "</body></html>";
85 }
86
87
handle_index_c()88 std::string handle_index_c()
89 {
90 ULXR_TRACE(ULXR_PCHAR("handle_index_c"));
91 std::string resp = get_head_c("Index") +
92 "<h1>Index</h1>"
93 "<p>This page contains information about the example http server"
94 " shipped with <a href=\"http://ulxmlrpcpp.sf.net\">ulxmlrpcpp</a>.</p>"
95 "<a href=\"general.html\">General System information<a><br />"
96 "<a href=\"special.html\">Special System information<a><br /><br />"
97 "<a href=\"/rpc-info/index.html\">Information about the built-in XML-RPC server<a><br />"
98 "<a href=\"/rpc-info/calc.html\">A simple calculator<a><br />"
99 "<a href=\"/rpc-info/elements.html\">Display all form elements<a>"
100 + get_tail_c();
101 return resp;
102 }
103
104
handle_special_c()105 std::string handle_special_c()
106 {
107 ULXR_TRACE(ULXR_PCHAR("handle_special_c"));
108 std::string resp = get_head_c("Special") +
109 "<h1>Special Information</h1>"
110 "<p>This page contains really special information.</p>"
111 "<a href=\"index.html\">Index<a><br />"
112 "<a href=\"general.html\">General System information<a>"
113 + get_tail_c();
114 return resp;
115 }
116
117
handle_general_c()118 std::string handle_general_c()
119 {
120 ULXR_TRACE(ULXR_PCHAR("handle_general_c"));
121
122 int ma;
123 int mi;
124 int pa;
125 bool deb;
126 ulxr::CppString info;
127 ulxr::getVersion (ma, mi, pa, deb, info);
128 char s_ma[40];
129 char s_mi[40];
130
131 ulxr_sprintf(s_ma, "%d", ma);
132 ulxr_sprintf(s_mi, "%d", mi);
133
134 #ifndef ULXR_OMIT_REENTRANT_PROTECTOR // todo: optionally replace with ctime_r
135 ulxr::Mutex::Locker lock(ulxr::ctimeMutex);
136 #endif
137
138 ulxr_time_t tt = ulxr_time(0);
139 std::string tm (ulxr_ctime(&tt));
140
141 std::string resp = get_head_c("General") +
142 "<h1>General Information</h1>"
143 "<p>This page contains very general information.</p>"
144 "<p>"
145 "Current time: " + tm + "<br />"
146 "Library version: " + s_ma + "." + s_mi + "<br />"
147 "</p>"
148 "<a href=\"index.html\">Index<a><br />"
149 "<a href=\"special.html\">Special System information<a>"
150 + get_tail_c();
151 return resp;
152 }
153
154
155 #ifdef ULXR_SHOW_TRACE
systemInfoHandler(ulxr::HttpProtocol * prot,const ulxr::CppString & method,const ulxr::CppString & resource,const ulxr::Cpp8BitString &)156 bool systemInfoHandler(ulxr::HttpProtocol *prot,
157 const ulxr::CppString &method,
158 const ulxr::CppString &resource,
159 const ulxr::Cpp8BitString &/*conn_data*/)
160 #else
161 bool systemInfoHandler(ulxr::HttpProtocol *prot,
162 const ulxr::CppString &/*method*/,
163 const ulxr::CppString &resource,
164 const ulxr::Cpp8BitString &/*conn_data*/)
165 #endif
166 {
167 ULXR_TRACE(ULXR_PCHAR("systemInfoHandler ") << method << " " << resource);
168
169 ulxr::CppString rsc_start = ULXR_PCHAR("/system/");
170 if (resource.substr(0, rsc_start.length()) == rsc_start)
171 {
172 ulxr::CppString target = resource.substr(rsc_start.length());
173 std::string resp;
174
175 if (target.length() == 0 || target == ULXR_PCHAR("index.html"))
176 resp = handle_index_c();
177
178 else if (target == ULXR_PCHAR("general.html"))
179 resp = handle_general_c();
180
181 else if (target == ULXR_PCHAR("special.html"))
182 resp = handle_special_c();
183
184 else if (target == ULXR_PCHAR("ulxr_system.css"))
185 resp = handle_css_c();
186
187 else
188 return false;
189
190 prot->sendResponseHeader(200, ULXR_PCHAR("OK"), ULXR_PCHAR("text/html"), resp.length());
191 prot->writeRaw(resp.data(), resp.length());
192
193 return true;
194 }
195 else
196 return false;
197 }
198
199 // C-style handler
200 ////////////////////////////////////////////////////////////////////////////////////
201
202
203 ////////////////////////////////////////////////////////////////////////////////////
204 // class-style handler, use helper class extensively
205
206 class RpcInfoHandler : public ulxr::HtmlFormHandler
207 {
208 public:
209
RpcInfoHandler(ulxr::Dispatcher * in_disp)210 RpcInfoHandler(ulxr::Dispatcher *in_disp)
211 : ulxr::HtmlFormHandler(ULXR_PCHAR("/rpc-info/"))
212 {
213 disp = in_disp;
214
215 addSubResource(ULXR_PCHAR(""), this, &RpcInfoHandler::handle_index, ULXR_PCHAR("The main index page in this subresource"));
216 addSubResource(ULXR_PCHAR("index.html"), this, &RpcInfoHandler::handle_index, ULXR_PCHAR("The main index page in this subresource"));
217 addSubResource(ULXR_PCHAR("calc.html"), this, &RpcInfoHandler::handle_calc, ULXR_PCHAR("A simple calculator"));
218 addSubResource(ULXR_PCHAR("elements.html"), this, &RpcInfoHandler::handle_elements, ULXR_PCHAR("A sample page with form elements"));
219
220 addSubResource(ULXR_PCHAR("subresources.html"), (ulxr::HtmlFormHandler*)this, &ulxr::HtmlFormHandler::handle_subresource_list, ULXR_PCHAR("Display subresources"));
221 // css already handled by parent
222 }
223
224
handle_css_file(const ulxr::HtmlFormData &,ulxr::CppString & mimetype)225 virtual ulxr::CppString handle_css_file(const ulxr::HtmlFormData &, ulxr::CppString &mimetype)
226 {
227 mimetype = ULXR_PCHAR("text/css");
228 return ULXR_PCHAR("H1 { text-align: center; color: red; }\n")
229 ULXR_PCHAR("A { color: gray; }\n");
230 }
231
232
handle_index(const ulxr::HtmlFormData & formdata,ulxr::CppString & mimetype)233 ulxr::CppString handle_index(const ulxr::HtmlFormData &formdata, ulxr::CppString &mimetype)
234 {
235 mimetype = ULXR_PCHAR("text/html");
236 if (formdata.size() != 0 && formdata.hasElement(ULXR_PCHAR("method_modifier"))) // first update rpc-server
237 for (unsigned i = 0; i < disp->numMethods(); ++i)
238 disp->getMethod(i)->setEnabled(formdata.hasElement(ULXR_PCHAR("method_enable_"), i) == true);
239
240 ULXR_TRACE(ULXR_PCHAR("handle_index"));
241 ulxr::CppString resp = getHeader(ULXR_PCHAR("Index"))
242 + ULXR_PCHAR("<h1>Index</h1>")
243 + makeAnchor(ULXR_PCHAR("subresources.html"), ULXR_PCHAR("Show all subresources of this branch"))
244 + makeLineBreak()
245 + ULXR_PCHAR("<p>The following table contains information about the available rpc methods.</p>\n");
246
247 resp += openForm(ULXR_PCHAR("rpc-controller"), ULXR_PCHAR("POST"));
248
249 resp += ULXR_PCHAR("<table border=\"3\">\n")
250 ULXR_PCHAR("<tr><td>Return type</td>")
251 ULXR_PCHAR("<td>Method name</td>")
252 ULXR_PCHAR("<td>Parameter signature</td>")
253 ULXR_PCHAR("<td>Type</td>")
254 ULXR_PCHAR("<td>Description</td>")
255 + applyTags(ULXR_PCHAR("Invoked"), ULXR_PCHAR("td"))
256 + applyTags(ULXR_PCHAR("Enabled"), ULXR_PCHAR("td"))
257 + makeSubmitButton(ULXR_PCHAR("method_modifier"), ULXR_PCHAR("Update"))
258 + ULXR_PCHAR("</td>");
259
260 ULXR_TRACE(ULXR_PCHAR("handle_index 1"));
261 for (unsigned i = 0; i < disp->numMethods(); ++i)
262 {
263 ulxr::CppString id = makeNumber(i);
264
265 const ulxr::Dispatcher::MethodCallDescriptor *meth = disp->getMethod(i);
266 resp += ULXR_PCHAR("<tr>");
267 resp += ULXR_PCHAR("<td>") + meth->getReturnValueSignature() + ULXR_PCHAR("</td>");
268 resp += ULXR_PCHAR("<td>") + meth->getMethodName() + ULXR_PCHAR("</td>");
269 resp += ULXR_PCHAR("<td>") + meth->getParameterSignature() + ULXR_PCHAR("</td>");
270
271 if (meth->getCallType() == ulxr::Dispatcher::CallSystem)
272 resp += ULXR_PCHAR("<td>system</td>");
273 else
274 resp += ULXR_PCHAR("<td>external</td>");
275
276 resp += ULXR_PCHAR("<td>") + meth->getDocumentation() + ULXR_PCHAR("</td>");
277
278 resp += ULXR_PCHAR("<td>") + makeNumber(meth->getInvoked()) + ULXR_PCHAR("</td>");
279
280 resp += ULXR_PCHAR("<td>")
281 + makeCheckBox(makeIdent(ULXR_PCHAR("method_enable_"), i), ULXR_PCHAR("on"), meth->isEnabled())
282 + ULXR_PCHAR("</td>");
283
284 resp += ULXR_PCHAR("</tr>\n");
285 }
286 resp += ULXR_PCHAR("</table>");
287 resp += closeForm();
288 resp += getTail();
289 return resp;
290 }
291
292
handle_calc(const ulxr::HtmlFormData & formdata,ulxr::CppString & mimetype)293 ulxr::CppString handle_calc(const ulxr::HtmlFormData &formdata, ulxr::CppString &mimetype)
294 {
295 mimetype = ULXR_PCHAR("text/html");
296 ulxr::CppString rhs;
297 ulxr::CppString lhs;
298 ulxr::CppString result;
299 ulxr::CppString op = ULXR_PCHAR("plus");
300
301 if ( formdata.size() != 0
302 && formdata.hasElement(ULXR_PCHAR("lhs"))
303 && formdata.hasElement(ULXR_PCHAR("rhs"))
304 && formdata.hasElement(ULXR_PCHAR("operator"))
305 )
306 {
307 int l = getLong(formdata.getElement(ULXR_PCHAR("lhs"))[0]);
308 int r = getLong(formdata.getElement(ULXR_PCHAR("rhs"))[0]);
309 int res;
310 op = formdata.getElement(ULXR_PCHAR("operator"))[0];
311 if (op == ULXR_PCHAR("plus"))
312 res = l + r;
313
314 else if (op == ULXR_PCHAR("minus"))
315 res = l - r;
316
317 else if (op == ULXR_PCHAR("mul"))
318 res = l * r;
319
320 else if (op == ULXR_PCHAR("div"))
321 {
322 if (r == 0)
323 res = 0;
324 else
325 res = l / r;
326 }
327 else
328 res = 0;
329
330 rhs = makeNumber(r);
331 lhs = makeNumber(l);
332 result = makeNumber(res);
333 }
334
335 ULXR_TRACE(ULXR_PCHAR("handle_calc"));
336 ulxr::CppString resp = getHeader(ULXR_PCHAR("Calculator"))
337 + ULXR_PCHAR("<h1>Calculator</h1>")
338 ULXR_PCHAR("<p>Enter two numbers and select an operator.</p>\n");
339
340 resp += openForm(ULXR_PCHAR("magic-calculator"), ULXR_PCHAR("POST"));
341
342 resp += makeTextField(ULXR_PCHAR("lhs"), lhs);
343
344 resp += openSelect(ULXR_PCHAR("operator"));
345 resp += makeOption(ULXR_PCHAR("+"), ULXR_PCHAR("plus"), op == ULXR_PCHAR("plus"));
346 resp += makeOption(ULXR_PCHAR("-"), ULXR_PCHAR("minus"), op == ULXR_PCHAR("minus"));
347 resp += makeOption(ULXR_PCHAR("*"), ULXR_PCHAR("mul"), op == ULXR_PCHAR("mul"));
348 resp += makeOption(ULXR_PCHAR("/"), ULXR_PCHAR("div"), op == ULXR_PCHAR("div"));
349 resp += closeSelect();
350
351 resp += makeTextField(ULXR_PCHAR("rhs"), rhs);
352
353 resp += ULXR_PCHAR(" = ");
354
355 resp += makeTextField(ULXR_PCHAR("result"), result);
356
357 resp += ULXR_PCHAR("<br /><br />");
358
359 resp += makeSubmitButton(ULXR_PCHAR("start_calc"), ULXR_PCHAR("Calculate"));
360 resp += closeForm();
361
362 resp += getTail();
363 return resp;
364 }
365
366
handle_elements(const ulxr::HtmlFormData & formdata,ulxr::CppString & mimetype)367 ulxr::CppString handle_elements(const ulxr::HtmlFormData &formdata, ulxr::CppString &mimetype)
368 {
369 mimetype = ULXR_PCHAR("text/html");
370 ULXR_TRACE(ULXR_PCHAR("handle_elements"));
371 ulxr::CppString resp = getHeader(ULXR_PCHAR("Available Form Elements"))
372 + ULXR_PCHAR("<h1>Available Form Elements</h1>");
373
374 resp += openForm(ULXR_PCHAR("testform"), ULXR_PCHAR("POST"))
375 + ULXR_PCHAR("Checkbox 1")
376 + makeCheckBox (ULXR_PCHAR("Check1"), ULXR_PCHAR("on"), true)
377 + makeLineBreak()
378
379 + ULXR_PCHAR("Checkbox 2")
380 + makeCheckBox (ULXR_PCHAR("Check2"), ULXR_PCHAR("on"), false)
381 + makeLineBreak()
382
383 + ULXR_PCHAR("<br /><br />")
384
385 + makeTextField(ULXR_PCHAR("Textfield"), ULXR_PCHAR("textdata"))
386 + makeLineBreak();
387
388 if (formdata.hasElement(ULXR_PCHAR("Textfield")))
389 {
390 resp += makeLineBreak()
391 + makeText(ULXR_PCHAR("Data from text field above:"))
392 + makeLineBreak()
393 + formdata.getElement(ULXR_PCHAR("Textfield"))[0]
394 + makeLineBreak()
395 + makeLineBreak();
396 }
397
398 resp += ULXR_PCHAR("<br /><br />")
399 + makeTextArea(ULXR_PCHAR("TextArea"), ULXR_PCHAR("text +&%= line1\nline 2\nline 3"), 40, 5)
400 + makeLineBreak();
401
402 if (formdata.hasElement(ULXR_PCHAR("TextArea")))
403 {
404 resp += makeLineBreak()
405 + makeText(ULXR_PCHAR("Data from text area above:"))
406 + makeLineBreak()
407 + formdata.getElement(ULXR_PCHAR("TextArea"))[0]
408 + makeLineBreak()
409 + makeLineBreak();
410 }
411
412 resp += ULXR_PCHAR("<br /><br />")
413
414 + openSelect(ULXR_PCHAR("Select1"), 5, true)
415 + makeOption(ULXR_PCHAR("Option 1"))
416 + makeOption(ULXR_PCHAR("Option 2"), ULXR_PCHAR("opt2"))
417 + makeOption(ULXR_PCHAR("Option 3"), ULXR_PCHAR(""), true)
418 + makeOption(ULXR_PCHAR("Option 4"), ULXR_PCHAR(""), true)
419 + closeSelect()
420
421 + makeLineBreak()
422
423 + openSelect(ULXR_PCHAR("Select2"), 1, false)
424 + makeOption(ULXR_PCHAR("Option 21"))
425 + makeOption(ULXR_PCHAR("Option 22"), ULXR_PCHAR("opt2"))
426 + makeOption(ULXR_PCHAR("Option 23"), ULXR_PCHAR(""), true)
427 + makeOption(ULXR_PCHAR("Option 24"), ULXR_PCHAR(""), true)
428 + closeSelect()
429
430 + ULXR_PCHAR("<br /><br />")
431
432 + makeRadioButton(ULXR_PCHAR("radio1"), ULXR_PCHAR("val1")) + ULXR_PCHAR("Radio 1a") + makeLineBreak()
433 + makeRadioButton(ULXR_PCHAR("radio1"), ULXR_PCHAR("val2"), true) + ULXR_PCHAR("Radio 1b") + makeLineBreak()
434 + makeRadioButton(ULXR_PCHAR("radio2"), ULXR_PCHAR("val3"), true) + ULXR_PCHAR("Radio 3") + makeLineBreak()
435
436 + makeLineBreak()
437
438 + makeSubmitButton(ULXR_PCHAR("submit"), ULXR_PCHAR("Do Submit"))
439 + makeResetButton(ULXR_PCHAR("reset"), ULXR_PCHAR("Do Reset"))
440
441 + closeForm()
442
443 + getTail();
444
445 return resp;
446 }
447
448
449 private:
450 ulxr::Dispatcher *disp;
451 };
452
453 // class-style handler
454 ////////////////////////////////////////////////////////////////////////////////////
455
456
testcall(const ulxr::MethodCall & calldata)457 ulxr::MethodResponse testcall (const ulxr::MethodCall &calldata)
458 {
459 ulxr::Integer i = calldata.getParam(0);
460 ulxr::Integer i2 = calldata.getParam(1);
461
462 ulxr::Struct st;
463 st.addMember(ULXR_PCHAR("before"), i);
464 st.addMember(ULXR_PCHAR("sum"), ulxr::Integer(i.getInteger()+i2.getInteger()));
465 st.addMember(ULXR_PCHAR("difference"), ulxr::Integer(i.getInteger()-i2.getInteger()));
466
467 return ulxr::MethodResponse (st);
468 }
469
470
numThreads(const ulxr::MethodCall &)471 ulxr::MethodResponse numThreads (const ulxr::MethodCall &/*calldata*/)
472 {
473 #ifdef ULXR_MULTITHREADED
474 return ulxr::MethodResponse(ulxr::Integer(my_http_server->numThreads()));
475 #else
476 return ulxr::MethodResponse(ulxr::Integer(1));
477 #endif
478 }
479
480
shutdown(const ulxr::MethodCall &)481 ulxr::MethodResponse shutdown (const ulxr::MethodCall &/*calldata*/)
482 {
483 ULXR_COUT << ULXR_PCHAR("got signal to shut down\n");
484 my_http_server->requestTermination();
485 return ulxr::MethodResponse(ulxr::Boolean(true));
486 }
487
488
main(int argc,char ** argv)489 int main(int argc, char **argv)
490 {
491 int ret = 0;
492
493 #ifndef ULXR_OMIT_TCP_STUFF
494 #ifdef ULXR_INCLUDE_SSL_STUFF
495
496 try
497 {
498 ulxr::intializeLog4J(argv[0]);
499
500 ulxr::CppString host = ULXR_PCHAR("localhost");
501 if (argc > 1)
502 host = ULXR_GET_STRING(argv[1]);
503
504 unsigned port = 32006;
505 if (argc > 2)
506 port = ulxr_atoi(argv[2]);
507
508 bool auth = true;
509 if (argc > 3)
510 auth = (bool) ulxr_atoi(argv[3]);
511
512 bool wbxml = false;
513 if (argc > 4)
514 wbxml = ulxr_atoi(argv[4]) != 0;
515
516 ulxr::SSLConnection conn (true, host, port); // SSL
517 conn.setConnectionTimeout(conn.getTimeout(), 60 * 60);
518 conn.setCryptographyData("password", "foo-cert.pem", "foo-cert.pem");
519 ulxr::HttpProtocol prot(&conn);
520 ulxr::HttpServer http_server (&prot, num_threads, wbxml);
521 my_http_server = &http_server;
522 http_server.addHttpHandler(ULXR_PCHAR("get"), ulxr::make_methodhandler(&systemInfoHandler));
523
524 ulxr::Dispatcher rpc_server(0, wbxml);
525
526 RpcInfoHandler rpcinfo(&rpc_server);
527 http_server.addHttpHandler(ULXR_PCHAR("get"), ulxr::make_methodhandler(rpcinfo, &RpcInfoHandler::handler));
528 http_server.addHttpHandler(ULXR_PCHAR("post"), ulxr::make_methodhandler(rpcinfo, &RpcInfoHandler::handler));
529
530 if (auth)
531 {
532 http_server.addRealm(ULXR_CHAR("/"), ULXR_CHAR("http-root-resource"));
533 http_server.addAuthentication(ULXR_CHAR("ali-baba"),
534 ULXR_CHAR("open-sesame"),
535 ULXR_CHAR("http-root-resource"));
536
537 http_server.addRealm(ULXR_CHAR("/RPC2"), ULXR_CHAR("rpc2-resource"));
538 http_server.addAuthentication(ULXR_CHAR("ali-baba-rpc"),
539 ULXR_CHAR("open-sesame-rpc"),
540 ULXR_CHAR("rpc2-resource"));
541 }
542
543 ulxr::CppString xs = conn.getErrorString(10035);
544
545 #ifdef _WIN32
546 ulxr::CppString root_dir = ULXR_PCHAR("x:\\public_html");
547 #else
548 std::string home = getenv("HOME");
549 ulxr::CppString root_dir = ULXR_GET_STRING(home)+ULXR_PCHAR("/public_html");
550 #endif
551 ULXR_COUT << ULXR_PCHAR("Server root directory is: ") << root_dir << std::endl;
552 ULXR_COUT << ULXR_PCHAR("Accepting https request at ") << host << ULXR_PCHAR(":") << port << std::endl;
553 ULXR_COUT << ULXR_PCHAR("Please point your browser to \n https://")
554 << host << ULXR_PCHAR(":") << port << ULXR_PCHAR("/system/")
555 << ULXR_PCHAR("\nor to \n https://")
556 << host << ULXR_PCHAR(":") << port << ULXR_PCHAR("/rpc-info/")<< std::endl
557 << ULXR_PCHAR("username is \"ali-baba\" and password is \"open-sesame\"") << std::endl;
558 ULXR_COUT << ULXR_PCHAR("WBXML: ") << wbxml << std::endl;
559
560 http_server.setHttpRoot(root_dir);
561
562 rpc_server.addMethod(&testcall,
563 ulxr::Struct::getValueName(),
564 ULXR_CHAR("testcall"),
565 ulxr::Integer::getValueName() + ULXR_CHAR(",") + ulxr::Integer::getValueName(),
566 ULXR_CHAR("Testcase with a c-function"));
567
568 rpc_server.addMethod(ulxr::make_method(&shutdown),
569 ulxr::Signature(),
570 ULXR_PCHAR("shutdown"),
571 ulxr::Signature(),
572 ULXR_PCHAR("Shut down Worker"));
573
574 rpc_server.addMethod(ulxr::make_method(&numThreads),
575 ulxr::Signature(ulxr::Integer()),
576 ULXR_PCHAR("numthreads"),
577 ulxr::Signature(),
578 ULXR_PCHAR("Returns number of installed threads at startup"));
579
580 http_server.setRpcDispatcher(&rpc_server);
581
582 // run forever...
583 unsigned started = http_server.runPicoHttpd();
584 ULXR_COUT << ULXR_PCHAR("Started ") << started << ULXR_PCHAR(" threads for dispatching http and rpc requests\n");
585 if (started > 1)
586 http_server.waitAsync(false, true);
587 ULXR_COUT << ULXR_PCHAR("Done.\n");
588 }
589
590 catch(ulxr::Exception &ex)
591 {
592 ULXR_COUT << ULXR_CHAR("Error occured: ") << ex.why() << std::endl;
593 ret = 1;
594 }
595
596 catch(...)
597 {
598 ULXR_COUT << ULXR_CHAR("unknown Error occured.\n");
599 ret = 1;
600 }
601
602 if (!ret)
603 ULXR_COUT << ULXR_CHAR("Ready and ok.\n");
604 else
605 ULXR_COUT << ULXR_CHAR("Ready but not ok.\n");
606
607 #endif // ULXR_OMIT_TCP_STUFF
608 #endif // ULXR_INCLUDE_SSL_STUFF
609
610 return ret;
611 }
612
613
614