Commit e4daceb67519db3444a30cb761a3e2722bbacaa2

Authored by Jürgen Knödlseder
1 parent b21f1d1d

Now the GVOHub is fully fonctional with TOPCAT and Alladin.

include/GVOHub.hpp
... ... @@ -94,6 +94,7 @@ protected:
94 94 void request_shutdown(const socklen_t& sock);
95 95 std::string get_client_key(const GXml& xml) const;
96 96 int get_client_index(const GXml& xml) const;
  97 + int get_client_index(const std::string& reference) const;
97 98 std::string get_response_value(const GXml& xml,
98 99 const std::string& name) const;
99 100 void get_name_value_pair(const GXmlNode* node,
... ... @@ -108,6 +109,7 @@ protected:
108 109 // Low-level methods
109 110 void create_samp_file(void) const;
110 111 void post_samp_ok(const socklen_t& sock) const;
  112 + void post_samp_void(const socklen_t& sock) const;
111 113 void post_string(const std::string& content, const socklen_t& sock) const;
112 114 void notify(const std::string& url, const std::string& notification) const;
113 115 std::string random_string(const size_t& length) const;
... ...
src/vo/GVOClient.cpp
... ... @@ -913,7 +913,7 @@ void GVOClient::post_string(const std::string& content) const
913 913 // Send content to socket
914 914 bool done = false;
915 915 do {
916   - int length = post.length() + 1; // +1 for terminating 0
  916 + int length = post.length();
917 917 int sent_length = send(m_socket, post.c_str(), length, 0);
918 918 if (sent_length < length) {
919 919 post = post.substr(sent_length, std::string::npos);
... ...
src/vo/GVOHub.cpp
... ... @@ -42,24 +42,19 @@
42 42 #include <sys/wait.h> // waitpid() function
43 43 #include <arpa/inet.h> // inet_addr() function
44 44 #include "GVOHub.hpp"
45   -#include "GVOClient.hpp"
46 45 #include "GException.hpp"
47 46 #include "GTools.hpp"
48 47  
49 48 /* __ Method name definitions ____________________________________________ */
50   -#define G_INIT_MEMBERS "GVOHub::init_members()"
51 49 #define G_START_HUB "GVOHub::start_hub()"
52   -#define G_HANDLE_REQUEST "GVOHub::handle_request(socklen_t&)"
53   -#define G_REGISTER_SERVICE "GVOHub::register_service(GXml&, socklen_t&)"
54 50  
55 51 /* __ Macros _____________________________________________________________ */
56 52  
57 53 /* __ Coding definitions _________________________________________________ */
58   -#define G_KEY 12345
59   -//#define G_USE_FORK
60 54  
61 55 /* __ Debug definitions __________________________________________________ */
62   -#define G_CONSOLE_DUMP
  56 +//#define G_CONSOLE_DUMP
  57 +#define G_SHOW_MESSAGE
63 58  
64 59  
65 60 /*==========================================================================
... ... @@ -249,8 +244,8 @@ void GVOHub::init_members(void)
249 244 m_version = "1.3";
250 245 m_hub_id = "gammalib_hub";
251 246 m_socket = -1; // Signals no socket
252   - m_clients.clear();
253 247 m_shutdown = false;
  248 + m_clients.clear();
254 249  
255 250 // Return
256 251 return;
... ... @@ -273,8 +268,8 @@ void GVOHub::copy_members(const GVOHub&amp; hub)
273 268 m_version = hub.m_version;
274 269 m_hub_id = hub.m_hub_id;
275 270 m_socket = hub.m_socket;
276   - m_clients = hub.m_clients;
277 271 m_shutdown = hub.m_shutdown;
  272 + m_clients = hub.m_clients;
278 273  
279 274 // Return
280 275 return;
... ... @@ -372,47 +367,6 @@ void GVOHub::start_hub(void)
372 367 throw GException::runtime_error(G_START_HUB, msg);
373 368 }
374 369  
375   - #if defined(G_USE_FORK)
376   - // Create child process to handle the request
377   - int pid = fork();
378   - if (pid < 0) {
379   - std::string msg = "No child process created.";
380   - throw GException::runtime_error(G_START_HUB, msg);
381   - }
382   -
383   - // If we have a PID of 0 we are in the child process. In this case
384   - // we have to handle the incoming requests ...
385   - if (pid == 0) {
386   -
387   - // Handle request
388   - handle_request(socket);
389   -
390   - // Exit child process
391   - exit(0);
392   - }
393   -
394   - // ... otherwise we are in the parent process.
395   - else {
396   -
397   - // Wait for the child process to terminate
398   - int status = 0;
399   - waitpid(pid, &status, 0);
400   -
401   - // Close socket
402   - close(socket);
403   -
404   - // Send SIG_IGN to the child process so that the kernel can
405   - // close it without sending it to zombie state <defunct>
406   - std::signal(pid, SIG_IGN);
407   -
408   - // If we have received a shutdown request then exit the event
409   - // loop
410   - if (o_clients->registered == -1) {
411   - break;
412   - }
413   -
414   - }
415   - #else
416 370 // Handle request
417 371 handle_request(socket);
418 372  
... ... @@ -424,7 +378,6 @@ void GVOHub::start_hub(void)
424 378 if (m_shutdown) {
425 379 break;
426 380 }
427   - #endif
428 381  
429 382 } // endwhile: main event loop
430 383  
... ... @@ -452,8 +405,8 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
452 405 // Initialize buffer
453 406 char buffer[1001];
454 407  
455   - // Initialise response
456   - std::string response = "";
  408 + // Initialise message
  409 + std::string message = "";
457 410  
458 411 // Read from socket until nothing is received anymore.
459 412 int timeout = 2000; // Initial timeout is 2 sec
... ... @@ -462,22 +415,24 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
462 415 n = gammalib::recv(sock, buffer, 1000, 0, timeout);
463 416 if (n > 0) {
464 417 buffer[n] = '\0';
465   - response.append(std::string(buffer));
  418 + message.append(std::string(buffer));
466 419 }
467 420 timeout = 10; // The timeout now is 0.01 sec
468 421 } while (n > 0);
469 422  
470 423 // Dump the buffer
471   - #if defined(G_CONSOLE_DUMP)
472   - std::cout << "Hub has received the following message:" << std::endl;
473   - std::cout << response << std::endl;
  424 + #if defined(G_SHOW_MESSAGE)
  425 + std::cout << std::endl;
  426 + std::cout << "GVOHub has received the following message:" << std::endl;
  427 + std::cout << "==========================================" << std::endl;
  428 + std::cout << message << std::endl;
474 429 #endif
475 430  
476 431 // Extract response into an XML object
477 432 GXml xml;
478   - size_t start = response.find("<?xml");
  433 + size_t start = message.find("<?xml");
479 434 if (start != std::string::npos) {
480   - xml = GXml(response.substr(start, std::string::npos));
  435 + xml = GXml(message.substr(start, std::string::npos));
481 436 }
482 437  
483 438 // Get methodName value
... ... @@ -567,21 +522,8 @@ void GVOHub::request_ping(const socklen_t&amp; sock)
567 522 std::cout << "GVOHub::request_ping" << std::endl;
568 523 #endif
569 524  
570   - // Declare response
571   - std::string response = "";
572   -
573   - // Set response
574   - response.append("<?xml version='1.0' encoding='UTF-8'?>\n");
575   - response.append("<methodResponse>\n");
576   - response.append(" <params>\n");
577   - response.append(" <param>\n");
578   - response.append(" <value/>\n");
579   - response.append(" </param>\n");
580   - response.append(" </params>\n");
581   - response.append("</methodResponse>\n");
582   -
583   - // Post response
584   - post_string(response, sock);
  525 + // Post void message
  526 + post_samp_void(sock);
585 527  
586 528 // Return
587 529 return;
... ... @@ -610,46 +552,41 @@ void GVOHub::request_register(const GXml&amp; xml, const socklen_t&amp; sock)
610 552  
611 553 // Attached client
612 554 m_clients.push_back(voclient);
613   - /*
614   - for (int i = 0; i < m_clients.size(); ++i) {
615   - std::cout << "Client i " << m_clients[i].reference << " key=" << m_clients[i].private_key << std::endl;
616   - }
617   - */
618 555  
619 556 // Declare response
620   - std::string msg = "";
  557 + std::string response = "";
621 558  
622 559 // Set response
623   - msg.append("<?xml version='1.0' encoding='UTF-8'?>\n");
624   - msg.append("<methodResponse>\n");
625   - msg.append("<params>\n");
626   - msg.append(" <param><value><struct>\n");
627   - msg.append(" <member>\n");
628   - msg.append(" <name>samp.private-key</name>\n");
629   - msg.append(" <value>"+voclient.private_key+"</value>\n");
630   - msg.append(" </member>\n");
631   - msg.append(" <member>\n");
632   - msg.append(" <name>samp.hub-id</name>\n");
633   - msg.append(" <value>"+m_hub_id+"</value>\n");
634   - msg.append(" </member>\n");
635   - msg.append(" <member>\n");
636   - msg.append(" <name>samp.self-id</name>\n");
637   - msg.append(" <value>"+voclient.reference+"</value>\n");
638   - msg.append(" </member>\n");
639   - msg.append(" <member>\n");
640   - msg.append(" <name>samp.status</name>\n");
641   - msg.append(" <value>samp.ok</value>\n");
642   - msg.append(" </member>\n");
643   - msg.append(" <member>\n");
644   - msg.append(" <name>samp.url-translator</name>\n");
645   - msg.append(" <value>"+m_hub_url+"</value>\n");
646   - msg.append(" </member>\n");
647   - msg.append(" </struct></value></param>\n");
648   - msg.append("</params>\n");
649   - msg.append("</methodResponse>\n");
  560 + response.append("<?xml version='1.0' encoding='UTF-8'?>\n");
  561 + response.append("<methodResponse>\n");
  562 + response.append("<params>\n");
  563 + response.append(" <param><value><struct>\n");
  564 + response.append(" <member>\n");
  565 + response.append(" <name>samp.private-key</name>\n");
  566 + response.append(" <value>"+voclient.private_key+"</value>\n");
  567 + response.append(" </member>\n");
  568 + response.append(" <member>\n");
  569 + response.append(" <name>samp.hub-id</name>\n");
  570 + response.append(" <value>"+m_hub_id+"</value>\n");
  571 + response.append(" </member>\n");
  572 + response.append(" <member>\n");
  573 + response.append(" <name>samp.self-id</name>\n");
  574 + response.append(" <value>"+voclient.reference+"</value>\n");
  575 + response.append(" </member>\n");
  576 + response.append(" <member>\n");
  577 + response.append(" <name>samp.status</name>\n");
  578 + response.append(" <value>samp.ok</value>\n");
  579 + response.append(" </member>\n");
  580 + response.append(" <member>\n");
  581 + response.append(" <name>samp.url-translator</name>\n");
  582 + response.append(" <value>"+m_hub_url+"</value>\n");
  583 + response.append(" </member>\n");
  584 + response.append(" </struct></value></param>\n");
  585 + response.append("</params>\n");
  586 + response.append("</methodResponse>\n");
650 587  
651 588 // Post response
652   - post_string(msg, sock);
  589 + post_string(response, sock);
653 590  
654 591 // Send notifications
655 592 send_notifications("samp.hub.event.register", voclient.reference);
... ... @@ -680,19 +617,8 @@ void GVOHub::request_unregister(const GXml&amp; xml, const socklen_t&amp; sock)
680 617 // Continue only if index is valid
681 618 if (i != -1) {
682 619  
683   - // Declare message
684   - std::string msg = "";
685   -
686   - // Set response
687   - msg.append("<?xml version=\"1.0\"?>\n");
688   - msg.append("<methodResponse>\n");
689   - msg.append("<params>\n");
690   - msg.append(" <param><value/></param>\n");
691   - msg.append("</params>\n");
692   - msg.append("</methodResponse>\n");
693   -
694   - // Post response
695   - post_string(msg, sock);
  620 + // Post void message
  621 + post_samp_void(sock);
696 622  
697 623 // Send notifications
698 624 send_notifications("samp.hub.event.unregister",
... ... @@ -746,18 +672,8 @@ void GVOHub::request_declare_metadata(const GXml&amp; xml, const socklen_t&amp; sock)
746 672 m_clients[i].author_name = get_response_value(xml, "author.name");
747 673 m_clients[i].homepage = get_response_value(xml, "home.page");
748 674  
749   - // Declare message
750   - std::string msg = "";
751   -
752   - // The hub response to Metadata declaration has no useful
753   - // content and can be discarded by the client.
754   - msg.append("<?xml version=\"1.0\"?>\n");
755   - msg.append("<methodResponse>\n");
756   - msg.append("<params><param><value/></param></params>\n");
757   - msg.append("</methodResponse>\n");
758   -
759   - // Post response
760   - post_string(msg,sock);
  675 + // Post void message
  676 + post_samp_void(sock);
761 677  
762 678 // Send notifications
763 679 send_notifications("samp.hub.event.metadata", m_clients[i].reference);
... ... @@ -882,47 +798,69 @@ void GVOHub::request_get_subscriptions(const GXml&amp; xml, const socklen_t&amp; sock)
882 798 std::cout << "GVOHub::request_get_subscriptions" << std::endl;
883 799 #endif
884 800  
885   - // Get client index
886   - int i = get_client_index(xml);
  801 + // Initialise client name
  802 + std::string client_name = "";
887 803  
888   - // Continue only if index is valid
889   - if (i != -1) {
890   -
891   - // Declare message
892   - std::string msg = "";
893   -
894   - // Set response
895   - msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
896   - msg.append("<methodResponse>\n");
897   - msg.append("<params>\n");
898   - msg.append(" <param><value><struct>\n");
899   -
900   - // Append all subscriptions
901   - for (int k = 0; k < m_clients[i].subscriptions.size(); ++k) {
902   - msg.append(" <member>\n");
903   - msg.append(" <name>");
904   - msg.append(m_clients[i].subscriptions[k]);
905   - msg.append("</name>\n");
906   - msg.append(" <value></value>\n)");
907   - msg.append(" </member>\n");
  804 + // Get the client name
  805 + const GXmlNode* node = xml.element("methodCall > params > param[1] > value");
  806 + if (node != NULL) {
  807 + const GXmlText* text = static_cast<const GXmlText*>((*node)[0]);
  808 + if (text != NULL) {
  809 + client_name = text->text();
908 810 }
  811 + }
909 812  
910   - // Finish response
911   - msg.append(" </struct></value></param>\n");
912   - msg.append("</params>\n");
913   - msg.append("</methodResponse>\n");
914   -
915   - // Post response
916   - post_string(msg, sock);
  813 + // Declare response
  814 + std::string response = "";
917 815  
918   - } // endif: client index was valid
  816 + // Set response
  817 + response.append("<?xml version='1.0' encoding='UTF-8'?>\n");
  818 + response.append("<methodResponse>\n");
  819 + response.append("<params>\n");
  820 + response.append(" <param><value><struct>\n");
919 821  
920   - // Signal if the client was unknown
921   - #if defined(G_CONSOLE_DUMP)
  822 + // If key is "gammalib_hub" then return some special information
  823 + if (client_name == "gammalib_hub") {
  824 + // Do nothing
  825 + }
  826 +
  827 + // ... handle all other clients
922 828 else {
923   - std::cout << " *** ERROR: Unable to find client " << get_client_key(xml) << std::endl;
  829 +
  830 + // Get client index
  831 + int i = get_client_index(client_name);
  832 +
  833 + // Continue only if index is valid
  834 + if (i != -1) {
  835 +
  836 + // Append all subscriptions
  837 + for (int k = 0; k < m_clients[i].subscriptions.size(); ++k) {
  838 + response.append(" <member>\n");
  839 + response.append(" <name>");
  840 + response.append(m_clients[i].subscriptions[k]);
  841 + response.append("</name>\n");
  842 + response.append(" <value></value>\n");
  843 + response.append(" </member>\n");
  844 + }
  845 +
  846 + }
  847 +
  848 + // Signal if the client was unknown
  849 + #if defined(G_CONSOLE_DUMP)
  850 + else {
  851 + std::cout << " *** ERROR: Unable to find client " << get_client_key(xml) << std::endl;
  852 + }
  853 + #endif
  854 +
924 855 }
925   - #endif
  856 +
  857 + // Finish response
  858 + response.append(" </struct></value></param>\n");
  859 + response.append("</params>\n");
  860 + response.append("</methodResponse>\n");
  861 +
  862 + // Post response
  863 + post_string(response, sock);
926 864  
927 865 // Return
928 866 return;
... ... @@ -1016,19 +954,8 @@ void GVOHub::request_get_subscribed_clients(const GXml&amp; xml, const socklen_t&amp; so
1016 954 fclose(fptr);
1017 955 */
1018 956  
1019   - // Declare message
1020   - std::string msg = "";
1021   -
1022   - // Set response
1023   - msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1024   - msg.append("<methodResponse>\n");
1025   - msg.append("<params>\n");
1026   - msg.append(" <param><value/></param>\n");
1027   - msg.append("</params>\n");
1028   - msg.append("</methodResponse>\n");
1029   -
1030   - // Post message
1031   - post_string(msg, sock);
  957 + // Post void message
  958 + post_samp_void(sock);
1032 959  
1033 960 // Return
1034 961 return;
... ... @@ -1043,87 +970,128 @@ void GVOHub::request_get_subscribed_clients(const GXml&amp; xml, const socklen_t&amp; so
1043 970 *
1044 971 * Handles all metadata requests.
1045 972 ***************************************************************************/
1046   -void GVOHub::request_get_metadata(const GXml& xml,const socklen_t& sock)
  973 +void GVOHub::request_get_metadata(const GXml& xml, const socklen_t& sock)
1047 974 {
1048 975 // Header
1049 976 #if defined(G_CONSOLE_DUMP)
1050 977 std::cout << "GVOHub::request_get_metadata" << std::endl;
1051 978 #endif
1052 979  
1053   - // Get client key
1054   - std::string key = get_client_key(xml);
  980 + // Initialise client name
  981 + std::string client_name = "";
1055 982  
1056   - // Declare message
1057   - std::string msg = "";
  983 + // Get the client name
  984 + const GXmlNode* node = xml.element("methodCall > params > param[1] > value");
  985 + if (node != NULL) {
  986 + const GXmlText* text = static_cast<const GXmlText*>((*node)[0]);
  987 + if (text != NULL) {
  988 + client_name = text->text();
  989 + }
  990 + }
  991 +
  992 + // Declare response
  993 + std::string response = "";
1058 994  
1059 995 // Set response
1060   - msg.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1061   - msg.append("<methodResponse>\n");
1062   - msg.append("<params>\n");
1063   - msg.append(" <param><value><struct>\n");
1064   - msg.append(" <member>\n");
1065   - msg.append(" <name>samp.status</name>\n");
1066   - msg.append(" <value>samp.ok</value>\n");
1067   - msg.append(" </member>\n");
  996 + response.append("<?xml version='1.0' encoding='UTF-8'?>\n");
  997 + response.append("<methodResponse>\n");
  998 + response.append("<params>\n");
  999 + response.append(" <param><value><struct>\n");
  1000 + response.append(" <member>\n");
  1001 + response.append(" <name>samp.status</name>\n");
  1002 + response.append(" <value>samp.ok</value>\n");
  1003 + response.append(" </member>\n");
1068 1004  
1069 1005 // If key is "gammalib_hub" then return some special information
1070   - if (key == "gammalib_hub") {
1071   - msg.append(" <member><name>samp.name</name><value>gammalib_hub</value></member>\n");
1072   - msg.append(" <member><name>samp.description.text</name><value>GammaLib VO Hub</value></member>\n");
1073   - msg.append(" <member><name>samp.icon.url</name><value></value></member>\n");
1074   - msg.append(" <member><name>samp.documentation.url</name><value>gammalib github documentation</value></member>\n");
1075   - msg.append(" <member><name>author.affiliation</name><value>IRAP, CNRS Toulouse</value></member>\n");
1076   - msg.append(" <member><name>author.email</name><value>dontcontactme@please</value></member>\n");
1077   - msg.append(" <member><name>author.name</name><value>J. Knoedlseder, T. Louge</value></member>\n");
1078   - msg.append(" <member><name>home.page</name><value>no dedicated page</value></member>\n");
  1006 + if (client_name == "gammalib_hub") {
  1007 + response.append(" <member>\n");
  1008 + response.append(" <name>samp.name</name>\n");
  1009 + response.append(" <value>gammalib_hub</value>\n");
  1010 + response.append(" </member>\n");
  1011 + response.append(" <member>\n");
  1012 + response.append(" <name>samp.description.text</name>\n");
  1013 + response.append(" <value>GammaLib VO Hub</value>\n");
  1014 + response.append(" </member>\n");
  1015 + response.append(" <member>\n");
  1016 + response.append(" <name>samp.icon.url</name>\n");
  1017 + response.append(" <value>http://a.fsdn.com/allura/p/gammalib/icon</value>\n");
  1018 + response.append(" </member>\n");
  1019 + response.append(" <member>\n");
  1020 + response.append(" <name>samp.documentation.url</name>\n");
  1021 + response.append(" <value>http://cta.irap.omp.eu/gammalib/user_manual/modules/vo.html</value>\n");
  1022 + response.append(" </member>\n");
  1023 + response.append(" <member>\n");
  1024 + response.append(" <name>author.affiliation</name>\n");
  1025 + response.append(" <value>IRAP, Toulouse, France</value>\n");
  1026 + response.append(" </member>\n");
  1027 + response.append(" <member>\n");
  1028 + response.append(" <name>author.email</name>\n");
  1029 + response.append(" <value>jurgen.knodlseder@irap.omp.eu</value>\n");
  1030 + response.append(" </member>\n");
  1031 + response.append(" <member>\n");
  1032 + response.append(" <name>author.name</name>\n");
  1033 + response.append(" <value>J. Knoedlseder, T. Louge</value>\n");
  1034 + response.append(" </member>\n");
  1035 + response.append(" <member>\n");
  1036 + response.append(" <name>home.page</name>\n");
  1037 + response.append(" <value>http://cta.irap.omp.eu/gammalib/</value>\n");
  1038 + response.append(" </member>\n");
1079 1039 }
1080 1040  
1081 1041 // ... otherwise get the index
1082 1042 else {
1083 1043  
1084 1044 // Get client index
1085   - int i = get_client_index(xml);
  1045 + int i = get_client_index(client_name);
1086 1046  
1087 1047 // Continue only if index is valid
1088 1048 if (i != -1) {
1089 1049  
1090 1050 // Append response
1091   - msg.append(" <member><name>samp.name</name><value>");
1092   - msg.append(m_clients[i].name);
1093   - msg.append("</value></member>\n");
1094   - msg.append(" <member><name>samp.description.text</name><value>");
1095   - msg.append(m_clients[i].description);
1096   - msg.append("</value></member>\n");
1097   - msg.append(" <member><name>samp.icon.url</name><value>");
1098   - msg.append(m_clients[i].icon);
1099   - msg.append("</value></member>\n");
1100   - msg.append(" <member><name>samp.documentation.url</name><value>");
1101   - msg.append(m_clients[i].documentation);
1102   - msg.append("</value></member>\n");
1103   - msg.append(" <member><name>author.affiliation</name><value>");
1104   - msg.append(m_clients[i].affiliation);
1105   - msg.append("</value></member>\n");
1106   - msg.append(" <member><name>author.email</name><value>");
1107   - msg.append(m_clients[i].email);
1108   - msg.append("</value></member>\n");
1109   - msg.append(" <member><name>author.name</name><value>");
1110   - msg.append(m_clients[i].author_name);
1111   - msg.append("</value></member>\n");
1112   - msg.append(" <member><name>home.page</name><value>");
1113   - msg.append(m_clients[i].homepage);
1114   - msg.append("</value></member>\n");
  1051 + response.append(" <member>\n");
  1052 + response.append(" <name>samp.name</name>\n");
  1053 + response.append(" <value>"+m_clients[i].name+"</value>\n");
  1054 + response.append(" </member>\n");
  1055 + response.append(" <member>\n");
  1056 + response.append(" <name>samp.description.text</name>\n");
  1057 + response.append(" <value>"+m_clients[i].description+"</value>\n");
  1058 + response.append(" </member>\n");
  1059 + response.append(" <member>\n");
  1060 + response.append(" <name>samp.icon.url</name>\n");
  1061 + response.append(" <value>"+m_clients[i].icon+"</value>\n");
  1062 + response.append(" </member>\n");
  1063 + response.append(" <member>\n");
  1064 + response.append(" <name>samp.documentation.url</name>\n");
  1065 + response.append(" <value>"+m_clients[i].documentation+"</value>\n");
  1066 + response.append(" </member>\n");
  1067 + response.append(" <member>\n");
  1068 + response.append(" <name>author.affiliation</name>\n");
  1069 + response.append(" <value>"+m_clients[i].affiliation+"</value>\n");
  1070 + response.append(" </member>\n");
  1071 + response.append(" <member>\n");
  1072 + response.append(" <name>author.email</name>\n");
  1073 + response.append(" <value>"+m_clients[i].email+"</value>\n");
  1074 + response.append(" </member>\n");
  1075 + response.append(" <member>\n");
  1076 + response.append(" <name>author.name</name>\n");
  1077 + response.append(" <value>"+m_clients[i].author_name+"</value>\n");
  1078 + response.append(" </member>\n");
  1079 + response.append(" <member>\n");
  1080 + response.append(" <name>home.page</name>\n");
  1081 + response.append(" <value>"+m_clients[i].homepage+"</value>\n");
  1082 + response.append(" </member>\n");
1115 1083  
1116 1084 } // endif: index was valid
1117 1085  
1118 1086 } // endelse: client was not the hub
1119 1087  
1120 1088 // Finish response
1121   - msg.append(" </struct></value></param>\n");
1122   - msg.append("</params>\n");
1123   - msg.append("</methodResponse>\n");
  1089 + response.append(" </struct></value></param>\n");
  1090 + response.append("</params>\n");
  1091 + response.append("</methodResponse>\n");
1124 1092  
1125 1093 // Post response
1126   - post_string(msg, sock);
  1094 + post_string(response, sock);
1127 1095  
1128 1096 // Return
1129 1097 return;
... ... @@ -1190,9 +1158,10 @@ std::string GVOHub::get_client_key(const GXml&amp; xml) const
1190 1158 * @brief Extract client index in shared memory from XML request
1191 1159 *
1192 1160 * @param[in] xml XML message sent by client.
  1161 + * @return Client index (-1 if not found).
1193 1162 *
1194   - * Extracts the client index in shared memory from the XML request. The
1195   - * method returns -1 if no client was found.
  1163 + * Extracts the client index from the XML request. The method returns -1 if
  1164 + * no client was found.
1196 1165 ***************************************************************************/
1197 1166 int GVOHub::get_client_index(const GXml& xml) const
1198 1167 {
... ... @@ -1226,6 +1195,38 @@ int GVOHub::get_client_index(const GXml&amp; xml) const
1226 1195  
1227 1196  
1228 1197 /***********************************************************************//**
  1198 + * @brief Extract client index in shared memory from XML request
  1199 + *
  1200 + * @param[in] reference Client reference.
  1201 + * @return Client index (-1 if not found).
  1202 + *
  1203 + * Extracts the client index from the client reference. The method returns -1
  1204 + * if no client was found.
  1205 + ***************************************************************************/
  1206 +int GVOHub::get_client_index(const std::string& reference) const
  1207 +{
  1208 + // Header
  1209 + #if defined(G_CONSOLE_DUMP)
  1210 + std::cout << "GVOHub::get_client_index" << std::endl;
  1211 + #endif
  1212 +
  1213 + // Initialise index
  1214 + int index = -1;
  1215 +
  1216 + // Search for index
  1217 + for (int i = 0; i < m_clients.size(); ++i) {
  1218 + if (m_clients[i].reference == reference) {
  1219 + index = i;
  1220 + break;
  1221 + }
  1222 + }
  1223 +
  1224 + // Return index
  1225 + return index;
  1226 +}
  1227 +
  1228 +
  1229 +/***********************************************************************//**
1229 1230 * @brief Returns value for a SAMP client query parameter
1230 1231 *
1231 1232 * @param[in] xml client query XML document.
... ... @@ -1243,7 +1244,7 @@ std::string GVOHub::get_response_value(const GXml&amp; xml,
1243 1244 std::string value = "";
1244 1245  
1245 1246 // Get the client's private key
1246   - const GXmlNode* node = xml.element("methodCall > params > param > value > struct");
  1247 + const GXmlNode* node = xml.element("methodCall > params > param[1] > value > struct");
1247 1248 if (node != NULL) {
1248 1249 int num = node->elements("member");
1249 1250 for (int i = 0; i < num; ++i) {
... ... @@ -1645,39 +1646,6 @@ void GVOHub::create_samp_file(void) const
1645 1646  
1646 1647  
1647 1648 /***********************************************************************//**
1648   - * @brief Post SAMP ok massage to client
1649   - *
1650   - * @param[in] sock Socket.
1651   - *
1652   - * Posts a SAMP of massage to a client.
1653   - ***************************************************************************/
1654   -void GVOHub::post_samp_ok(const socklen_t& sock) const
1655   -{
1656   - // Declare response
1657   - std::string response = "";
1658   -
1659   - // Compose response
1660   - response.append("<?xml version='1.0' encoding='UTF-8'?>\n");
1661   - response.append("<methodResponse>\n");
1662   - response.append("<params>\n");
1663   - response.append(" <param><value><struct>\n");
1664   - response.append(" <member>\n");
1665   - response.append(" <name>samp.status</name>\n");
1666   - response.append(" <value>samp.ok</value>\n");
1667   - response.append(" </member>\n");
1668   - response.append(" </struct></value></param>\n");
1669   - response.append("</params>\n");
1670   - response.append("</methodResponse>\n");
1671   -
1672   - // Post string
1673   - post_string(response, sock);
1674   -
1675   - // Return
1676   - return;
1677   -}
1678   -
1679   -
1680   -/***********************************************************************//**
1681 1649 * @brief Post string content to client
1682 1650 *
1683 1651 * @param[in] content String content to post.
... ... @@ -1693,27 +1661,28 @@ void GVOHub::post_string(const std::string&amp; content, const socklen_t&amp; sock) cons
1693 1661 // Determine content length
1694 1662 int length = content.length();
1695 1663  
1696   - // Set prefix
1697   - std::string prefix = "POST /"+m_hub_path+" HTTP/1.1\n"
1698   - "Content-Type: text/xml\n"
1699   - "User-Agent: GammaLib\n"
1700   - "Host: "+m_hub_host+":"+m_hub_port+"\n"
  1664 + // Set prefix (note that the response has no POST!)
  1665 + std::string prefix = "HTTP/1.1 200 OK\n"
1701 1666 "Connection: close\n"
  1667 + "Content-Type: text/xml\n"
1702 1668 "Content-Length: "+gammalib::str(length)+"\n\n";
1703 1669  
  1670 +
1704 1671 // Build post string
1705 1672 std::string post = prefix + content;
1706 1673  
1707 1674 // Dump message to post
1708   - #if defined(G_CONSOLE_DUMP)
1709   - std::cout << "\nGVOHub::post_string posts the following message" << std::endl;
  1675 + #if defined(G_SHOW_MESSAGE)
  1676 + std::cout << std::endl;
  1677 + std::cout << "GVOHub response:" << std::endl;
  1678 + std::cout << "================" << std::endl;
1710 1679 std::cout << post << std::endl;
1711 1680 #endif
1712 1681  
1713 1682 // Send content to socket
1714 1683 bool done = false;
1715 1684 do {
1716   - int length = post.length() + 1; // +1 for terminating 0
  1685 + int length = post.length();
1717 1686 int sent_length = send(sock, post.c_str(), length, 0);
1718 1687 if (sent_length < length) {
1719 1688 post = post.substr(sent_length, std::string::npos);
... ... @@ -1731,6 +1700,70 @@ void GVOHub::post_string(const std::string&amp; content, const socklen_t&amp; sock) cons
1731 1700  
1732 1701  
1733 1702 /***********************************************************************//**
  1703 + * @brief Post SAMP ok massage to client
  1704 + *
  1705 + * @param[in] sock Socket.
  1706 + *
  1707 + * Posts a SAMP OK message to a client.
  1708 + ***************************************************************************/
  1709 +void GVOHub::post_samp_ok(const socklen_t& sock) const
  1710 +{
  1711 + // Declare response
  1712 + std::string response = "";
  1713 +
  1714 + // Compose response
  1715 + response.append("<?xml version='1.0' encoding='UTF-8'?>\n");
  1716 + response.append("<methodResponse>\n");
  1717 + response.append("<params>\n");
  1718 + response.append(" <param><value><struct>\n");
  1719 + response.append(" <member>\n");
  1720 + response.append(" <name>samp.status</name>\n");
  1721 + response.append(" <value>samp.ok</value>\n");
  1722 + response.append(" </member>\n");
  1723 + response.append(" </struct></value></param>\n");
  1724 + response.append("</params>\n");
  1725 + response.append("</methodResponse>\n");
  1726 +
  1727 + // Post string
  1728 + post_string(response, sock);
  1729 +
  1730 + // Return
  1731 + return;
  1732 +}
  1733 +
  1734 +
  1735 +/***********************************************************************//**
  1736 + * @brief Post SAMP void massage to client
  1737 + *
  1738 + * @param[in] sock Socket.
  1739 + *
  1740 + * Posts a void SAMP message to a client. Void messages can typically be
  1741 + * discared by the client.
  1742 + ***************************************************************************/
  1743 +void GVOHub::post_samp_void(const socklen_t& sock) const
  1744 +{
  1745 + // Declare response
  1746 + std::string response = "";
  1747 +
  1748 + // Compose response
  1749 + response.append("<?xml version='1.0' encoding='UTF-8'?>\n");
  1750 + response.append("<methodResponse>\n");
  1751 + response.append(" <params>\n");
  1752 + response.append(" <param>\n");
  1753 + response.append(" <value/>\n");
  1754 + response.append(" </param>\n");
  1755 + response.append(" </params>\n");
  1756 + response.append("</methodResponse>\n");
  1757 +
  1758 + // Post string
  1759 + post_string(response, sock);
  1760 +
  1761 + // Return
  1762 + return;
  1763 +}
  1764 +
  1765 +
  1766 +/***********************************************************************//**
1734 1767 * @brief Send notification to client
1735 1768 *
1736 1769 * @param[in] url URL.
... ... @@ -1831,8 +1864,10 @@ void GVOHub::notify(const std::string&amp; url,
1831 1864 std::string post = prefix + notification;
1832 1865  
1833 1866 // Dump message to post
1834   - #if defined(G_CONSOLE_DUMP)
1835   - std::cout << "\nGVOHub::notify posts the following message" << std::endl;
  1867 + #if defined(G_SHOW_MESSAGE)
  1868 + std::cout << std::endl;
  1869 + std::cout << "GVOHub sends following notification:" << std::endl;
  1870 + std::cout << "====================================" << std::endl;
1836 1871 std::cout << post << std::endl;
1837 1872 #endif
1838 1873  
... ...