浏览代码

Put and get use received messages

anon 5 年之前
父节点
当前提交
5c7f4a40a9
共有 2 个文件被更改,包括 92 次插入42 次删除
  1. 10 0
      daemon/include/Server.h
  2. 82 42
      daemon/src/Server.cpp

+ 10 - 0
daemon/include/Server.h

@@ -52,6 +52,16 @@ private:
    */
   std::string putFileName;
 
+  /**
+   * Last chunk number which was sent.
+   */
+  int getFileRemaining;
+
+  /**
+   * Last chunk number which was received.
+   */
+  int putFileReceived;
+
 public:
   /**
    * Pointer to a con_handler.

+ 82 - 42
daemon/src/Server.cpp

@@ -242,9 +242,10 @@ void con_handler::handle_read_command(const boost::system::error_code &err,
         this->putFile.close();
         std::remove(this->putFileName.c_str());
 
-      } else if (this->putFile.is_open()) {
+      } else if (this->putFile.is_open() &&
+                 (this->putFile.tellp() == std::ios::beg ||
+                  root["remaining"].asInt() == this->putFileReceived - 1)) {
         // upload chunks
-
         // decode base64 string
         const std::vector<char> data =
             base64::decodeVector(root["data"].asString());
@@ -253,11 +254,23 @@ void con_handler::handle_read_command(const boost::system::error_code &err,
         std::ostream_iterator<char> output_iterator(putFile);
         std::copy(data.begin(), data.end(), output_iterator);
 
+        this->putFileReceived = root["remaining"].asInt();
         // close file if put sends remaining = 0
-        if (root["remaining"].asInt() == 0) {
+        if (this->putFileReceived == 0) {
           this->putFile.close();
         }
 
+        answer["cancel"] = false;
+        answer["received"] = this->putFileReceived;
+
+        const std::string answerString =
+            Json::writeString(stringBuilder, answer);
+        // send answer
+        sock.async_write_some(
+            buffer(answerString, max_length),
+            boost::bind(&con_handler::handle_write, shared_from_this(),
+                        placeholders::error, placeholders::bytes_transferred));
+
       } else {
         // start upload
         const std::string filename = root["file"].asString();
@@ -281,7 +294,8 @@ void con_handler::handle_read_command(const boost::system::error_code &err,
           // open file and test if it already exists
           this->putFile.open(this->putFileName,
                              std::ios::app | std::ios::binary);
-          if (this->putFile.tellp() != std::ios::beg) {
+          if (this->putFile.tellp() != std::ios::beg &&
+              root["file"].isString()) {
             // file already exists
             this->putFile.close();
             answer["accept"] = false;
@@ -318,17 +332,50 @@ void con_handler::handle_read_command(const boost::system::error_code &err,
 
       answer["command"] = "get";
 
-      // a get request is already being progressed
       if (this->getFile.is_open()) {
-        answer["accept"] = false;
+        // a get request is already being progressed
+        if (root["received"].asInt() == this->getFileRemaining) {
+          if (root["cancel"].asBool()) {
+            // cancel get
+            this->getFile.close();
+          } else if (this->getFileRemaining > 0) {
+            char fileBuffer[max_data_length];
+            size_t read = this->getFile.readsome(fileBuffer, max_data_length);
+            this->getFileRemaining--;
 
-        const std::string answerString =
-            Json::writeString(stringBuilder, answer);
-        // send answer
-        sock.async_write_some(
-            buffer(answerString, max_length),
-            boost::bind(&con_handler::handle_write, shared_from_this(),
-                        placeholders::error, placeholders::bytes_transferred));
+            // store binary data in vector because a string whould end with
+            // '\0'
+            std::vector<char> data;
+            data.assign(fileBuffer, fileBuffer + read);
+
+            answer["remaining"] = this->getFileRemaining;
+            answer["cancel"] = false;
+            answer["data"] = base64::encodeVector(data);
+
+            const std::string answerString =
+                Json::writeString(stringBuilder, answer);
+
+            sock.async_write_some(buffer(answerString, max_length),
+                                  boost::bind(&con_handler::handle_write,
+                                              shared_from_this(),
+                                              placeholders::error,
+                                              placeholders::bytes_transferred));
+          } else {
+            // remaining 0 and received by client so you can close the file
+            this->getFile.close();
+          }
+        } else {
+          answer["accept"] = false;
+
+          const std::string answerString =
+              Json::writeString(stringBuilder, answer);
+          // send answer
+          sock.async_write_some(buffer(answerString, max_length),
+                                boost::bind(&con_handler::handle_write,
+                                            shared_from_this(),
+                                            placeholders::error,
+                                            placeholders::bytes_transferred));
+        }
       } else {
         // open file
         const std::string filename = root["file"].asString();
@@ -365,8 +412,7 @@ void con_handler::handle_read_command(const boost::system::error_code &err,
           } else {
             answer["accept"] = true;
 
-            const std::string answerString =
-                Json::writeString(stringBuilder, answer);
+            std::string answerString = Json::writeString(stringBuilder, answer);
 
             sock.async_write_some(buffer(answerString, max_length),
                                   boost::bind(&con_handler::handle_write,
@@ -381,34 +427,28 @@ void con_handler::handle_read_command(const boost::system::error_code &err,
             size_t size = this->getFile.tellg();
             this->getFile.seekg(std::ios::beg);
 
-            char fileBuffer[max_data_length + 1];
-            while (size_t read =
-                       this->getFile.readsome(fileBuffer, max_data_length)) {
-              fileBuffer[read] = 0;
-              size -= read;
-              int remaining = size / max_data_length +
-                              (size % max_data_length == 0 ? 0 : 1);
-
-              // store binary data in vector because a string whould end with
-              // '\0'
-              std::vector<char> data;
-              data.assign(fileBuffer, fileBuffer + read);
-
-              answer["remaining"] = remaining;
-              answer["cancel"] = false;
-              answer["data"] = base64::encodeVector(data);
-
-              const std::string answerString =
-                  Json::writeString(stringBuilder, answer);
-
-              sock.async_write_some(
-                  buffer(answerString, max_length),
-                  boost::bind(&con_handler::handle_write, shared_from_this(),
-                              placeholders::error,
-                              placeholders::bytes_transferred));
-            }
+            char fileBuffer[max_data_length];
+            size_t read = this->getFile.readsome(fileBuffer, max_data_length);
+            size -= read;
+            this->getFileRemaining =
+                size / max_data_length + (size % max_data_length == 0 ? 0 : 1);
 
-            this->getFile.close();
+            // store binary data in vector because a string whould end with
+            // '\0'
+            std::vector<char> data;
+            data.assign(fileBuffer, fileBuffer + read);
+
+            answer["remaining"] = this->getFileRemaining;
+            answer["cancel"] = false;
+            answer["data"] = base64::encodeVector(data);
+
+            answerString = Json::writeString(stringBuilder, answer);
+
+            sock.async_write_some(buffer(answerString, max_length),
+                                  boost::bind(&con_handler::handle_write,
+                                              shared_from_this(),
+                                              placeholders::error,
+                                              placeholders::bytes_transferred));
           }
         }
       }