00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef TNT_HTTPREQUEST_H
00031 #define TNT_HTTPREQUEST_H
00032
00033 #include <tnt/httpmessage.h>
00034 #include <tnt/httpheader.h>
00035 #include <tnt/socketif.h>
00036 #include <tnt/contenttype.h>
00037 #include <tnt/multipart.h>
00038 #include <tnt/cookie.h>
00039 #include <tnt/encoding.h>
00040 #include <tnt/query_params.h>
00041 #include <tnt/scope.h>
00042 #include <tnt/threadcontext.h>
00043 #include <locale>
00044 #include <vector>
00045 #include <cxxtools/atomicity.h>
00046 #include <string>
00047 #include <cstring>
00048
00049 namespace tnt
00050 {
00051 class Sessionscope;
00052 class Tntnet;
00053
00055 class HttpRequest : public HttpMessage
00056 {
00057 public:
00058 class Parser;
00059 friend class Parser;
00060 friend class SessionUnlocker;
00061 friend class ApplicationUnlocker;
00062
00063 typedef std::vector<std::string> args_type;
00064
00065 private:
00066 std::string body;
00067 unsigned methodLen;
00068 char method[8];
00069 std::string url;
00070 std::string queryString;
00071
00072 size_t contentSize;
00073 static size_t maxRequestSize;
00074
00075 std::string pathinfo;
00076 args_type args;
00077 tnt::QueryParams qparam;
00078
00079 const SocketIf* socketIf;
00080
00081 mutable Contenttype ct;
00082 Multipart mp;
00083 cxxtools::atomic_t serial;
00084 static cxxtools::atomic_t serial_;
00085 mutable bool locale_init;
00086 mutable std::string lang;
00087 mutable std::locale locale;
00088
00089 mutable Encoding encoding;
00090 mutable bool encodingRead;
00091
00092 mutable std::string username;
00093 mutable std::string password;
00094
00095 Scope* requestScope;
00096 Scope* applicationScope;
00097 Sessionscope* sessionScope;
00098 ThreadContext* threadContext;
00099
00100 bool applicationScopeLocked;
00101 bool sessionScopeLocked;
00102
00103 void ensureApplicationScopeLock();
00104 void ensureSessionScopeLock();
00105
00106 void releaseApplicationScopeLock();
00107 void releaseSessionScopeLock();
00108
00109 void releaseLocks() { releaseApplicationScopeLock(); }
00110
00111 mutable std::string peerAddrStr;
00112 mutable std::string serverAddrStr;
00113
00114 const Contenttype& getContentTypePriv() const;
00115 Tntnet& application;
00116
00117 public:
00118 explicit HttpRequest(Tntnet& application_, const SocketIf* socketIf = 0);
00119 HttpRequest(Tntnet& application_, const std::string& url, const SocketIf* socketIf = 0);
00120 HttpRequest(const HttpRequest& r);
00121 ~HttpRequest();
00122
00123 HttpRequest& operator= (const HttpRequest& r);
00124
00125 void clear();
00126
00128 const std::string& getBody() const { return body; }
00130 void setBody(const std::string& body_) { body = body_; }
00132 std::string getMethod() const { return method; }
00133 const char* getMethod_cstr() const { return method; }
00134 bool isMethodGET() const { return std::strcmp(method, "GET") == 0; }
00135 bool isMethodPOST() const { return std::strcmp(method, "POST") == 0; }
00136 bool isMethodHEAD() const { return std::strcmp(method, "HEAD") == 0; }
00138 void setMethod(const char* method);
00139
00141 std::string getQuery() const
00142 { return queryString.empty() ? url : url + '?' + queryString; }
00144 const std::string& getUrl() const { return url; }
00146 const std::string& getQueryString() const { return queryString; }
00148 void setQueryString(const std::string& queryString_)
00149 { queryString = queryString_; }
00150
00151 void setPathInfo(const std::string& p) { pathinfo = p; }
00152 const std::string& getPathInfo() const { return pathinfo; }
00153
00154 void setArgs(const args_type& a) { args = a; }
00155 const args_type& getArgs() const { return args; }
00156 args_type& getArgs() { return args; }
00157
00158 std::string getArgDef(args_type::size_type n,
00159 const std::string& def = std::string()) const
00160 { return args.size() > n ? args[n] : def; }
00161 const std::string& getArg(args_type::size_type n) const
00162 { return args[n]; }
00163 std::string getArg(const std::string& name, const std::string& def = std::string()) const;
00164 args_type::size_type getArgsCount() const { return args.size(); }
00165
00166 void parse(std::istream& in);
00167 void doPostParse();
00168
00169 tnt::QueryParams& getQueryParams() { return qparam; }
00170 const tnt::QueryParams& getQueryParams() const { return qparam; }
00171 void setQueryParams(const tnt::QueryParams& q) { qparam = q; }
00172
00173 std::string getPeerIp() const { return socketIf ? socketIf->getPeerIp() : std::string(); }
00174 std::string getServerIp() const { return socketIf ? socketIf->getServerIp() : std::string(); }
00175 bool isSsl() const { return socketIf && socketIf->isSsl(); }
00176
00177 const Contenttype& getContentType() const
00178 { return ct.getType().empty() && hasHeader(httpheader::contentType) ? getContentTypePriv() : ct; }
00179 bool isMultipart() const { return getContentType().isMultipart(); }
00180 const Multipart& getMultipart() const { return mp; }
00181
00182 cxxtools::atomic_t getSerial() const { return serial; }
00183
00184 const std::locale& getLocale() const;
00185 const std::string& getLang() const
00186 {
00187 if (!locale_init)
00188 getLocale();
00189 return lang;
00190 }
00191 void setLocale(const std::locale& loc);
00192 void setLang(const std::string& lang);
00193
00194 const Cookies& getCookies() const;
00195
00196 bool hasCookie(const std::string& name) const
00197 { return getCookies().hasCookie(name); }
00198 bool hasCookies() const
00199 { return getCookies().hasCookies(); }
00200 Cookie getCookie(const std::string& name) const
00201 { return getCookies().getCookie(name); }
00202
00203 const Encoding& getEncoding() const;
00204 const char* getUserAgent() const
00205 { return getHeader(httpheader::userAgent); }
00206 const char* getHost() const
00207 { return getHeader(httpheader::host); }
00208
00209 const std::string& getUsername() const;
00210 const std::string& getPassword() const;
00211 bool verifyPassword(const std::string& password) const;
00212
00213 bool keepAlive() const;
00214 bool acceptGzipEncoding() const { return getEncoding().accept("gzip"); }
00215
00216 void setApplicationScope(Scope* s);
00217 void setApplicationScope(Scope& s) { setApplicationScope(&s); }
00218
00219 void setSessionScope(Sessionscope* s);
00220 void setSessionScope(Sessionscope& s) { setSessionScope(&s); }
00221 void clearSession();
00222
00223 void setThreadContext(ThreadContext* ctx) { threadContext = ctx; }
00224
00225 Scope& getRequestScope();
00226 Scope& getApplicationScope();
00227 Scope& getThreadScope();
00228 Sessionscope& getSessionScope();
00229 bool hasSessionScope() const;
00230
00232 size_t getContentSize() const
00233 { return contentSize; }
00234
00236 std::string getVirtualHost() const
00237 { return getHeader(httpheader::host); }
00238
00239 Tntnet& getApplication()
00240 { return application; }
00241
00243 void touch() { threadContext->touch(); }
00244
00246 static void setMaxRequestSize(size_t s) { maxRequestSize = s; }
00247 static size_t getMaxRequestSize() { return maxRequestSize; }
00248 };
00249
00250 inline std::istream& operator>> (std::istream& in, HttpRequest& msg)
00251 { msg.parse(in); return in; }
00252
00253 }
00254
00255 #endif // TNT_HTTPREQUEST_H