Rename openpli-streamproxy to external.
[vuplus_transtreamproxy] / src / Utils.cpp
index 9345e59..af7ac4b 100644 (file)
@@ -8,8 +8,15 @@
 #include <errno.h>
 #include <stdarg.h>
 #include <string.h>
+#include <dirent.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
 
 #include <sstream>
+#include <fstream>
 
 #include "mpegts.h"
 
@@ -28,9 +35,9 @@ std::string ultostr(int64_t data)
 }
 //----------------------------------------------------------------------
 
-int strtoi(std::string data)
+int strtollu(std::string data)
 {
-       int     retval;
+       long long retval;
        std::stringstream ss;
        try {
                ss.str(data);
@@ -103,22 +110,34 @@ bool RequestHeader::parse_header(std::string header)
        method  = infos[0];
        path    = infos[1];
        version = infos[2];
-       decoded_path = path;
 
        if (strncmp(path.c_str(), "/file", 5) == 0) {
-               std::string key = "", value = "";
-               if (!split_key_value(path, "=", key, value)) {
-                       ERROR("fail to parse path(file) : %s", path.c_str());
-                       return false;
-               }
-               if (key != "/file?file") {
-                       ERROR("unknown request file path (key : %s, value : %s)", key.c_str(), value.c_str());
-                       return false;
+               std::vector<std::string> tokens;
+               if (split(path.substr(6), '&', tokens) > 0) {
+                       for (int i = 0; i < tokens.size(); ++i) {
+                               std::string data = tokens[i];
+                               std::string key = "", value = "";
+                               if (!split_key_value(data, "=", key, value)) {
+                                       ERROR("fail to request : %s", data.c_str());
+                                       continue;
+                               }
+                               if (key == "file") {
+                                       extension[key] = UriDecoder().decode(value.c_str());;
+                                       continue;
+                               }
+                               extension[key] = value;
+                       }
                }
                type = REQ_TYPE_TRANSCODING_FILE;
-               decoded_path = UriDecoder().decode(value.c_str());
-       }
 
+//             DEBUG(":: HEADER :: %s", extension["file"].c_str());
+//             std::map<std::string, std::string>::iterator iter = extension.begin();
+//             for (; iter != extension.end(); ++iter) {
+//                     std::string key = iter->first;
+//                     std::string value = iter->second;
+//                     DEBUG("[%s] -> [%s]", key.c_str(), value.c_str());
+//             }
+       }
        DEBUG("info (%d) -> type : [%s], path : [%s], version : [%s]", infos.size(), method.c_str(), path.c_str(), version.c_str());
 
        for (++iter; iter != lines.end(); ++iter) {
@@ -155,14 +174,25 @@ off_t make_response(ThreadParams *params, std::string& response)
                        if((range.length() > 7) && (range.substr(0, 6) == "bytes=")) {
                                range = range.substr(6);
                                if(range.find('-') == (range.length() - 1)) {
-                                       byte_offset = strtoi(range);
+                                       byte_offset = strtollu(range);
                                }
                        }
 
-                       response += (byte_offset > 0) ? HTTP_PARTIAL : HTTP_OK;
+                       off_t content_length = source->stream_length - byte_offset;
+                       if (byte_offset > 0) {
+                               content_length += 1;
+                               response += HTTP_PARTIAL;
+                       }
+                       else {
+                               response += HTTP_OK;
+                       }
                        response += HTTP_PARAMS;
                        response += "Accept-Ranges: bytes\r\n"
-                                           "Content-Length: " + ultostr(source->stream_length) + "\r\n";
+                                           "Content-Length: " + ultostr(content_length) + "\r\n";
+                       response += string("Content-Range: bytes ") +
+                                       ultostr(byte_offset) + "-" +
+                                       ultostr(source->stream_length - 1) + "/" +
+                                       ultostr(source->stream_length) + "\r\n";
                        response += HTTP_DONE;
                }
                break;
@@ -191,3 +221,58 @@ void Util::vlog(const char * format, ...) throw()
        WARNING("%s", vlog_buffer);
 }
 //----------------------------------------------------------------------
+
+std::string get_host_addr()
+{
+       std::stringstream ss;
+    struct sockaddr_in addr;
+    socklen_t addrlen = sizeof(addr);
+
+    getpeername(0, (struct sockaddr*)&addr, &addrlen);
+    ss << inet_ntoa(addr.sin_addr);
+
+    return ss.str();
+}
+//-------------------------------------------------------------------------------
+
+std::vector<int> find_process_by_name(std::string name, int mypid)
+{
+       std::vector<int> pidlist;
+       char cmdlinepath[256] = {0};
+       DIR* d = opendir("/proc");
+       if (d != 0) {
+               struct dirent* de;
+               while ((de = readdir(d)) != 0) {
+                       int pid = atoi(de->d_name);
+                       if (pid > 0) {
+                               sprintf(cmdlinepath, "/proc/%s/cmdline", de->d_name);
+
+                               std::string cmdline;
+                               std::ifstream cmdlinefile(cmdlinepath);
+                               std::getline(cmdlinefile, cmdline);
+                               if (!cmdline.empty()) {
+                                       size_t pos = cmdline.find('\0');
+                                       if (pos != string::npos)
+                                       cmdline = cmdline.substr(0, pos);
+                                       pos = cmdline.rfind('/');
+                                       if (pos != string::npos)
+                                       cmdline = cmdline.substr(pos + 1);
+                                       if ((name == cmdline) && ((mypid != pid) || (mypid == 0))) {
+                                               pidlist.push_back(pid);
+                                       }
+                               }
+                       }
+               }
+               closedir(d);
+       }
+       return pidlist;
+}
+//-------------------------------------------------------------------------------
+
+void kill_process(int pid)
+{
+       int result = kill(pid, SIGINT);
+       DEBUG("SEND SIGINT to %d, result : %d", pid, result);
+       sleep(1);
+}
+//----------------------------------------------------------------------