httprequest.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2005 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 
30 #ifndef TNT_HTTPREQUEST_H
31 #define TNT_HTTPREQUEST_H
32 
33 #include <tnt/httpmessage.h>
34 #include <tnt/httpheader.h>
35 #include <tnt/socketif.h>
36 #include <tnt/contenttype.h>
37 #include <tnt/multipart.h>
38 #include <tnt/cookie.h>
39 #include <tnt/encoding.h>
40 #include <tnt/query_params.h>
41 #include <tnt/scope.h>
42 #include <tnt/threadcontext.h>
43 #include <locale>
44 #include <map>
45 #include <cxxtools/atomicity.h>
46 #include <string>
47 #include <cstring>
48 
49 namespace tnt
50 {
51  class Sessionscope;
52  class Tntnet;
53 
55  class HttpRequest : public HttpMessage
56  {
57  friend class SessionUnlocker;
58  friend class ApplicationUnlocker;
59 
60  public:
61  // forward declaration of subclass defined in httpparser.h
62  class Parser;
63 
64  typedef std::map<std::string, std::string> args_type;
65 
66  private:
67  std::string _body;
68  unsigned _methodLen;
69  char _method[8];
70  std::string _url;
71  std::string _queryString;
72 
73  size_t _contentSize;
74 
75  std::string _pathinfo;
76  args_type _args;
77  tnt::QueryParams _getparam;
78  tnt::QueryParams _postparam;
79  tnt::QueryParams _qparam;
80 
81  const SocketIf* _socketIf;
82 
83  mutable Contenttype _ct;
84  Multipart _mp;
85  cxxtools::atomic_t _serial;
86  static cxxtools::atomic_t _nextSerial;
87  mutable bool _localeInit;
88  mutable std::string _lang;
89 
90  mutable Encoding _encoding;
91  mutable bool _encodingRead;
92 
93  mutable std::string _username;
94  mutable std::string _password;
95 
96  Scope* _requestScope;
97  Scope* _applicationScope;
98  Sessionscope* _sessionScope;
99  Sessionscope* _secureSessionScope;
100  ThreadContext* _threadContext;
101 
102  bool _applicationScopeLocked;
103  bool _sessionScopeLocked;
104  bool _secureSessionScopeLocked;
105 
106  mutable std::string _peerAddrStr;
107  mutable std::string _serverAddrStr;
108 
109  Tntnet& _application;
110 
111  void ensureApplicationScopeLock();
112  void ensureSessionScopeLock();
113 
114  void releaseApplicationScopeLock();
115  void releaseSessionScopeLock();
116 
117  void releaseLocks() { releaseApplicationScopeLock(); }
118 
119  const Contenttype& getContentTypePriv() const;
120 
121  public:
122  explicit HttpRequest(Tntnet& application, const SocketIf* socketIf = 0);
123  HttpRequest(Tntnet& application, const std::string& url, const SocketIf* socketIf = 0);
124  HttpRequest(const HttpRequest& r);
125  ~HttpRequest();
126 
128 
129  void clear();
130 
132  const std::string& getBody() const { return _body; }
133 
135  void setBody(const std::string& body) { _body = body; }
136 
139  std::string getMethod() const { return _method; }
140  const char* getMethod_cstr() const { return _method; }
142 
144  bool isMethodGET() const { return std::strcmp(_method, "GET") == 0; }
145 
147  bool isMethodPOST() const { return std::strcmp(_method, "POST") == 0; }
148 
150  bool isMethodHEAD() const { return std::strcmp(_method, "HEAD") == 0; }
151 
153  void setMethod(const char* _method);
154 
156  std::string getQuery() const
157  { return _queryString.empty() ? _url : _url + '?' + _queryString; }
158 
160  const std::string& getUrl() const { return _url; }
161 
163  const std::string& getQueryString() const { return _queryString; }
164 
166  void setQueryString(const std::string& queryString)
167  { _queryString = queryString; }
168 
169  void setPathInfo(const std::string& p) { _pathinfo = p; }
170  const std::string& getPathInfo() const { return _pathinfo; }
171 
172  void setArgs(const args_type& a) { _args = a; }
173  const args_type& getArgs() const { return _args; }
174  args_type& getArgs() { return _args; }
175 
178  std::string getArgDef(args_type::size_type n, const std::string& def = std::string()) const;
179  std::string getArg(args_type::size_type n) const { return getArgDef(n); }
180  args_type::size_type getArgsCount() const { return _args.size(); }
182 
183  std::string getArg(const std::string& name, const std::string& def = std::string()) const;
184 
185  void parse(std::istream& in);
186  void doPostParse();
187 
190  tnt::QueryParams& getQueryParams() { return _qparam; }
191  const tnt::QueryParams& getQueryParams() const { return _qparam; }
193 
195  const tnt::QueryParams& getGetParams() const { return _getparam; }
196 
198  const tnt::QueryParams& getPostParams() const { return _postparam; }
199 
201  void setQueryParams(const tnt::QueryParams& q) { _qparam = q; }
202 
204  std::string getPeerIp() const { return _socketIf ? _socketIf->getPeerIp() : std::string(); }
205 
207  std::string getServerIp() const { return _socketIf ? _socketIf->getServerIp() : std::string(); }
208 
210  bool isSsl() const { return _socketIf && _socketIf->isSsl(); }
211 
213  { return _ct.getType().empty() && hasHeader(httpheader::contentType) ? getContentTypePriv() : _ct; }
214  bool isMultipart() const { return getContentType().isMultipart(); }
215  const Multipart& getMultipart() const { return _mp; }
216 
217  cxxtools::atomic_t getSerial() const { return _serial; }
218 
219  const std::locale& getLocale() const;
220  const std::string& getLang() const
221  {
222  if (!_localeInit)
223  getLocale();
224  return _lang;
225  }
226 
227  void setLocale(const std::locale& loc);
228  void setLang(const std::string& lang);
229 
230  const Cookies& getCookies() const;
231 
232  bool hasCookie(const std::string& name) const
233  { return getCookies().hasCookie(name); }
234  bool hasCookies() const
235  { return getCookies().hasCookies(); }
236  Cookie getCookie(const std::string& name) const
237  { return getCookies().getCookie(name); }
238 
239  const Encoding& getEncoding() const;
240 
242  const char* getUserAgent() const
243  { return getHeader(httpheader::userAgent); }
244 
246  const char* getHost() const
247  { return getHeader(httpheader::host); }
248 
250  const std::string& getUsername() const;
251 
253  const std::string& getPassword() const;
254 
256  bool verifyPassword(const std::string& password) const;
257 
258  bool keepAlive() const;
259 
261  bool acceptGzipEncoding() const { return getEncoding().accept("gzip"); }
262 
263  void setApplicationScope(Scope* s);
265 
266  void setSessionScope(Sessionscope* s);
270 
271  void setThreadContext(ThreadContext* ctx) { _threadContext = ctx; }
272 
278  bool hasSessionScope() const;
279  bool hasSecureSessionScope() const;
280 
282  size_t getContentSize() const
283  { return _contentSize; }
284 
286  std::string getVirtualHost() const
287  { return getHeader(httpheader::host); }
288 
290  { return _application; }
291 
293  void touch() { _threadContext->touch(); }
294 
295  static void postRunCleanup();
296  };
297 
298  inline std::istream& operator>> (std::istream& in, HttpRequest& msg)
299  { msg.parse(in); return in; }
300 }
301 
302 #endif // TNT_HTTPREQUEST_H
303