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