VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gvhttpserver.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
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.
8 //
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.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gvhttpserver.h
19 ///
20 
21 #ifndef GV_HTTPSERVER__H
22 #define GV_HTTPSERVER__H
23 
24 #include "gdef.h"
25 #include "gvimageinput.h"
26 #include "gdatetime.h"
27 #include "gaddress.h"
28 #include "gurl.h"
29 #include "gpath.h"
30 #include <string>
31 #include <memory>
32 #include <vector>
33 #include <utility>
34 
35 namespace Gv
36 {
37  class HttpServerSource ;
38  class HttpServerSources ;
39  class HttpServerConfig ;
40  class HttpServerResources ;
41  class HttpServerInput ;
42 }
43 
44 /// \class Gv::HttpServerInput
45 /// An ImageInput class that integrates with the event loop, with automatic
46 /// re-opening if the channel goes away for a while.
47 ///
49 {
50 public:
51  HttpServerInput( Gr::ImageConverter & , const std::string & channel_name , unsigned int reopen_timeout ) ;
52  ///< Constructor taking a channel name.
53 
54  virtual ~HttpServerInput() ;
55  ///< Destructor.
56 
57  void start() ;
58  ///< Starts the input.
59 
60 private:
61  HttpServerInput( const HttpServerInput & ) ;
62  void operator=( const HttpServerInput & ) ;
63  void attach() ;
64  void detach() ;
65  virtual void onException( std::exception & ) override ; // GNet::EventExceptionHandler
66  virtual void readEvent() override ; // GNet::EventHandler
67  void onTimeout() ;
68 
69 private:
70  int m_fd ;
71  unsigned int m_reopen_timeout ;
72  GNet::Timer<HttpServerInput> m_reopen_timer ;
73 } ;
74 
75 /// \class Gv::HttpServerSource
76 /// Used by a ImageInputHandler-derived object to hold a ImageInputSource
77 /// pointer. The pointer is normally set() by HttpServerSources::select().
78 ///
80 {
81 public:
82  explicit HttpServerSource( ImageInputHandler & ) ;
83  ///< Constructor.
84 
86  ///< Destructor.
87 
88  std::string name() const ;
89  ///< Returns the source name. In practice this is likely
90  ///< to be the channel name or the camera device name.
91 
92  std::string info() const ;
93  ///< Returns information on the channel publisher, or the
94  ///< empty string for non-channel sources.
95 
96  void resend() ;
97  ///< Calls resend() on the source.
98 
99  ImageInputSource * get() ;
100  ///< Returns the source pointer.
101 
102  bool set( ImageInputSource * , const std::string & info ) ;
103  ///< Sets the source pointer. Used by Gv::HttpServerSources.
104 
105 private:
107  void operator=( const HttpServerSource & ) ;
108 
109 private:
110  ImageInputHandler & m_handler ;
111  ImageInputSource * m_source ;
112  std::string m_info ;
113 } ;
114 
115 /// \class Gv::HttpServerSources
116 /// A container for ImageInputSource pointers, used by Gv::HttpServerPeer.
117 /// Image sources can be publication channels or not (cf. httpserver
118 /// vs. webcamplayer). Consequently the pointers are actually pairs of
119 /// pointers; one pointing to the base class, and the other possibly-null
120 /// pointer pointing at the channel-specific derived class.
121 ///
123 {
124 public:
126  unsigned int channel_reopen_timeout ) ;
127  ///< Constructor. The converter reference is kept. The resources
128  ///< object simply provides a list of channel names.
129 
131  ///< Constructor for a single non-channel source, typically
132  ///< a Gv::Camera reference. The references are kept,
133  ///< with no transfer of ownership.
134 
136  ///< Destructor.
137 
138  bool valid( const std::string & url_path ) ;
139  ///< Returns true if the given url path looks like it is for
140  ///< an input-source rather than a file.
141 
142  bool select( const std::string & url_path , HttpServerSource & ) ;
143  ///< Looks up the required input source and deposits its pointer
144  ///< into the supplied holder. Returns true if the source changes.
145 
147  ///< Returns the image-converter reference, as passed in to the
148  ///< constructor.
149 
150 private:
151  typedef std::pair<ImageInputSource*,HttpServerInput*> Pair ;
153  void operator=( const HttpServerSources & ) ;
154  Pair findByName( const std::string & ) ;
155  Pair findByNumber( size_t ) ;
156  bool addChannel( const std::string & , bool do_throw ) ;
157 
158 private:
159  Gr::ImageConverter & m_converter ;
160  const HttpServerResources * m_resources ;
161  std::vector<Pair> m_list ;
162  unsigned int m_reopen_timeout ;
163 } ;
164 
165 /// \class Gv::HttpServerResources
166 /// A configuration structure for resources that Gv::HttpServerPeer makes
167 /// available.
168 ///
170 {
171 public:
173  ///< Default constructor.
174 
175  void setDirectory( const G::Path & ) ;
176  ///< Sets a directory for file resources.
177 
178  void addFileAny() ;
179  ///< Allow any file in the directory.
180 
181  std::string addFile( const G::Path & ) ;
182  ///< Adds a file resource. Returns the empty string
183  ///< or a failure reason.
184 
185  void addFileType( const G::Path & , const std::string & type ) ;
186  ///< Adds a filename-to-type mapping that overrides
187  ///< the extension mapping.
188 
189  void addChannel( const std::string & channel_name ) ;
190  ///< Adds a channel resource.
191 
192  void addChannelAny() ;
193  ///< Adds the wildcard channel.
194 
195  std::string setDefault( const std::string & ) ;
196  ///< Sets the default resource. Returns a warning string.
197 
198  bool empty() const ;
199  ///< Returns true if just default-constructed with no
200  ///< "add" or "set" methods called.
201 
202  std::vector<std::string> channels() const ;
203  ///< Returns a list of added channel names.
204 
205  bool anyChannel() const ;
206  ///< Returns true if addChannelAny() called.
207 
208  bool fileResource( const G::Path & url_path ) const ;
209  ///< Returns true if the url path is for a file (eg. "/index.html").
210 
211  bool channelResource( const G::Path & url_path ) const ;
212  ///< Returns true if the url path is for a channel (eg. "/_foo").
213 
214  bool specialResource( const G::Path & url_path ) const ;
215  ///< Returns true if the url path is for a special resource (eg. "/__").
216 
217  std::string fileResourcePath( const G::Path & url_path ) const ;
218  ///< Returns the file-system path for the given url path, or the
219  ///< empty string if there is no matching resource map entry.
220  ///< Precondition: fileResource(url_path)
221 
222  std::string fileResourceType( const G::Path & url_path ) const ;
223  ///< Returns the content-type path for the given url path, or the
224  ///< empty string if there is no matching resource map entry.
225  ///< Precondition: fileResource(url_path)
226 
227  std::pair<std::string,std::string> fileResourcePair( const G::Path & url_path ) const ;
228  ///< Returns fileResourcePath() and fileResourceType() as a pair.
229  ///< If not a valid fileResourcePath() then the reason is returned
230  ///< in the second part.
231 
232  std::string channelName( const G::Path & url_path ) const ;
233  ///< Returns the channel name for the given channel-like url path.
234  ///< Precondition: channelResource(url_path)
235 
236  static std::string guessType( const G::Path & path ) ;
237  ///< Returns a probable content-type based on the filename,
238  ///< or the empty string.
239 
240  void log() const ;
241  ///< Emits diagnostic logging for the configured resources.
242 
243 private:
244  enum ResourceType
245  {
246  t_file ,
247  t_channel ,
248  t_source ,
249  t_special
250  } ;
252  void operator=( HttpServerResources & ) ;
253  ResourceType resourceType( const G::Path & url_path ) const ;
254  static bool readable( const G::Path & ) ;
255  void log( std::ostream & ) const ;
256  static G::Path normalise( const G::Path & path_in , const std::string & default_ ) ;
257  static G::Path normalise( const G::Path & path_in ) ;
258 
259 private:
260  typedef std::map<std::string,std::string> Map ;
261  G::Path m_dir ;
262  bool m_any_file ;
263  bool m_any_channel ;
264  bool m_with_specials ;
265  std::string m_default_resource ;
266  std::vector<std::string> m_channels ;
267  Map m_files ;
268  Map m_file_types ;
269 } ;
270 
271 /// \class Gv::HttpServerConfig
272 /// A configuration structure for Gv::HttpServerPeer holding default settings
273 /// from the command-line which are then overriden by url parameters.
274 ///
276 {
277 public:
278  HttpServerConfig() ;
279  ///< Default constructor for reasonable default values.
280 
281  void init( unsigned int idle_timeout , unsigned int first_image_timeout , G::EpochTime repeat_timeout ,
282  unsigned int refresh_header ,
283  const GNet::Address & gateway , bool more_verbose ) ;
284  ///< Initialises the configuration from command-line parameters.
285 
286  void init( unsigned int idle_timeout , unsigned int first_image_timeout , G::EpochTime repeat_timeout ,
287  unsigned int refresh_header ,
288  const std::string & type ) ;
289  ///< Initialises the configuration from command-line parameters.
290 
291  void init( const G::Url & ) ;
292  ///< Further initialises the configuration from url parameters.
293 
294  unsigned int idleTimeout() const ;
295  ///< Returns the connection idle timeout. This terminates the
296  ///< connection if no http commands are received, unless
297  ///< streaming.
298 
299  unsigned int firstImageTimeout() const ;
300  ///< Returns the first-image timeout. If no input image is
301  ///< received in this period after the http get request then
302  ///< the get fails with '503 image unavailable'.
303 
305  ///< Returns the repeat timeout. When streaming this is the
306  ///< maximum time spent waiting for a new input image; if nothing
307  ///< is available by then then the old image is resent.
308 
309  bool moreVerbose() const ;
310  ///< Returns true for more verbosity.
311 
312  std::string type() const ;
313  ///< Returns the required content-type.
314 
315  bool quick() const ;
316  ///< Returns true if requesting the most-recent data from the channel rather
317  ///< than waiting for the next update.
318 
319  bool streaming() const ;
320  ///< Returns true if streaming using multipart/x-mixed-replace.
321 
322  GNet::Address gateway() const ;
323  ///< Returns the gateway network address, or the default address if none.
324 
325  int scale() const ;
326  ///< Returns the required scale factor.
327 
328  bool monochrome() const ;
329  ///< Returns the monochrome flag.
330 
331  unsigned int refresh() const ;
332  ///< Returns the value for the http refresh header.
333 
334  bool withStatus() const ;
335  ///< Returns true if the status url is enabled.
336 
337 private:
338  static bool integral( const G::Url & url , const std::string & key ) ;
339 
340 private:
341  bool m_streaming ; // multipart/x-mixed-replace
342  unsigned int m_refresh ; // refresh header value if not streaming
343  std::string m_type ; // jpeg/raw/pnm
344  int m_scale ; // image size scale factor
345  bool m_monochrome ; // greyscale image
346  unsigned int m_idle_timeout ; // input idle timeout
347  unsigned int m_first_image_timeout ; // first-image timeout
348  G::EpochTime m_image_repeat_timeout ; // minimum output frame rate, even if no new input images
349  GNet::Address m_gateway ;
350  bool m_more_verbose ; // log the http protocol
351  bool m_quick ; // start with the most recent image available, even if old
352 } ;
353 
354 #endif
unsigned int refresh() const
Returns the value for the http refresh header.
A configuration structure for Gv::HttpServerPeer holding default settings from the command-line which...
Definition: gvhttpserver.h:275
A subsecond-resolution timestamp based on a time_t.
Definition: gdatetime.h:39
void setDirectory(const G::Path &)
Sets a directory for file resources.
std::string channelName(const G::Path &url_path) const
Returns the channel name for the given channel-like url path.
bool specialResource(const G::Path &url_path) const
Returns true if the url path is for a special resource (eg. "/__").
bool set(ImageInputSource *, const std::string &info)
Sets the source pointer. Used by Gv::HttpServerSources.
~HttpServerSource()
Destructor.
bool withStatus() const
Returns true if the status url is enabled.
bool streaming() const
Returns true if streaming using multipart/x-mixed-replace.
HttpServerInput(Gr::ImageConverter &, const std::string &channel_name, unsigned int reopen_timeout)
Constructor taking a channel name.
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:55
GNet::Address gateway() const
Returns the gateway network address, or the default address if none.
std::string type() const
Returns the required content-type.
void resend()
Calls resend() on the source.
virtual ~HttpServerInput()
Destructor.
A class for reading images from a publication channel and distributing them to multiple client object...
Definition: gvimageinput.h:168
A callback interface for Gv::ImageInputSource.
Definition: gvimageinput.h:84
bool valid(const std::string &url_path)
Returns true if the given url path looks like it is for an input-source rather than a file...
A simple parser for URLs.
Definition: gurl.h:42
void addChannelAny()
Adds the wildcard channel.
Gr::ImageConverter & converter()
Returns the image-converter reference, as passed in to the constructor.
std::string info() const
Returns information on the channel publisher, or the empty string for non-channel sources...
bool fileResource(const G::Path &url_path) const
Returns true if the url path is for a file (eg. "/index.html").
void init(unsigned int idle_timeout, unsigned int first_image_timeout, G::EpochTime repeat_timeout, unsigned int refresh_header, const GNet::Address &gateway, bool more_verbose)
Initialises the configuration from command-line parameters.
bool quick() const
Returns true if requesting the most-recent data from the channel rather than waiting for the next upd...
unsigned int idleTimeout() const
Returns the connection idle timeout.
std::vector< std::string > channels() const
Returns a list of added channel names.
A base class for distributing incoming images to multiple client objects, supporting some simple imag...
Definition: gvimageinput.h:116
HttpServerConfig()
Default constructor for reasonable default values.
std::string fileResourcePath(const G::Path &url_path) const
Returns the file-system path for the given url path, or the empty string if there is no matching reso...
bool empty() const
Returns true if just default-constructed with no "add" or "set" methods called.
std::string fileResourceType(const G::Path &url_path) const
Returns the content-type path for the given url path, or the empty string if there is no matching res...
bool moreVerbose() const
Returns true for more verbosity.
void addFileAny()
Allow any file in the directory.
A base class for classes that handle asynchronous events from the event loop.
Definition: geventhandler.h:78
void addFileType(const G::Path &, const std::string &type)
Adds a filename-to-type mapping that overrides the extension mapping.
Used by a ImageInputHandler-derived object to hold a ImageInputSource pointer.
Definition: gvhttpserver.h:79
G::EpochTime imageRepeatTimeout() const
Returns the repeat timeout.
std::string setDefault(const std::string &)
Sets the default resource. Returns a warning string.
An ImageInput class that integrates with the event loop, with automatic re-opening if the channel goe...
Definition: gvhttpserver.h:48
bool anyChannel() const
Returns true if addChannelAny() called.
HttpServerResources()
Default constructor.
static std::string guessType(const G::Path &path)
Returns a probable content-type based on the filename, or the empty string.
std::pair< std::string, std::string > fileResourcePair(const G::Path &url_path) const
Returns fileResourcePath() and fileResourceType() as a pair.
std::string name() const
Returns the source name.
~HttpServerSources()
Destructor.
A container for ImageInputSource pointers, used by Gv::HttpServerPeer.
Definition: gvhttpserver.h:122
A configuration structure for resources that Gv::HttpServerPeer makes available.
Definition: gvhttpserver.h:169
unsigned int firstImageTimeout() const
Returns the first-image timeout.
An image format converter that can convert to and from the raw and jpeg formats (only), with scaling and monochrome options.
bool select(const std::string &url_path, HttpServerSource &)
Looks up the required input source and deposits its pointer into the supplied holder.
A timer class template in which the timeout is delivered to the specified method. ...
Definition: gtimer.h:110
std::string addFile(const G::Path &)
Adds a file resource.
int scale() const
Returns the required scale factor.
HttpServerSource(ImageInputHandler &)
Constructor.
void addChannel(const std::string &channel_name)
Adds a channel resource.
A Path object represents a file system path.
Definition: gpath.h:72
bool monochrome() const
Returns the monochrome flag.
bool channelResource(const G::Path &url_path) const
Returns true if the url path is for a channel (eg. "/_foo").
void log() const
Emits diagnostic logging for the configured resources.
HttpServerSources(Gr::ImageConverter &, const HttpServerResources &, unsigned int channel_reopen_timeout)
Constructor.
void start()
Starts the input.