A fast, lightweight and simple STOMP compatible messaging server
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (C) 2011 Bernhard Froehlich <decke@bluelife.at>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Author's name may not be used endorse or promote products derived
  12. * from this software without specific prior written permission.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  18. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  20. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  22. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  23. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24. * POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <sys/queue.h>
  29. #include <unistd.h>
  30. #include <event2/event.h>
  31. #include <event2/buffer.h>
  32. #include <event2/bufferevent.h>
  33. #include <event2/http.h>
  34. #include <event2/keyvalq_struct.h>
  35. #include "client.h"
  36. #include "log.h"
  37. #include "stomp.h"
  38. #include "stomputil.h"
  39. #include "leveldb.h"
  40. struct queue* stomp_add_queue(const char *queuename)
  41. {
  42. struct queue *entry;
  43. if(queuename == NULL || strlen(queuename) >= MAXQUEUELEN)
  44. return NULL;
  45. entry = malloc(sizeof(*entry));
  46. entry->queuename = malloc(strlen(queuename)+1);
  47. strcpy(entry->queuename, queuename);
  48. TAILQ_INIT(&entry->subscribers);
  49. TAILQ_INSERT_TAIL(&queues, entry, entries);
  50. #ifdef WITH_LEVELDB
  51. if(leveldb_load_queue(entry) != 0){
  52. stomp_free_queue(entry);
  53. return NULL;
  54. }
  55. #else
  56. entry->read = 1;
  57. entry->write = 1;
  58. #endif
  59. return entry;
  60. }
  61. struct queue* stomp_find_queue(const char *queuename)
  62. {
  63. struct queue *queue;
  64. TAILQ_FOREACH(queue, &queues, entries) {
  65. if(strcmp(queue->queuename, queuename) == 0){
  66. return queue;
  67. }
  68. }
  69. return NULL;
  70. }
  71. void stomp_free_queue(struct queue *queue)
  72. {
  73. /* TODO: Remove subscriptions */
  74. TAILQ_REMOVE(&queues, queue, entries);
  75. free(queue);
  76. }
  77. void stomp_free_client(struct client *client)
  78. {
  79. /* Error/Logout */
  80. logwarn("Logout Client %d", client->fd);
  81. client->authenticated = 0;
  82. /* TODO: remove all subscriptions */
  83. /* Disconnect/Free */
  84. if(client->response_cmd == STOMP_CMD_DISCONNECT){
  85. /* TODO: free all allocated memory */
  86. TAILQ_REMOVE(&clients, client, entries);
  87. bufferevent_free(client->bev);
  88. close(client->fd);
  89. free(client);
  90. }
  91. }
  92. int stomp_parse_headers(struct evkeyvalq *headers, char *request)
  93. {
  94. char *line;
  95. size_t line_length;
  96. char *skey, *svalue;
  97. struct evbuffer *buffer;
  98. buffer = evbuffer_new();
  99. evbuffer_add(buffer, request, strlen(request));
  100. while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF)) != NULL) {
  101. skey = NULL;
  102. svalue = NULL;
  103. if(line_length > MAXHEADERLEN){
  104. free(line);
  105. evbuffer_free(buffer);
  106. logwarn("Request exceeded maximum header length %d", MAXHEADERLEN);
  107. return 1;
  108. }
  109. if(strchr(line, ':') == NULL){
  110. free(line);
  111. continue;
  112. }
  113. /* Processing of header lines */
  114. svalue = line;
  115. skey = strsep(&svalue, ":");
  116. if (svalue == NULL){
  117. free(line);
  118. evbuffer_free(buffer);
  119. return 2;
  120. }
  121. svalue += strspn(svalue, " ");
  122. if (evhttp_find_header(headers, skey) == NULL){
  123. if (evhttp_add_header(headers, skey, svalue) == -1){
  124. free(line);
  125. evbuffer_free(buffer);
  126. return 1;
  127. }
  128. }
  129. free(line);
  130. }
  131. evbuffer_free(buffer);
  132. return 0;
  133. }