浏览代码

Daemon get file command transfers file

anon 5 年之前
父节点
当前提交
dbade41402
共有 2 个文件被更改,包括 95 次插入15 次删除
  1. 9 0
      daemon/include/Server.h
  2. 86 15
      daemon/src/Server.cpp

+ 9 - 0
daemon/include/Server.h

@@ -1,6 +1,8 @@
 #ifndef SERVER_H
 #define SERVER_H
 
+#include <fstream>
+
 #include <boost/asio.hpp>
 #include <boost/bind.hpp>
 #include <boost/enable_shared_from_this.hpp>
@@ -22,6 +24,8 @@ private:
 
   const std::string protocolVersion = "0.1";
 
+  const std::string fileDirectory = "./files/";
+
   /**
    * max buffer length
    */
@@ -32,6 +36,11 @@ private:
    */
   char data[max_length];
 
+  /**
+   * file stream for get command
+   */
+  std::ifstream getFile;
+
 public:
   /**
    * Pointer to a con_handler.

+ 86 - 15
daemon/src/Server.cpp

@@ -237,21 +237,92 @@ void con_handler::handle_read_command(const boost::system::error_code &err,
     } else if (root["command"].compare("get") == 0) {
       answer["command"] = "get";
 
-      // TODO establish real connection and send file
-      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));
-
-      // read next data
-      sock.async_read_some(buffer(data, max_length),
-                           boost::bind(&con_handler::handle_read_command,
-                                       shared_from_this(), placeholders::error,
-                                       placeholders::bytes_transferred));
+      // a get request is already being progressed
+      if(this->getFile.is_open()) {
+        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));
+
+        // read next data
+        sock.async_read_some(buffer(data, max_length),
+                             boost::bind(&con_handler::handle_read_command,
+                                         shared_from_this(), placeholders::error,
+                                         placeholders::bytes_transferred));
+      } else {
+        // open file
+        const std::string filename = root["file"].asString();
+        if(filename.find("/") != std::string::npos) {
+          // slashes in file names are illegal
+          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));
+
+          // read next data
+          sock.async_read_some(buffer(data, max_length),
+                               boost::bind(&con_handler::handle_read_command,
+                                           shared_from_this(), placeholders::error,
+                                           placeholders::bytes_transferred));
+        } else {
+          std::string file = this->fileDirectory;
+          file.append(filename);
+
+          this->getFile = std::ifstream(file, std::ios::ate | std::ios::binary);
+
+          if(this->getFile.is_open() == 0) {
+            // file does not exist or cannot be opened
+            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));
+
+            // read next data
+            sock.async_read_some(buffer(data, max_length),
+                                 boost::bind(&con_handler::handle_read_command,
+                                             shared_from_this(), placeholders::error,
+                                             placeholders::bytes_transferred));
+          } else {
+            sock.async_read_some(buffer(data, max_length),
+                                 boost::bind(&con_handler::handle_read_command,
+                                             shared_from_this(), placeholders::error,
+                                             placeholders::bytes_transferred));
+
+            // get size of file
+            size_t size = this->getFile.tellg();
+            this->getFile.seekg(std::ios::beg);
+
+            char fileBuffer[9];
+            while(size_t read = this->getFile.readsome(fileBuffer, 8)) {
+              fileBuffer[read] = 0;
+              size -= read;
+              int remaining = size / 8 + (size % 8 == 0 ? 0 : 1);
+              answer["remaining"] = remaining;
+              answer["cancel"] = false;
+              answer["data"] = base64::encode(fileBuffer);
+
+              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 if (root["command"].compare("close") == 0) {
       answer["command"] = "close";
       answer["response"] = "bye";