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  public:
58  class Parser;
59  friend class Parser;
60  friend class SessionUnlocker;
61  friend class ApplicationUnlocker;
62 
63  typedef std::map<std::string, std::string> args_type;
64 
65  private:
66  std::string body;
67  unsigned methodLen;
68  char method[8];
69  std::string url;
70  std::string queryString;
71 
72  size_t contentSize;
73 
74  std::string pathinfo;
75  args_type args;
76  tnt::QueryParams getparam;
77  tnt::QueryParams postparam;
78  tnt::QueryParams qparam;
79 
80  const SocketIf* socketIf;
81 
82  mutable Contenttype ct;
83  Multipart mp;
84  cxxtools::atomic_t serial;
85  static cxxtools::atomic_t serial_;
86  mutable bool locale_init;
87  mutable std::string lang;
88  mutable std::locale locale;
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  void ensureApplicationScopeLock();
107  void ensureSessionScopeLock();
108 
109  void releaseApplicationScopeLock();
110  void releaseSessionScopeLock();
111 
112  void releaseLocks() { releaseApplicationScopeLock(); }
113 
114  mutable std::string peerAddrStr;
115  mutable std::string serverAddrStr;
116 
117  const Contenttype& getContentTypePriv() const;
118  Tntnet& application;
119 
120  public:
121  explicit HttpRequest(Tntnet& application_, const SocketIf* socketIf = 0);
122  HttpRequest(Tntnet& application_, const std::string& url, const SocketIf* socketIf = 0);
123  HttpRequest(const HttpRequest& r);
124  ~HttpRequest();
125 
127 
128  void clear();
129 
131  const std::string& getBody() const { return body; }
133  void setBody(const std::string& body_) { body = body_; }
135  std::string getMethod() const { return method; }
136  const char* getMethod_cstr() const { return method; }
137  bool isMethodGET() const { return std::strcmp(method, "GET") == 0; }
138  bool isMethodPOST() const { return std::strcmp(method, "POST") == 0; }
139  bool isMethodHEAD() const { return std::strcmp(method, "HEAD") == 0; }
141  void setMethod(const char* method);
142 
144  std::string getQuery() const
145  { return queryString.empty() ? url : url + '?' + queryString; }
147  const std::string& getUrl() const { return url; }
149  const std::string& getQueryString() const { return queryString; }
151  void setQueryString(const std::string& queryString_)
152  { queryString = queryString_; }
153 
154  void setPathInfo(const std::string& p) { pathinfo = p; }
155  const std::string& getPathInfo() const { return pathinfo; }
156 
157  void setArgs(const args_type& a) { args = a; }
158  const args_type& getArgs() const { return args; }
159  args_type& getArgs() { return args; }
160 
162  std::string getArgDef(args_type::size_type n, const std::string& def = std::string()) const;
164  std::string getArg(args_type::size_type n) const { return getArgDef(n); }
166  args_type::size_type getArgsCount() const { return args.size(); }
167 
168  std::string getArg(const std::string& name, const std::string& def = std::string()) const;
169 
170  void parse(std::istream& in);
171  void doPostParse();
172 
173  tnt::QueryParams& getQueryParams() { return qparam; }
174  const tnt::QueryParams& getQueryParams() const { return qparam; }
175  const tnt::QueryParams& getGetParams() const { return getparam; }
176  const tnt::QueryParams& getPostParams() const { return postparam; }
177  void setQueryParams(const tnt::QueryParams& q) { qparam = q; }
178 
179  std::string getPeerIp() const { return socketIf ? socketIf->getPeerIp() : std::string(); }
180  std::string getServerIp() const { return socketIf ? socketIf->getServerIp() : std::string(); }
181  bool isSsl() const { return socketIf && socketIf->isSsl(); }
182 
184  { return ct.getType().empty() && hasHeader(httpheader::contentType) ? getContentTypePriv() : ct; }
185  bool isMultipart() const { return getContentType().isMultipart(); }
186  const Multipart& getMultipart() const { return mp; }
187 
188  cxxtools::atomic_t getSerial() const { return serial; }
189 
190  const std::locale& getLocale() const;
191  const std::string& getLang() const
192  {
193  if (!locale_init)
194  getLocale();
195  return lang;
196  }
197  void setLocale(const std::locale& loc);
198  void setLang(const std::string& lang);
199 
200  const Cookies& getCookies() const;
201 
202  bool hasCookie(const std::string& name) const
203  { return getCookies().hasCookie(name); }
204  bool hasCookies() const
205  { return getCookies().hasCookies(); }
206  Cookie getCookie(const std::string& name) const
207  { return getCookies().getCookie(name); }
208 
209  const Encoding& getEncoding() const;
210  const char* getUserAgent() const
211  { return getHeader(httpheader::userAgent); }
212  const char* getHost() const
213  { return getHeader(httpheader::host); }
214 
215  const std::string& getUsername() const;
216  const std::string& getPassword() const;
217  bool verifyPassword(const std::string& password) const;
218 
219  bool keepAlive() const;
220  bool acceptGzipEncoding() const { return getEncoding().accept("gzip"); }
221 
222  void setApplicationScope(Scope* s);
224 
225  void setSessionScope(Sessionscope* s);
229  void clearSession();
230 
231  void setThreadContext(ThreadContext* ctx) { threadContext = ctx; }
232 
238  bool hasSessionScope() const;
239  bool hasSecureSessionScope() const;
240 
242  size_t getContentSize() const
243  { return contentSize; }
244 
246  std::string getVirtualHost() const
247  { return getHeader(httpheader::host); }
248 
250  { return application; }
251 
253  void touch() { threadContext->touch(); }
254 
255  static void postRunCleanup();
256  };
257 
258  inline std::istream& operator>> (std::istream& in, HttpRequest& msg)
259  { msg.parse(in); return in; }
260 
261 }
262 
263 #endif // TNT_HTTPREQUEST_H