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,6 +94,7 @@ protected:
94 void request_shutdown(const socklen_t& sock); 94 void request_shutdown(const socklen_t& sock);
95 std::string get_client_key(const GXml& xml) const; 95 std::string get_client_key(const GXml& xml) const;
96 int get_client_index(const GXml& xml) const; 96 int get_client_index(const GXml& xml) const;
  97 + int get_client_index(const std::string& reference) const;
97 std::string get_response_value(const GXml& xml, 98 std::string get_response_value(const GXml& xml,
98 const std::string& name) const; 99 const std::string& name) const;
99 void get_name_value_pair(const GXmlNode* node, 100 void get_name_value_pair(const GXmlNode* node,
@@ -108,6 +109,7 @@ protected: @@ -108,6 +109,7 @@ protected:
108 // Low-level methods 109 // Low-level methods
109 void create_samp_file(void) const; 110 void create_samp_file(void) const;
110 void post_samp_ok(const socklen_t& sock) const; 111 void post_samp_ok(const socklen_t& sock) const;
  112 + void post_samp_void(const socklen_t& sock) const;
111 void post_string(const std::string& content, const socklen_t& sock) const; 113 void post_string(const std::string& content, const socklen_t& sock) const;
112 void notify(const std::string& url, const std::string& notification) const; 114 void notify(const std::string& url, const std::string& notification) const;
113 std::string random_string(const size_t& length) const; 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,7 +913,7 @@ void GVOClient::post_string(const std::string& content) const
913 // Send content to socket 913 // Send content to socket
914 bool done = false; 914 bool done = false;
915 do { 915 do {
916 - int length = post.length() + 1; // +1 for terminating 0 916 + int length = post.length();
917 int sent_length = send(m_socket, post.c_str(), length, 0); 917 int sent_length = send(m_socket, post.c_str(), length, 0);
918 if (sent_length < length) { 918 if (sent_length < length) {
919 post = post.substr(sent_length, std::string::npos); 919 post = post.substr(sent_length, std::string::npos);
src/vo/GVOHub.cpp
@@ -42,24 +42,19 @@ @@ -42,24 +42,19 @@
42 #include <sys/wait.h> // waitpid() function 42 #include <sys/wait.h> // waitpid() function
43 #include <arpa/inet.h> // inet_addr() function 43 #include <arpa/inet.h> // inet_addr() function
44 #include "GVOHub.hpp" 44 #include "GVOHub.hpp"
45 -#include "GVOClient.hpp"  
46 #include "GException.hpp" 45 #include "GException.hpp"
47 #include "GTools.hpp" 46 #include "GTools.hpp"
48 47
49 /* __ Method name definitions ____________________________________________ */ 48 /* __ Method name definitions ____________________________________________ */
50 -#define G_INIT_MEMBERS "GVOHub::init_members()"  
51 #define G_START_HUB "GVOHub::start_hub()" 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 /* __ Macros _____________________________________________________________ */ 51 /* __ Macros _____________________________________________________________ */
56 52
57 /* __ Coding definitions _________________________________________________ */ 53 /* __ Coding definitions _________________________________________________ */
58 -#define G_KEY 12345  
59 -//#define G_USE_FORK  
60 54
61 /* __ Debug definitions __________________________________________________ */ 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,8 +244,8 @@ void GVOHub::init_members(void)
249 m_version = "1.3"; 244 m_version = "1.3";
250 m_hub_id = "gammalib_hub"; 245 m_hub_id = "gammalib_hub";
251 m_socket = -1; // Signals no socket 246 m_socket = -1; // Signals no socket
252 - m_clients.clear();  
253 m_shutdown = false; 247 m_shutdown = false;
  248 + m_clients.clear();
254 249
255 // Return 250 // Return
256 return; 251 return;
@@ -273,8 +268,8 @@ void GVOHub::copy_members(const GVOHub&amp; hub) @@ -273,8 +268,8 @@ void GVOHub::copy_members(const GVOHub&amp; hub)
273 m_version = hub.m_version; 268 m_version = hub.m_version;
274 m_hub_id = hub.m_hub_id; 269 m_hub_id = hub.m_hub_id;
275 m_socket = hub.m_socket; 270 m_socket = hub.m_socket;
276 - m_clients = hub.m_clients;  
277 m_shutdown = hub.m_shutdown; 271 m_shutdown = hub.m_shutdown;
  272 + m_clients = hub.m_clients;
278 273
279 // Return 274 // Return
280 return; 275 return;
@@ -372,47 +367,6 @@ void GVOHub::start_hub(void) @@ -372,47 +367,6 @@ void GVOHub::start_hub(void)
372 throw GException::runtime_error(G_START_HUB, msg); 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 // Handle request 370 // Handle request
417 handle_request(socket); 371 handle_request(socket);
418 372
@@ -424,7 +378,6 @@ void GVOHub::start_hub(void) @@ -424,7 +378,6 @@ void GVOHub::start_hub(void)
424 if (m_shutdown) { 378 if (m_shutdown) {
425 break; 379 break;
426 } 380 }
427 - #endif  
428 381
429 } // endwhile: main event loop 382 } // endwhile: main event loop
430 383
@@ -452,8 +405,8 @@ void GVOHub::handle_request(const socklen_t&amp; sock) @@ -452,8 +405,8 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
452 // Initialize buffer 405 // Initialize buffer
453 char buffer[1001]; 406 char buffer[1001];
454 407
455 - // Initialise response  
456 - std::string response = ""; 408 + // Initialise message
  409 + std::string message = "";
457 410
458 // Read from socket until nothing is received anymore. 411 // Read from socket until nothing is received anymore.
459 int timeout = 2000; // Initial timeout is 2 sec 412 int timeout = 2000; // Initial timeout is 2 sec
@@ -462,22 +415,24 @@ void GVOHub::handle_request(const socklen_t&amp; sock) @@ -462,22 +415,24 @@ void GVOHub::handle_request(const socklen_t&amp; sock)
462 n = gammalib::recv(sock, buffer, 1000, 0, timeout); 415 n = gammalib::recv(sock, buffer, 1000, 0, timeout);
463 if (n > 0) { 416 if (n > 0) {
464 buffer[n] = '\0'; 417 buffer[n] = '\0';
465 - response.append(std::string(buffer)); 418 + message.append(std::string(buffer));
466 } 419 }
467 timeout = 10; // The timeout now is 0.01 sec 420 timeout = 10; // The timeout now is 0.01 sec
468 } while (n > 0); 421 } while (n > 0);
469 422
470 // Dump the buffer 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 #endif 429 #endif
475 430
476 // Extract response into an XML object 431 // Extract response into an XML object
477 GXml xml; 432 GXml xml;
478 - size_t start = response.find("<?xml"); 433 + size_t start = message.find("<?xml");
479 if (start != std::string::npos) { 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 // Get methodName value 438 // Get methodName value
@@ -567,21 +522,8 @@ void GVOHub::request_ping(const socklen_t&amp; sock) @@ -567,21 +522,8 @@ void GVOHub::request_ping(const socklen_t&amp; sock)
567 std::cout << "GVOHub::request_ping" << std::endl; 522 std::cout << "GVOHub::request_ping" << std::endl;
568 #endif 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 // Return 528 // Return
587 return; 529 return;
@@ -610,46 +552,41 @@ void GVOHub::request_register(const GXml&amp; xml, const socklen_t&amp; sock) @@ -610,46 +552,41 @@ void GVOHub::request_register(const GXml&amp; xml, const socklen_t&amp; sock)
610 552
611 // Attached client 553 // Attached client
612 m_clients.push_back(voclient); 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 // Declare response 556 // Declare response
620 - std::string msg = ""; 557 + std::string response = "";
621 558
622 // Set response 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 // Post response 588 // Post response
652 - post_string(msg, sock); 589 + post_string(response, sock);
653 590
654 // Send notifications 591 // Send notifications
655 send_notifications("samp.hub.event.register", voclient.reference); 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,19 +617,8 @@ void GVOHub::request_unregister(const GXml&amp; xml, const socklen_t&amp; sock)
680 // Continue only if index is valid 617 // Continue only if index is valid
681 if (i != -1) { 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 // Send notifications 623 // Send notifications
698 send_notifications("samp.hub.event.unregister", 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,18 +672,8 @@ void GVOHub::request_declare_metadata(const GXml&amp; xml, const socklen_t&amp; sock)
746 m_clients[i].author_name = get_response_value(xml, "author.name"); 672 m_clients[i].author_name = get_response_value(xml, "author.name");
747 m_clients[i].homepage = get_response_value(xml, "home.page"); 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 // Send notifications 678 // Send notifications
763 send_notifications("samp.hub.event.metadata", m_clients[i].reference); 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,47 +798,69 @@ void GVOHub::request_get_subscriptions(const GXml&amp; xml, const socklen_t&amp; sock)
882 std::cout << "GVOHub::request_get_subscriptions" << std::endl; 798 std::cout << "GVOHub::request_get_subscriptions" << std::endl;
883 #endif 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 else { 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 // Return 865 // Return
928 return; 866 return;
@@ -1016,19 +954,8 @@ void GVOHub::request_get_subscribed_clients(const GXml&amp; xml, const socklen_t&amp; so @@ -1016,19 +954,8 @@ void GVOHub::request_get_subscribed_clients(const GXml&amp; xml, const socklen_t&amp; so
1016 fclose(fptr); 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 // Return 960 // Return
1034 return; 961 return;
@@ -1043,87 +970,128 @@ void GVOHub::request_get_subscribed_clients(const GXml&amp; xml, const socklen_t&amp; so @@ -1043,87 +970,128 @@ void GVOHub::request_get_subscribed_clients(const GXml&amp; xml, const socklen_t&amp; so
1043 * 970 *
1044 * Handles all metadata requests. 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 // Header 975 // Header
1049 #if defined(G_CONSOLE_DUMP) 976 #if defined(G_CONSOLE_DUMP)
1050 std::cout << "GVOHub::request_get_metadata" << std::endl; 977 std::cout << "GVOHub::request_get_metadata" << std::endl;
1051 #endif 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 // Set response 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 // If key is "gammalib_hub" then return some special information 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 // ... otherwise get the index 1041 // ... otherwise get the index
1082 else { 1042 else {
1083 1043
1084 // Get client index 1044 // Get client index
1085 - int i = get_client_index(xml); 1045 + int i = get_client_index(client_name);
1086 1046
1087 // Continue only if index is valid 1047 // Continue only if index is valid
1088 if (i != -1) { 1048 if (i != -1) {
1089 1049
1090 // Append response 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 } // endif: index was valid 1084 } // endif: index was valid
1117 1085
1118 } // endelse: client was not the hub 1086 } // endelse: client was not the hub
1119 1087
1120 // Finish response 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 // Post response 1093 // Post response
1126 - post_string(msg, sock); 1094 + post_string(response, sock);
1127 1095
1128 // Return 1096 // Return
1129 return; 1097 return;
@@ -1190,9 +1158,10 @@ std::string GVOHub::get_client_key(const GXml&amp; xml) const @@ -1190,9 +1158,10 @@ std::string GVOHub::get_client_key(const GXml&amp; xml) const
1190 * @brief Extract client index in shared memory from XML request 1158 * @brief Extract client index in shared memory from XML request
1191 * 1159 *
1192 * @param[in] xml XML message sent by client. 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 int GVOHub::get_client_index(const GXml& xml) const 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,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 * @brief Returns value for a SAMP client query parameter 1230 * @brief Returns value for a SAMP client query parameter
1230 * 1231 *
1231 * @param[in] xml client query XML document. 1232 * @param[in] xml client query XML document.
@@ -1243,7 +1244,7 @@ std::string GVOHub::get_response_value(const GXml&amp; xml, @@ -1243,7 +1244,7 @@ std::string GVOHub::get_response_value(const GXml&amp; xml,
1243 std::string value = ""; 1244 std::string value = "";
1244 1245
1245 // Get the client's private key 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 if (node != NULL) { 1248 if (node != NULL) {
1248 int num = node->elements("member"); 1249 int num = node->elements("member");
1249 for (int i = 0; i < num; ++i) { 1250 for (int i = 0; i < num; ++i) {
@@ -1645,39 +1646,6 @@ void GVOHub::create_samp_file(void) const @@ -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 * @brief Post string content to client 1649 * @brief Post string content to client
1682 * 1650 *
1683 * @param[in] content String content to post. 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,27 +1661,28 @@ void GVOHub::post_string(const std::string&amp; content, const socklen_t&amp; sock) cons
1693 // Determine content length 1661 // Determine content length
1694 int length = content.length(); 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 "Connection: close\n" 1666 "Connection: close\n"
  1667 + "Content-Type: text/xml\n"
1702 "Content-Length: "+gammalib::str(length)+"\n\n"; 1668 "Content-Length: "+gammalib::str(length)+"\n\n";
1703 1669
  1670 +
1704 // Build post string 1671 // Build post string
1705 std::string post = prefix + content; 1672 std::string post = prefix + content;
1706 1673
1707 // Dump message to post 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 std::cout << post << std::endl; 1679 std::cout << post << std::endl;
1711 #endif 1680 #endif
1712 1681
1713 // Send content to socket 1682 // Send content to socket
1714 bool done = false; 1683 bool done = false;
1715 do { 1684 do {
1716 - int length = post.length() + 1; // +1 for terminating 0 1685 + int length = post.length();
1717 int sent_length = send(sock, post.c_str(), length, 0); 1686 int sent_length = send(sock, post.c_str(), length, 0);
1718 if (sent_length < length) { 1687 if (sent_length < length) {
1719 post = post.substr(sent_length, std::string::npos); 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,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 * @brief Send notification to client 1767 * @brief Send notification to client
1735 * 1768 *
1736 * @param[in] url URL. 1769 * @param[in] url URL.
@@ -1831,8 +1864,10 @@ void GVOHub::notify(const std::string&amp; url, @@ -1831,8 +1864,10 @@ void GVOHub::notify(const std::string&amp; url,
1831 std::string post = prefix + notification; 1864 std::string post = prefix + notification;
1832 1865
1833 // Dump message to post 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 std::cout << post << std::endl; 1871 std::cout << post << std::endl;
1837 #endif 1872 #endif
1838 1873