diff options
author | T. Lohmar <smarttv640@gmail.com> | 2016-01-30 17:58:09 +0100 |
---|---|---|
committer | T. Lohmar <smarttv640@gmail.com> | 2016-01-30 17:58:09 +0100 |
commit | a0e67197b6bbf6646a03f9a01e2ca204b447e8ae (patch) | |
tree | 61c9c580d30db60d7a126f06794bb16ab7dc0365 | |
parent | 89fa8d151e96f68a9190299a2f04c1e47590ea51 (diff) | |
download | vdr-plugin-smarttvweb-a0e67197b6bbf6646a03f9a01e2ca204b447e8ae.tar.gz vdr-plugin-smarttvweb-a0e67197b6bbf6646a03f9a01e2ca204b447e8ae.tar.bz2 |
Monitor remote IP of HTTP transactions. Monitor transaction duration also for recording playback. Add anchor for Per-Folder Recordin list query.
-rwxr-xr-x | httpclient.c | 2 | ||||
-rwxr-xr-x | httpresource.c | 8 | ||||
-rwxr-xr-x | httpresource.h | 2 | ||||
-rw-r--r-- | httpresource_base.c | 2 | ||||
-rwxr-xr-x | httpresource_base.h | 9 | ||||
-rwxr-xr-x | responsebase.c | 2 | ||||
-rw-r--r-- | responsebase.h | 3 | ||||
-rwxr-xr-x | responsefile.c | 14 | ||||
-rwxr-xr-x | responsememblk.c | 4 | ||||
-rwxr-xr-x | responsememblk.h | 7 | ||||
-rwxr-xr-x | responsevdrdir.c | 26 | ||||
-rwxr-xr-x | smarttvfactory.c | 29 | ||||
-rwxr-xr-x | smarttvfactory.h | 95 |
13 files changed, 181 insertions, 22 deletions
diff --git a/httpclient.c b/httpclient.c index 08419fd..83e9de9 100755 --- a/httpclient.c +++ b/httpclient.c @@ -39,7 +39,7 @@ #define DEBUGPREFIX mLog->getTimeString() << ": mClient= " << mReqId << " fd= " << mFd -cHttpClientBase::cHttpClientBase(int f, int id, int port, SmartTvServer* factory, string peer) : cHttpResourceBase(f, id, port, factory), +cHttpClientBase::cHttpClientBase(int f, int id, int port, SmartTvServer* factory, string peer) : cHttpResourceBase(f, id, port, "-", factory), mLog(), mRequestMessage(""), mRequestMessagePos(0), mConnState(0), mResponseHdr(), mRespBdyLen(-1), mStatus(-1), mIsChunked(false), mResponseBdy(), mPeer(peer), mTransCount(0) { diff --git a/httpresource.c b/httpresource.c index b6f6d06..60868ba 100755 --- a/httpresource.c +++ b/httpresource.c @@ -79,7 +79,7 @@ using namespace std; -cHttpResource::cHttpResource(int f, int id, int port, SmartTvServer* factory): cHttpResourceBase(f, id, port, factory), +cHttpResource::cHttpResource(int f, int id, int port, string a, SmartTvServer* factory): cHttpResourceBase(f, id, port, a, factory), mLog(), mConnTime(0), mHandleReadCount(0), mConnected(true), mConnState(WAITING), mReadBuffer(), mMethod(), // mBlkData(NULL), mBlkPos(0), mBlkLen(0), @@ -301,6 +301,12 @@ int cHttpResource::processRequest() { return OKAY; } + if (mPath.compare("/getrecordings") == 0) { + mResponse = new cResponseMemBlk(this); + ((cResponseMemBlk*)mResponse)->GetRecordings(); + return OKAY; + } + if (mPath.compare("/channels.xml") == 0) { mResponse = new cResponseMemBlk(this); ((cResponseMemBlk*)mResponse)->sendChannelsXml( &statbuf); diff --git a/httpresource.h b/httpresource.h index daa75a6..abe0533 100755 --- a/httpresource.h +++ b/httpresource.h @@ -67,7 +67,7 @@ class cResponseBase; class cHttpResource : public cHttpResourceBase { public: - cHttpResource(int, int, int, SmartTvServer*); + cHttpResource(int, int, int, string, SmartTvServer*); virtual ~cHttpResource(); int handleRead(); diff --git a/httpresource_base.c b/httpresource_base.c index 63cbf69..f9d9904 100644 --- a/httpresource_base.c +++ b/httpresource_base.c @@ -28,7 +28,7 @@ int cHttpResourcePipe::mPipeId = 0; #define MEMBUFLEN 1000 -cHttpResourcePipe::cHttpResourcePipe(int f, SmartTvServer* fac) : cHttpResourceBase(f, mPipeId++, 0, fac), mLog(NULL), mBuf(NULL) { +cHttpResourcePipe::cHttpResourcePipe(int f, SmartTvServer* fac) : cHttpResourceBase(f, mPipeId++, 0, "-", fac), mLog(NULL), mBuf(NULL) { mLog = Log::getInstance(); mBuf = new char[MEMBUFLEN]; diff --git a/httpresource_base.h b/httpresource_base.h index 8341c8f..250f588 100755 --- a/httpresource_base.h +++ b/httpresource_base.h @@ -23,12 +23,17 @@ #ifndef __HTTPREQUEST_base_H__ #define __HTTPREQUEST_base_H__ +#include <string> + +using namespace std; + class SmartTvServer; class cHttpResourceBase { public: - cHttpResourceBase(int f, int id, int port, SmartTvServer* fac): mFd(f), mReqId(id), mFactory(fac), mServerPort(port) {}; + cHttpResourceBase(int f, int id, int port, string addr, SmartTvServer* fac): mFd(f), mReqId(id), mFactory(fac), mServerPort(port), + mRemoteAddr (addr) {}; virtual ~cHttpResourceBase() {}; virtual int handleRead() =0; @@ -39,6 +44,8 @@ class cHttpResourceBase { int mReqId; SmartTvServer* mFactory; int mServerPort; + + string mRemoteAddr; }; diff --git a/responsebase.c b/responsebase.c index 388b86a..1ca526a 100755 --- a/responsebase.c +++ b/responsebase.c @@ -40,6 +40,8 @@ cResponseBase::cResponseBase(cHttpResource* req): mBlkData(NULL), mBlkPos(0), mB mLog = Log::getInstance(); mBlkData = new char[MAXLEN]; + + gettimeofday(&mResponseStart,0); } diff --git a/responsebase.h b/responsebase.h index 5600866..0d251b5 100644 --- a/responsebase.h +++ b/responsebase.h @@ -25,6 +25,7 @@ #include <ctime> #include <stdint.h> +#include <sys/time.h> class cHttpResource; class Log; @@ -56,6 +57,8 @@ class cResponseBase { cHttpResource* mRequest; uint64_t mRemLength; bool mError; + + timeval mResponseStart; }; diff --git a/responsefile.c b/responsefile.c index f5bb319..cdf47b4 100755 --- a/responsefile.c +++ b/responsefile.c @@ -28,6 +28,7 @@ #include <sys/stat.h> #include <errno.h> #include <cstring> +#include <sys/time.h> //#define MAXLEN 4096 #define DEBUGPREFIX mLog->getTimeString() << ": mReqId= " << mRequest->mReqId << " fd= " << mRequest->mFd @@ -40,10 +41,23 @@ cResponseFile::cResponseFile(cHttpResource* req) : cResponseBase(req), mFile(NUL } cResponseFile::~cResponseFile() { + timeval now; + gettimeofday(&now, 0); + if (mFile != NULL) { fclose(mFile); mFile = NULL; } + + long long diff; // in sec + diff = (now.tv_sec - mResponseStart.tv_sec); + diff += (now.tv_usec - mResponseStart.tv_usec) /1000000.0; + + *(mLog->log())<< DEBUGPREFIX + << " cResponseFile: Response duration= " << diff << " s" + << " RemoteIP= " << mRequest->mRemoteAddr + << endl; + } diff --git a/responsememblk.c b/responsememblk.c index 5f6eba1..20bae59 100755 --- a/responsememblk.c +++ b/responsememblk.c @@ -83,9 +83,6 @@ int timerCompare(const void* i, const void *j) { #endif cResponseMemBlk::cResponseMemBlk(cHttpResource* req) : cResponseBase(req), mResponseMessage(NULL), mResponseMessagePos(0) { - - gettimeofday(&mResponseStart,0); - } cResponseMemBlk::~cResponseMemBlk() { @@ -103,6 +100,7 @@ cResponseMemBlk::~cResponseMemBlk() { *(mLog->log())<< DEBUGPREFIX << " cResponseMemBlk: Response duration= " << diff/1000.0 << " ms" + << " RemoteIP= " << mRequest->mRemoteAddr << endl; } diff --git a/responsememblk.h b/responsememblk.h index 752b527..5cd11e8 100755 --- a/responsememblk.h +++ b/responsememblk.h @@ -27,7 +27,6 @@ #include <sys/stat.h> #include <string> #include <vector> -#include <sys/time.h> #include "responsebase.h" #include <vdr/config.h> @@ -69,6 +68,8 @@ class cResponseMemBlk : public cResponseBase { int fillDataBlk(); int sendRecordingsXml (struct stat *statbuf); + int GetRecordings (); + int sendChannelsXml (struct stat *statbuf); int sendResumeXml (); int sendMarksXml (); @@ -110,14 +111,14 @@ class cResponseMemBlk : public cResponseBase { int parseResume(cResumeEntry &entry, string &id); int parseFiles(vector<sFileEntry> *entries, string prefix, string dir_base, string dir_name, struct stat *statbuf); int sendDir(struct stat *statbuf); - int writeXmlItem(string title, string link, string programme, string desc, string guid, int no, time_t start, int dur, double fps, int is_pes, int is_new, string mime); + int writeXmlItem(string title, string link, string programme, bool add_desc, string desc, string guid, + int no, time_t start, int dur, double fps, int is_pes, int is_new, string mime); uint64_t getVdrFileSize(); private: string *mResponseMessage; int mResponseMessagePos; - timeval mResponseStart; }; #endif diff --git a/responsevdrdir.c b/responsevdrdir.c index d01fe2b..1813441 100755 --- a/responsevdrdir.c +++ b/responsevdrdir.c @@ -26,6 +26,7 @@ #include "smarttvfactory.h" #include <vector> #include <cstdlib> +#include <sys/time.h> #ifndef STANDALONE #include <vdr/recording.h> @@ -71,22 +72,37 @@ struct tIndexTs { int reserved:7; // reserved for future use int independent:1; // marks frames that can be displayed by themselves (for trick modes) uint16_t number:16; // up to 64K files per recording - }; +}; cResponseVdrDir::cResponseVdrDir(cHttpResource* req) : cResponseBase(req), mIsRecording(false), mStreamToEnd(false), mRecProgress(0.0), mVdrIdx(0), mFile(NULL), mFileStructure() { + } cResponseVdrDir::~cResponseVdrDir() { + timeval now; + gettimeofday(&now, 0); + if (mFile != NULL) { - *(mLog->log())<< DEBUGPREFIX - << " ERROR: mFile still open. Closing now..." << endl; +#ifdef DEBUG + *(mLog->log())<< DEBUGPREFIX << " mFile still open. Closing now..." << endl; +#endif fclose(mFile); mFile = NULL; } -} + double diff; // in sec + diff = (now.tv_sec - mResponseStart.tv_sec); + diff += (now.tv_usec - mResponseStart.tv_usec) /1000000; + + char f[20]; + snprintf(f, sizeof(f), "%.02f", diff); + *(mLog->log())<< DEBUGPREFIX + << " cResponseVdrDir: Response duration= " << f << " s" + << " RemoteIP= " << mRequest->mRemoteAddr + << endl; +} bool cResponseVdrDir::isTimeRequest(struct stat *statbuf) { @@ -146,8 +162,6 @@ bool cResponseVdrDir::isTimeRequest(struct stat *statbuf) { if (is_pes){ idx_file = fopen(((mRequest->mDir) +"/index.vdr").c_str(), "r"); - // sendError(400, "Bad Request", NULL, "PES not yet supported."); - // return true; } else { idx_file = fopen(((mRequest->mDir) +"/index").c_str(), "r"); diff --git a/smarttvfactory.c b/smarttvfactory.c index 27c0b2a..3d18fd5 100755 --- a/smarttvfactory.c +++ b/smarttvfactory.c @@ -807,10 +807,27 @@ void SmartTvServer::logActiveSessionIds() { void SmartTvServer::acceptHttpResource(int &req_id) { int rfd = 0; sockaddr_in sadr; - socklen_t addr_size = 0; + char ipstr[INET6_ADDRSTRLEN + 1]; + socklen_t addr_size = sizeof(sadr); + + string ip_ver = "ipv6"; if((rfd = accept(mServerFd, (sockaddr*)&sadr, &addr_size))!= -1){ req_id ++; + + switch (sadr.sin_family) { + case AF_INET: + ip_ver = "ip_v4"; + inet_ntop(AF_INET, &(sadr.sin_addr), ipstr, sizeof ipstr); + break; + case AF_INET6: + inet_ntop(AF_INET6, &(sadr.sin_addr), ipstr, sizeof ipstr); + break; + default: + ip_ver = "Unknown"; + break; + } + #ifndef DEBUG *(mLog.log()) << mLog.getTimeString() << ": fd= " << rfd @@ -824,9 +841,12 @@ void SmartTvServer::acceptHttpResource(int &req_id) { mMaxFd = rfd; } - clientList.push_back(new cHttpResource(rfd, req_id, serverPort, this)); + clientList.push_back(new cHttpResource(rfd, req_id, serverPort, ipstr, this)); mActiveSessions ++; - *(mLog.log()) << mLog.getTimeString() << ": + New Session mReqId= " << req_id << endl; + *(mLog.log()) << mLog.getTimeString() << ": + New Session mReqId= " << req_id + << " ver= " << ip_ver << " " << sadr.sin_family + << " IP= " << ipstr + << endl; logActiveSessionIds(); } else{ @@ -1012,6 +1032,9 @@ int SmartTvServer::isServing() { return (mActiveSessions != 0 ? true : false) or connected_tv; } +int SmartTvServer::getActiveHttpSessions() { + return mActiveSessions; +} string SmartTvServer::processNestedItemList(string pref, cList<cNestedItem> *cmd, vector<cCmd*> *cmd_list) { char f[400]; diff --git a/smarttvfactory.h b/smarttvfactory.h index ad6b2c7..a2a53f1 100755 --- a/smarttvfactory.h +++ b/smarttvfactory.h @@ -47,8 +47,9 @@ class cStatus { using namespace std; -#define PLG_VERSION "1.0.2" -#define SERVER "SmartTvWeb/1.0.2" +#define PLG_VERSION "1.0.3" +#define SERVER "SmartTvWeb/1.0.3" + class cLiveRelay; struct sClientEntry { @@ -68,6 +69,84 @@ class cCmd { bool mConfirm; }; +class cActiveRecording { + public: + string mName; + string mFilename; + + cActiveRecording(string n, string fn) : mName(n), mFilename(fn) {}; +}; + +class cRecEntryBase { + public: + cRecEntryBase (string n, int l, bool i, Log* lg) : mLevel(l), mName(n), mIsFolder(i), mLog(lg) {}; + virtual ~cRecEntryBase() {}; + + // virtual void appendEntry(cRecEntryBase*, int ) {}; + + int mLevel; + string mName; + bool mIsFolder; + virtual void print(string pref); + virtual int writeXmlItem(string *, string own_ip, int own_port) { return -1; }; + + Log *mLog; + friend ostream &operator<< (ostream &ofd, cRecEntryBase b) { return ofd; }; +}; + +class cRecEntry; + +class cRecFolder : public cRecEntryBase { + public: + list<cRecEntryBase*> mEntries; // only when folder + string mPath; // full path (incl mName) + + cRecFolder(string n, string p, int l, Log* lg) : cRecEntryBase(n, l, true, lg), mEntries(), mPath(p) {}; + virtual ~cRecFolder() { + for (list<cRecEntryBase*>::iterator iter = mEntries.begin(); iter != mEntries.end(); ++iter) + delete *iter; + }; + void appendEntry(cRecEntry*); + void appendEntry(cRecFolder*); + + cRecFolder* GetFolder(list<string> *folder_list); + void print(string pref); + int writeXmlItem(string *, string own_ip, int own_port); + int writeXmlFolder(string*, string own_ip, int own_port); + + friend ostream &operator<< (ostream &ofd, cRecFolder b) { + ofd << "Folder " << b.mName << " l= " << b.mLevel; + + return ofd; + }; + +}; + +class cRecEntry : public cRecEntryBase { + cRecording* mRec; + // bool mIsFolder ; + public: + vector<string> mSubfolders; + bool mError; + // int mLevel; + string mTitle; + // list<cRecEntry*> mEntries; // only when folder + + cRecEntry(string mName, int l, Log* lg, cRecording*); + virtual ~cRecEntry() {}; + + int writeXmlItem(string *, string own_ip, int own_port); + void print(string pref); + + friend ostream &operator<< (ostream &ofd, cRecEntry b) { + ofd << "Entry " << b.mName << " l= " << b.mLevel << " s= " << b.mSubfolders.size() << " E= "; + for (uint i = 0; i < b.mSubfolders.size(); i++) + ofd << b.mSubfolders[i] << " "; + return ofd; + }; +}; + + class SmartTvServer : public cStatus { public: @@ -84,6 +163,7 @@ class SmartTvServer : public cStatus { void readRecordings(); int isServing(); + int getActiveHttpSessions(); string getConfigDir() { return mConfigDir; }; cSmartTvConfig* getConfig() { return mConfig; }; @@ -110,6 +190,8 @@ class SmartTvServer : public cStatus { void setWriteFlag(int fd); int openPipe(); + cRecFolder* GetRecDb(); + private: void addHttpResource(int fd, cHttpResourceBase* resource); void pushToClients(cHttpResourceBase* resource); @@ -165,6 +247,15 @@ class SmartTvServer : public cStatus { string mCmdCmdMsg; vector<string> mRecCmdList; vector<string> mCmdCmdList; + + list<cActiveRecording*> mActRecordings; + void AddActRecording(string, string); + void DelActRecording(string, string); + bool IsActRecording(string); + + cRecFolder* mRecordings; + int mRecState; + void CreateRecDb(); }; |