protocol_shoutcastClient.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #pragma once
  2. #ifndef protocol_shoutcastClient_H_
  3. #define protocol_shoutcastClient_H_
  4. #include "threadedRunner.h"
  5. #include "streamData.h"
  6. #include "stats.h"
  7. #include "bandwidth.h"
  8. #include "protocol_HTTPStyle.h"
  9. #pragma pack(push, 1)
  10. class protocol_shoutcastClient: public runnable, public clientProtocol
  11. {
  12. public:
  13. friend class protocol_HTTPStyle;
  14. typedef void (protocol_shoutcastClient::*state_t)();
  15. protocol_shoutcastClient (protocol_HTTPStyle &hs, const streamData::streamID_t streamID, const uniString::utf8 &hostName, const uniString::utf8 &clientAddr, const uniString::utf8 &XFF, const streamData::source_t clientType);
  16. protocol_shoutcastClient(const socketOps::tSOCKET socket, const u_short port,
  17. const streamData::source_t clientType, const uniString::utf8 &hostName,
  18. const streamData::streamID_t streamID, const size_t unique,
  19. const uniString::utf8 &userAgent, const uniString::utf8 &referer,
  20. const uniString::utf8 &clientAddr, const uniString::utf8 &XFF,
  21. const bool headRequest);
  22. virtual ~protocol_shoutcastClient() throw()
  23. {
  24. m_streamData = 0;
  25. socketOps::forgetTCPSocket(m_socket);
  26. }
  27. virtual void setIntro(vector<__uint8> &v, int uvoxDataType = MP3_DATA) { m_introFile = v; m_introFileOffset = 0; (void)uvoxDataType; }
  28. virtual void acquireIntroFile(const bool sc2 = false) throw();
  29. virtual int acquireBackupFile(int *dataType = 0, const bool sc2 = false) throw();
  30. void kickNextRound() throw() { m_kickNextRound = true; }
  31. void setGroup(size_t group) throw() { m_adAccess.setGroup (group); }
  32. const size_t getGroup() const throw() { return m_adAccess.getGroup(); }
  33. const size_t getUnique() const throw() { return m_unique; }
  34. const streamData::source_t getClientType() const throw() { return m_clientType; }
  35. const time_t getStartTime() const throw() { return m_startTime; }
  36. const uniString::utf8 getXFF() const throw() { return m_XFF; }
  37. const uniString::utf8 getUserAgent() const throw() { return (!m_userAgent.empty() ? m_userAgent : EMPTY_AGENT); }
  38. const uniString::utf8 getReferer() const throw() { return m_referer; }
  39. void return_403();
  40. const streamData::ringBufferAccess_t resetReadPtr(std::vector<__uint8>& data, const bool sc2 = false) throw();
  41. void resetReadPtr(const bool sc2 = false) throw();
  42. void resetReadPtr (streamData::ringBufferAccess_t ptr, bool sc2) throw();
  43. const int doTimeSlice(const bool sc2 = false) throw(std::exception);
  44. void resetCommon() throw();
  45. const bool sendText() throw(std::exception);
  46. void setupWorkingBuffer(const std::vector<__uint8>& data, std::vector<__uint8>& tempBuf, int& len) throw();
  47. virtual void processFrame (int type, const unsigned char *buf, unsigned int len);
  48. const int doFLVFrameSync(const int type, const bool debug, const int offset,
  49. const std::vector<__uint8>& buf, const time_t cur_time,
  50. const int bitrate, const unsigned int samplerate,
  51. int &len, int &frames, bool &advert, int &timestamp,
  52. const bool fill_remainder = false) throw();
  53. virtual const int doFrameSync(const int type, const bool debug, const int len,
  54. const int offset, const std::vector<__uint8>& buf,
  55. const time_t cur_time, const int bitrate,
  56. const unsigned int samplerate, int &frames,
  57. bool &advert, const bool fill_remainder = false) throw();
  58. void createFrameRate(const bool mp3, const int samplerate);
  59. const __uint64 calculateFrameLimit(const time_t cur_time = 0);
  60. void updateFrameCount(const int frames, const time_t cur_time = 0);
  61. const bool calculateDelay(const int autoDumpTime = -1);
  62. virtual int doSend(const bool debug, const time_t cur_time,
  63. const int autoDumpTime, int adjust = 0) throw(std::runtime_error);
  64. void checkListenerIsValid(const bool debug) throw(std::runtime_error);
  65. void setW3CState() throw();
  66. const uniString::utf8 getContainer() const;
  67. void authForStream(streamData *_sd = 0);
  68. const bool handleNoData(const uniString::utf8 &logString, const int remainder,
  69. const streamData::ringBufferAccess_t amt,
  70. const int autoDumpTime, const time_t cur_time,
  71. const bool sc2 = false);
  72. void streamMovedOrRejected(const uniString::utf8 &logString, const bandWidth::usageType_t type,
  73. const uniString::utf8 &serverUrl, const int mode) throw();
  74. const bool processAdvertTrigger(const bool advert);
  75. const uniString::utf8 fixICYMetadata(uniString::utf8 metadata);
  76. void logW3C() throw();
  77. void doLogW3C(const uniString::utf8 &title = "") throw();
  78. void processTitleW3C() throw();
  79. const adGroupAccess &getAdAccess () const { return m_adAccess; }
  80. void releaseAdvert();
  81. const int processAdd(const uniString::utf8 &logString, const bandWidth::usageType_t type,
  82. const uniString::utf8 &msg, const int msgLen,
  83. const uniString::utf8 &movedUrl, const uniString::utf8 &serverUrl) throw();
  84. const bool processReject(const uniString::utf8 &logString, const bandWidth::usageType_t type,
  85. const uniString::utf8 &msg, const int msgLen, int *read_bitrate,
  86. int *dataType = 0, const bool sc2 = false) throw();
  87. const int addClient();
  88. void reportNewListener(const uniString::utf8 &logString = "");
  89. void reportStopListener();
  90. void cleanup(const uniString::utf8 &logString, const bool debug,
  91. const bool sc2 = false, const bool altLog = false) throw(exception);
  92. virtual int detectAutoDumpTimeout (time_t &cur_time, const size_t streamID, const uniString::utf8 &msg) throw(runtime_error);
  93. virtual void state_AttachToStream() throw(exception) = 0;
  94. virtual void state_Close() throw(std::exception) = 0;
  95. virtual void state_InitiateStream() throw(std::exception) = 0;
  96. virtual void state_SendText() throw(std::exception);
  97. virtual void state_SendAdverts() throw(std::exception);
  98. virtual void state_Stream() throw(std::exception);
  99. virtual void state_SendBackupFile() throw(std::exception);
  100. virtual void state_SendIntroFile() throw(std::exception);
  101. virtual void state_SendIntro() throw(std::exception);
  102. virtual void setCallback (state_t callback = NULL, state_t next = NULL) = 0;
  103. friend class auth::authService;
  104. friend void metrics::metrics_listener_new(const protocol_shoutcastClient &client);
  105. friend void metrics::metrics_listener_drop(const protocol_shoutcastClient &client);
  106. friend void stats::catchPreAddClients(const streamData::streamID_t id);
  107. protected:
  108. uniString::utf8 m_clientHostName;
  109. const streamData::streamID_t m_streamID; // stream ID for this connection
  110. const size_t m_unique; // clients' unique id
  111. uniString::utf8 m_userAgent; // client's user agent string
  112. uniString::utf8 m_referer; // client's referer string
  113. uniString::utf8 m_queryParams; // client's query parameters
  114. streamData::source_t m_clientType; // stream client type
  115. bool m_removeClientFromStats; // do we have to do a stats::removeClient
  116. bool m_kickNextRound;
  117. bool m_headRequest;
  118. bool m_ignoreDisconnect; // used to prevent the 'client connection closed (0 seconds) [Bytes: 0] Agent:'
  119. // message if redirecting or if max limit was reached which keeps logs cleaner
  120. time_t m_startTime; // when connection started, used to implement listenerTime
  121. time_t m_newListener; // when the new listener metric was sent
  122. time_t m_timerStart; // for time regulated sending
  123. __uint64 m_timerFrames; // amount sent during timer;
  124. streamData *m_streamData;
  125. uniString::utf8 m_clientLogString;
  126. uniString::utf8 m_clientAddr; // client's address
  127. uniString::utf8 m_XFF;
  128. uniString::utf8 m_OKResponse;
  129. uniString::utf8 m_lastSentMetadata; // used for w3C tracking
  130. std::vector<__uint8> m_introFile;
  131. int m_introFileOffset;
  132. int m_backupFileOffset;
  133. std::vector<__uint8> m_backupFile;
  134. int m_backupLoopTries;
  135. unsigned int m_lagOffset;
  136. adGroupAccess m_adAccess;
  137. //// stats for w3c logs
  138. time_t m_lastTitleTime; // time of last title update used for w3c logs
  139. __uint64 m_bytesSentForCurrentTitle; // bytes sent since last title change. used for w3c logs
  140. __uint64 m_totalBytesSent; // total bytes sent whilst the connection is open
  141. ///////////////////////////
  142. streamData::ringBufferAccess_t m_readPtr; // pointer into ring buffer (main playback)
  143. const uniString::utf8::value_type *m_outBuffer; // for outgoing text lines
  144. int m_outBufferSize;
  145. unsigned short m_metaInterval;
  146. unsigned short m_metaIntervalCounter; // counter for metadata updates
  147. double m_fps;
  148. __uint64 m_frameLimit; // how many frames we're allowed
  149. __uint64 m_frameCount; // how many frames we've provided
  150. std::vector<__uint8> m_shortSend; // used to keep a copy of the data from short sends
  151. // which will be re-inserted into the output buffer
  152. // before processing more audio data to the output.
  153. std::vector<__uint8> m_remainder;
  154. std::vector<__uint8> m_output;
  155. };
  156. #pragma pack(pop)
  157. #endif