瀏覽代碼

fix potential cspot on socket timeout & optimize HTTP server - release

philippe44 2 年之前
父節點
當前提交
f2b0c40848
共有 2 個文件被更改,包括 36 次插入34 次删除
  1. 35 33
      components/spotify/cspot/bell/src/HTTPServer.cpp
  2. 1 1
      components/spotify/cspot/src/PlainConnection.cpp

+ 35 - 33
components/spotify/cspot/bell/src/HTTPServer.cpp

@@ -80,9 +80,8 @@ void bell::HTTPServer::listen() {
         socket(server->ai_family, server->ai_socktype, server->ai_protocol);
     struct sockaddr_in clientname;
     socklen_t incomingSockSize;
-    int i;
     int yes = true;
-    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) {
+    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*) &yes, sizeof(int)) < 0) {
         throw std::runtime_error("setsockopt failed: " +
                                  std::string(strerror(errno)));
     }
@@ -100,62 +99,65 @@ void bell::HTTPServer::listen() {
     FD_ZERO(&activeFdSet);
     FD_SET(sockfd, &activeFdSet);
 
-    for (;;) {
+    for (int maxfd = sockfd;;) {
         /* Block until input arrives on one or more active sockets. */
         readFdSet = activeFdSet;
         struct timeval tv = {0, 100000};
-
-        if (select(FD_SETSIZE, &readFdSet, NULL, NULL, &tv) < 0) {
+ 
+        if (select(maxfd + 1, &readFdSet, NULL, NULL, &tv) < 0) {
             BELL_LOG(error, "http", "Error in select");
             perror("select");
             // exit(EXIT_FAILURE);
         }
 
-        /* Service all the sockets with input pending. */
-        for (i = 0; i < FD_SETSIZE; ++i)
-            if (FD_ISSET(i, &readFdSet)) {
-                if (i == sockfd) {
-                    /* Connection request on original socket. */
-                    int newFd;
-                    incomingSockSize = sizeof(clientname);
-                    newFd = accept(sockfd, (struct sockaddr *)&clientname,
-                                   &incomingSockSize);
-                    if (newFd < 0) {
-                        perror("accept");
-                        exit(EXIT_FAILURE);
-                    }
+        /* Service listening socket. */
+        if (FD_ISSET(sockfd, &readFdSet)) {
+            int newFd;
+            incomingSockSize = sizeof(clientname);
+            newFd = accept(sockfd, (struct sockaddr*)&clientname,
+                    &incomingSockSize);
+            if (newFd < 0) {
+                perror("accept");
+                exit(EXIT_FAILURE);
+             }
 
-                    FD_SET(newFd, &activeFdSet);
+             FD_SET(newFd, &activeFdSet);
 
-                    HTTPConnection conn = {.buffer = std::vector<uint8_t>(128),
-                                           .httpMethod = ""};
+             HTTPConnection conn = { .buffer = std::vector<uint8_t>(128),
+                                     .httpMethod = "" };
 
-                    this->connections.insert({newFd, conn});
-                } else {
-                    /* Data arriving on an already-connected socket. */
-                    readFromClient(i);
-                }
-            }
+             this->connections.insert({ newFd, conn });
+         }
 
+        /* Service other sockets and update set & max */
+        maxfd = sockfd;
         for (auto it = this->connections.cbegin();
-             it != this->connections.cend() /* not hoisted */;
-             /* no increment */) {
+            it != this->connections.cend() /* not hoisted */;
+            /* no increment */) {
+            int fd = (*it).first;
             if ((*it).second.toBeClosed) {
-                close((*it).first);
-                FD_CLR((*it).first, &activeFdSet);
+                close(fd);
+                FD_CLR(fd, &activeFdSet);
                 this->connections.erase(
                     it++); // or "it = m.erase(it)" since C++11
-            } else {
+            }
+            else {
+                if (fd != sockfd && FD_ISSET(fd, &readFdSet)) {
+                    /* Data arriving on an already-connected socket. */
+                    readFromClient(fd);
+                }
+                if (fd > maxfd) maxfd = fd;
                 ++it;
             }
         }
+
     }
 }
 
 void bell::HTTPServer::readFromClient(int clientFd) {
     HTTPConnection &conn = this->connections[clientFd];
 
-    int nbytes = recv(clientFd, &conn.buffer[0], conn.buffer.size(), 0);
+    int nbytes = recv(clientFd, (char*) &conn.buffer[0], conn.buffer.size(), 0);
     if (nbytes < 0) {
         BELL_LOG(error, "http", "Error reading from client");
         perror("recv");

+ 1 - 1
components/spotify/cspot/src/PlainConnection.cpp

@@ -126,7 +126,7 @@ std::vector<uint8_t> PlainConnection::readBlock(size_t size)
                 break;
             default:
                 if (retries++ > 4) throw std::runtime_error("Error in read");
-
+                goto READ;
             }
         }
         idx += n;