2 // Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #define __HANDLER_H__ 1
23 #include <boost/cstdint.hpp>
24 #include <boost/thread/mutex.hpp>
25 #include <boost/shared_ptr.hpp>
26 #include <boost/shared_array.hpp>
27 #include <boost/scoped_ptr.hpp>
28 //#include <boost/thread/condition.hpp>
34 # include <sys/poll.h>
37 # include <sys/epoll.h>
47 #include "dsodefs.h" //For DSOEXPORT.
50 #include "diskstream.h"
51 #include "sharedlib.h"
52 #include "extension.h"
53 #include "diskstream.h"
60 // _definst_ is the default instance name
64 // The number of disk streams in the array.
65 const size_t STREAMS_BLOCK
= 1000;
71 class Handler
: public gnash::Extension
, gnash::Network
75 /// The Admin command sent by the client
84 /// This enum contains the possible values for streaming video
91 /// This typedef is only used for the io function that must be
92 /// supported by the plugin.
93 typedef size_t (*cygnal_io_write_t
)(boost::uint8_t *data
, size_t size
);
94 typedef boost::shared_ptr
<cygnal::Buffer
> (*cygnal_io_read_t
)();
97 std::string description
;
100 cygnal_io_read_t read_func
;
101 cygnal_io_write_t write_func
;
102 gnash::Network::protocols_supported_e protocol
;
105 /// This typedef is only used for the init function optionally
106 /// supported by the plugin.
107 typedef boost::shared_ptr
<cygnal_init_t
>(*cygnal_io_init_t
)(boost::shared_ptr
<gnash::RTMPMsg
> &msg
);
113 /// Send the onSync message to all connected clients
114 bool sync() { return sync(_in_fd
); };
115 bool sync(int in_fd
);
117 // Access the name field
118 void setName(const std::string
&x
) { _name
= x
; };
119 std::string
&getName() { return _name
; }
121 // Check the status of active disk streams, which is one less than
122 // default as the Streams IDs start at 1.
123 int getActiveDiskStreams() { return _diskstreams
.size(); }
124 // int removeDiskStream(boost::shared_ptr<DiskStream> x);
126 // Operate on a disk streaming inprogress
127 boost::shared_ptr
<gnash::DiskStream
> getDiskStream(int x
) { return _diskstreams
[x
]; }
128 void setDiskStream(int x
, boost::shared_ptr
<gnash::DiskStream
> y
) { _diskstreams
[x
] = y
; }
130 /// Add a SharedObject
131 void addSOL(boost::shared_ptr
<cygnal::Element
> x
) {
135 /// \method addClient
136 /// Add a client to the list for output messages for a
137 /// resource. This also specifies the protocol handler
138 /// required for data on this file descriptor.
139 size_t addClient(int fd
, gnash::Network::protocols_supported_e proto
);
140 /// \method removeClient
141 /// Remove a client from the list for messages.
142 void removeClient(int fd
);
144 /// Get the vector of file descriptors for this handler.
145 std::vector
<int> &getClients() { return _clients
; };
147 /// Get a client from the list of clients, we have too many
148 /// arrays so using an operator isn't useful.
149 int getClient(int x
) { return _clients
[x
]; };
151 /// \brief Receive a message from the other end of the network connection.
153 /// @param fd The file descriptor to read from
155 /// @return The number of bytes sent
158 gnash::Network::protocols_supported_e
getProtocol(int x
) { return _protocol
[x
]; };
159 void setProtocol(int fd
, gnash::Network::protocols_supported_e x
) { _protocol
[fd
] = x
; };
161 /// \method addRemote
162 /// Add a remote machine to the list for input messages.
163 size_t addRemote(int x
) { _remote
.push_back(x
); return _remote
.size(); };
165 void setPlugin(boost::shared_ptr
<Handler::cygnal_init_t
> &init
);
166 void setPlugin(Handler::cygnal_io_read_t read_ptr
, Handler::cygnal_io_write_t write_ptr
);
168 /// Initialize the named module within Cygnal
170 boost::shared_ptr
<cygnal_init_t
> initModule(const std::string
& module
);
172 /// \method initialized
173 /// See if any of the cgi-bins has been loaded.
176 /// This method reads raw data from a plugin.
177 boost::shared_ptr
<cygnal::Buffer
> readFromPlugin();
179 /// This method writes raw data to a plugin.
180 size_t writeToPlugin(cygnal::Buffer
&buf
) {
181 return writeToPlugin(buf
.begin(), buf
.allocated()); };
182 size_t writeToPlugin(boost::uint8_t *data
, size_t size
);
184 // These methods handle control of the file streaming, and are
185 // used by both HTTP and RTMP*
187 /// \fn int createStream()
188 double createStream(double transid
);
189 /// \overload int createStream(const std::string &filespec)
190 /// @param filespec The spec of the file to stream
191 double createStream(double transid
, const std::string
&filespec
);
194 /// Play the specified file as a stream
196 /// \overload int playStream(const std::string &filespec)
197 bool playStream(const std::string
&filespec
);
199 // Publish a live RTMP stream
201 int publishStream(const std::string
&filespec
, pub_stream_e op
);
203 // Seek within the RTMP stream
205 int seekStream(int offset
);
207 // Pause the RTMP stream
208 int pauseStream(double transid
);
210 // Find a stream in the vector or Disk Streams
211 boost::shared_ptr
<gnash::DiskStream
> findStream(const std::string
&filespec
);
213 // Pause the RTMP stream
214 int togglePause(double);
216 // Resume the paused RTMP stream
217 double resumeStream(double transid
);
219 // Close the RTMP stream
220 double closeStream(double transid
);
222 // Delete the RTMP stream
223 double deleteStream(double transid
);
225 // This is a site specific identifier of some kind.
226 void setFCSubscribe(const std::string
&x
) { _fcsubscribe
= x
; };
227 std::string
&getFCSubscribe() { return _fcsubscribe
; }
230 // FIXME: This holds the data from the first NetConnection packet,
231 // and shouldn't really be done here, but we're trying not to
232 // break things while refactoring.
233 void setNetConnection(gnash::RTMPMsg
*msg
) { _netconnect
.reset(msg
); };
234 void setNetConnection(boost::shared_ptr
<gnash::RTMPMsg
> msg
) { _netconnect
= msg
; };
235 boost::shared_ptr
<gnash::RTMPMsg
> getNetConnection() { return _netconnect
;};
239 boost::shared_ptr
<HTTPServer
> &getHTTPHandler(int fd
) { return _http
[fd
]; };
240 boost::shared_ptr
<RTMPServer
> getRTMPHandler(int fd
) { return _rtmp
[fd
]; };
243 // Parse the first nessages when starting a new message handler,
244 // which is used to determine the name of the resource to
245 // initialize, or load from the cache.
246 cygnal::Buffer
*parseFirstRequest(int fd
, gnash::Network::protocols_supported_e proto
);
248 std::string
&getKey(int x
) { return _keys
[x
]; };
249 void setKey(int fd
, std::string x
) { _keys
[fd
] = x
; };
251 // Dump internal data.
256 /// The name of the path this handler is supporting.
258 /// Each incoming request has one of 4 states the server has
259 /// to handle to send a response.
261 /// This is a counter of how many streams have been allocated
264 /// \var _diskstreams
265 /// This is all the opened disk based files that are currently
266 /// being streamed by the server.
267 // boost::shared_array<gnash::DiskStream> _diskstreams;
268 std::map
<int, boost::shared_ptr
<gnash::DiskStream
> > _diskstreams
;
270 /// this is the map of which protocol is being used by which
272 std::map
<int, gnash::Network::protocols_supported_e
> _protocol
;
274 std::map
<int, boost::shared_ptr
<HTTPServer
> > _http
;
275 std::map
<int, boost::shared_ptr
<RTMPServer
> > _rtmp
;
278 /// is the array of all clients connected to this server for
279 /// this application. This is where all the output goes.
280 std::vector
<int> _clients
;
282 /// This is network connections to other processes,
283 /// on other computers.
284 std::vector
<int> _remote
;
287 /// These are local process we're responsible for
288 /// starting and stopping.
289 boost::shared_ptr
<cygnal::Proc
> _local
;
291 /// is for the dynamically loaded applications
292 boost::shared_ptr
<cygnal_init_t
> _plugin
;
294 /// is for disk based files
295 std::vector
<boost::shared_ptr
<gnash::DiskStream
> > _files
;
297 /// is for remote SharedObjects
298 std::vector
<boost::shared_ptr
<cygnal::Element
> > _sol
;
300 /// is to store the body size of the previous packet for this
301 /// channel. 4 and 1 byte heades don't use the length field,
302 /// they just use the previous vaue for this field.
303 std::map
<int, size_t> _bodysize
;
305 /// The file descriptor of the incoming data for an
309 /// \var _fcssubscribe
310 /// This is a string sometimes sent by the client with what
311 /// appears to be a unique ID number.
312 std::string _fcsubscribe
;
316 /// This store the data from the NetConnection ActionScript
317 /// object we get as the final part of the handshake process
318 /// that is used to set up the connection. This has all the
319 /// file paths and other information needed by the server.
320 boost::shared_ptr
<gnash::RTMPMsg
> _netconnect
;
323 std::map
<int, std::string
> _keys
;
327 // Remote Shared Objects. References are an index into this vector.
328 // std::map<std::string, boost::shared_ptr<handler_t> > _handlers;
331 } // end of gnash namespace
333 #endif // end of __HANDLER_H__
337 // indent-tabs-mode: t