Ver código fonte

storing correct username in the message

Sergey Lyubka 15 anos atrás
pai
commit
abca5d8016
1 arquivos alterados com 35 adições e 25 exclusões
  1. 35 25
      examples/chat.c

+ 35 - 25
examples/chat.c

@@ -60,6 +60,22 @@ static long last_message_id;
 // Protects messages, sessions, last_message_id
 static pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
 
+// Get session object for the connection. Caller must hold the lock.
+static struct session *get_session(const struct mg_connection *conn) {
+  int i;
+  char session_id[33];
+  time_t now = time(NULL);
+  mg_get_cookie(conn, "session", session_id, sizeof(session_id));
+  for (i = 0; i < MAX_SESSIONS; i++) {
+    if (sessions[i].expire != 0 &&
+        sessions[i].expire > now &&
+        strcmp(sessions[i].session_id, session_id) == 0) {
+      break;
+    }
+  }
+  return i == MAX_SESSIONS ? NULL : &sessions[i];
+}
+
 // Get a get of messages with IDs greater than last_id and transform them
 // into a JSON string. Return that string to the caller. The string is
 // dynamically allocated, caller must free it. If there are no messages,
@@ -136,6 +152,7 @@ static void ajax_get_messages(struct mg_connection *conn,
 static void ajax_send_message(struct mg_connection *conn,
     const struct mg_request_info *request_info) {
   struct message *message;
+  struct session *session;
   char text[sizeof(message->text) - 1];
   int is_jsonp;
 
@@ -150,8 +167,10 @@ static void ajax_send_message(struct mg_connection *conn,
     message = &messages[last_message_id %
       (sizeof(messages) / sizeof(messages[0]))];
     // TODO(lsm): JSON-encode all text strings
-    strncpy(message->text, text, sizeof(text));
-    strncpy(message->user, "joe", sizeof(message->user));
+    session = get_session(conn);
+    assert(session != NULL);
+    strlcpy(message->text, text, sizeof(text));
+    strlcpy(message->user, session->user, sizeof(message->user));
     message->timestamp = time(0);
     message->id = last_message_id++;
     pthread_rwlock_unlock(&rwlock);
@@ -259,31 +278,22 @@ static void authorize(struct mg_connection *conn,
 // Return 1 if request is authorized, 0 otherwise.
 static int is_authorized(const struct mg_connection *conn,
     const struct mg_request_info *request_info) {
-  char valid_id[33], received_id[33];
-  int i, authorized = 0;
-
-  mg_get_cookie(conn, "session", received_id, sizeof(received_id));
-  if (received_id[0] != '\0') {
-    pthread_rwlock_rdlock(&rwlock);
-    for (i = 0; i < MAX_SESSIONS; i++) {
-      if (sessions[i].expire != 0 &&
-          sessions[i].expire > time(NULL) &&
-          strcmp(sessions[i].session_id, received_id) == 0) {
-        break;
-      }
-    }
-    if (i < MAX_SESSIONS) {
-      generate_session_id(valid_id, sessions[i].random,
-          sessions[i].user, request_info);
-      if (strcmp(valid_id, received_id) == 0) {
-        sessions[i].expire = time(0) + SESSION_TTL;
-        authorized = 1;
-      }
+  struct session *session;
+  char valid_id[33];
+  int authorized = 0;
+
+  pthread_rwlock_rdlock(&rwlock);
+  if ((session = get_session(conn)) != NULL) {
+    generate_session_id(valid_id, session->random, session->user, request_info);
+    if (strcmp(valid_id, session->session_id) == 0) {
+      session->expire = time(0) + SESSION_TTL;
+      authorized = 1;
     }
-    pthread_rwlock_unlock(&rwlock);
   }
-  printf("session: %s, uri: %s, authorized: %s, cookie: %s\n",
-      received_id, request_info->uri, authorized ? "yes" : "no", mg_get_header(conn, "Cookie"));
+  // Printing while holding the lock is a bad idea.
+  printf("session: %s, uri: %s, authorized: %s\n",
+      session->session_id, request_info->uri, authorized ? "yes" : "no");
+  pthread_rwlock_unlock(&rwlock);
 
   return authorized;
 }