VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ghttpclientparser.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 ghttpclientparser.h
19 ///
20 
21 #ifndef G_HTTP_CLIENT_PARSER__H
22 #define G_HTTP_CLIENT_PARSER__H
23 
24 #include "gdef.h"
25 #include "gnet.h"
26 #include "gstrings.h"
27 #include <string>
28 #include <utility>
29 #include <map>
30 
31 namespace GNet
32 {
33  class HttpClientParser ;
34 }
35 
36 /// \class GNet::HttpClientParser
37 /// A parser for HTTP responses received from a remote server. Also works
38 /// for RTSP.
39 ///
40 /// The response is structured as a status line, followed by an optional
41 /// set of headers, then a blank line, and then the optional body.
42 ///
43 /// Data is added incrementally with apply(), and gotHeaders() and gotBody()
44 /// indicate how complete the response is.
45 ///
46 /// The body can be multi-part, as indicated by headerMultipart(). Multi-part
47 /// streams can be be unending, so individual parts should normally be
48 /// cleared once they have been processed (see gotPart(), partData()
49 /// and clearPart()).
50 ///
52 {
53 public:
54  explicit HttpClientParser( const std::string & protocol = std::string() ) ;
55  ///< Constructor. The protocol defaults to "HTTP".
56 
57  void apply( const char * p , size_t n ) ;
58  ///< Adds some data.
59 
60  void clear() ;
61  ///< Clears the contents, returning the object to a newly-constructed
62  ///< state. This is preferable to destruction and construction because
63  ///< the internal receive buffer can be large.
64 
65  bool gotHeaders() const ;
66  ///< Returns true if headers are complete.
67 
68  size_t headerCount() const ;
69  ///< Returns the number of headers.
70 
71  bool responseOk() const ;
72  ///< Returns true for a 2xx response.
73 
74  bool responseRetry() const ;
75  ///< Returns true for a 503 response.
76 
77  bool responseUnauthorised() const ;
78  ///< Returns true for a "401 Unauthorized" response.
79 
80  int responseValue() const ;
81  ///< Returns the response value (eg. 200), or minus one.
82 
83  std::vector<size_t> headers( const std::string & header_key ) const ;
84  ///< Returns the indexes for the headers with the given key.
85 
86  std::string header( const std::string & header_key , const std::string & default_ = std::string() ) const ;
87  ///< Returns the value of the given header. If the header
88  ///< is repeated then only the first one is relevant.
89 
90  std::string header( size_t index , const std::string & default_ = std::string() ) const ;
91  ///< Overload using the header index.
92 
93  int headerValue( const std::string & header_key , int default_ = -1 ) const ;
94  ///< Returns the integer value of a numeric header.
95 
96  int headerValue( size_t header_index , int default_ = -1 ) const ;
97  ///< Overload using the header index.
98 
99  std::string headerWord( const std::string & header_key , const std::string & default_ = std::string() ) const ;
100  ///< Returns the first part of the header with the given key.
101 
102  std::string headerWord( size_t header_index , const std::string & default_ = std::string() ) const ;
103  ///< Overload using the header index.
104 
105  std::string headerAttribute( const std::string & header_key , const std::string & attribute_key ,
106  const std::string & default_ = std::string() ) const ;
107  ///< Returns a named attribute of the specified header.
108 
109  std::string headerAttribute( size_t header_index , const std::string & attribute_key ,
110  const std::string & default_ = std::string() ) const ;
111  ///< Overload using the header index.
112 
113  std::string headerContentType() const ;
114  ///< Returns the value of the "Content-Type" header.
115 
116  size_t headerContentLength() const ;
117  ///< Returns the value of the "Content-Length" header.
118  ///< Returns zero on error.
119 
120  void clearPart() ;
121  ///< Clears the current multipart body part.
122 
123  bool gotBody() const ;
124  ///< Returns true if the body is complete.
125 
126  std::string body() const ;
127  ///< Returns the body data.
128  ///< Precondition: gotBody()
129 
130  const char * bodyData() const ;
131  ///< Returns the body data.
132  ///< Precondition: gotBody()
133 
134  size_t bodySize() const ;
135  ///< Returns the body size.
136  ///< Precondition: gotBody()
137 
138  bool headerMultipart() const ;
139  ///< Returns true if the main body is of type "multipart".
140 
141  bool gotPart() const ;
142  ///< Returns true if a multipart part is complete.
143 
144  std::string partType() const ;
145  ///< Returns the content-type of the part.
146  ///< Precondition: gotPart()
147 
148  const char * partData() const ;
149  ///< Returns the part data.
150  ///< Precondition: gotPart()
151 
152  size_t partSize() const ;
153  ///< Returns the part size.
154  ///< Precondition: gotPart()
155 
156  std::string responseSummary() const ;
157  ///< Returns a summary of the response for debugging and error reporting.
158 
159 private:
160  struct ResponseStatusInfo
161  {
162  ResponseStatusInfo() ;
163  bool ok ;
164  int value ;
165  bool unauthorised ;
166  unsigned int retry ; // 503, Retry-After
167  } ;
168  struct HeaderInfo
169  {
170  std::string m_line ; // "Foo: bar; one,two three=x"
171  std::string m_lhs ; // "Foo"
172  std::string m_rhs ; // "bar; one,two three=x"
173  std::string m_value ; // "bar"
174  G::StringArray m_tokens ; // "one", "two", "three=x"
175  explicit HeaderInfo( const std::string & line_ ) ;
176  bool match( const std::string & key ) const ; // m_lhs, case-insensitive
177  int value( int default_ ) const ; // m_value as int
178  } ;
179  struct PartInfo
180  {
181  PartInfo() : start(0U) , headersize(0U) , bodysize(0U) {}
182  size_t start ; // dash-dash-boundary position in main data buffer
183  size_t headersize ; // header size, including dash-dash-boundary and blank line
184  size_t bodysize ; // payload size
185  std::string type ; // content-type
186  } ;
187  typedef std::vector<HeaderInfo> List ;
188  static List::const_iterator hfind( const List & , const std::string & ) ;
189  static List::const_iterator hfind( const List & , size_t ) ;
190  static List headerInfo( const std::string & ) ;
191  static ResponseStatusInfo responseStatusInfo( const std::string & , const std::string & ) ;
192  PartInfo partInfo() const ;
193  std::string headerMultipartBoundary() const ;
194  std::string headerAttribute( List::const_iterator , const std::string & , const std::string & ) const ;
195 
196 private:
197  std::string m_data ;
198  std::string m_http ;
199  std::string::size_type m_sep ;
200  List m_hlist ;
201  ResponseStatusInfo m_response_status ;
202 } ;
203 
204 #endif
std::string header(const std::string &header_key, const std::string &default_=std::string()) const
Returns the value of the given header.
bool gotBody() const
Returns true if the body is complete.
std::vector< size_t > headers(const std::string &header_key) const
Returns the indexes for the headers with the given key.
int headerValue(const std::string &header_key, int default_=-1) const
Returns the integer value of a numeric header.
size_t headerCount() const
Returns the number of headers.
std::string headerContentType() const
Returns the value of the "Content-Type" header.
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
bool responseUnauthorised() const
Returns true for a "401 Unauthorized" response.
std::string headerWord(const std::string &header_key, const std::string &default_=std::string()) const
Returns the first part of the header with the given key.
bool gotPart() const
Returns true if a multipart part is complete.
bool responseOk() const
Returns true for a 2xx response.
A parser for HTTP responses received from a remote server.
std::string partType() const
Returns the content-type of the part.
bool gotHeaders() const
Returns true if headers are complete.
void clear()
Clears the contents, returning the object to a newly-constructed state.
bool headerMultipart() const
Returns true if the main body is of type "multipart".
bool responseRetry() const
Returns true for a 503 response.
void clearPart()
Clears the current multipart body part.
size_t headerContentLength() const
Returns the value of the "Content-Length" header.
int responseValue() const
Returns the response value (eg. 200), or minus one.
size_t partSize() const
Returns the part size.
HttpClientParser(const std::string &protocol=std::string())
Constructor. The protocol defaults to "HTTP".
std::string headerAttribute(const std::string &header_key, const std::string &attribute_key, const std::string &default_=std::string()) const
Returns a named attribute of the specified header.
std::string responseSummary() const
Returns a summary of the response for debugging and error reporting.
const char * partData() const
Returns the part data.
std::string body() const
Returns the body data.
void apply(const char *p, size_t n)
Adds some data.
const char * bodyData() const
Returns the body data.
size_t bodySize() const
Returns the body size.