1 // This may look like C code, but it's really -*- C++ -*- 2 /* 3 * Copyright (C) 2008 Emweb bv, Herent, Belgium. 4 * 5 * See the LICENSE file for terms of use. 6 */ 7 #ifndef WENVIRONMENT_H_ 8 #define WENVIRONMENT_H_ 9 10 #include <chrono> 11 #include <string> 12 #include <map> 13 #include <vector> 14 15 #include <Wt/WDllDefs.h> 16 #include <Wt/Http/Request.h> 17 #include <Wt/WLocale.h> 18 #include <Wt/WSignal.h> 19 20 namespace Wt { 21 22 /*! \brief An enumeration type for specific user agent. 23 * 24 * \sa agent() 25 */ 26 enum class UserAgent { 27 Unknown = 0, //!< Unknown user agent 28 IEMobile = 1000, //!< Internet Explorer Mobile, 5 or older 29 IE6 = 1001, //!< Internet Explorer 6 30 IE7 = 1002, //!< Internet Explorer 7 31 IE8 = 1003, //!< Internet Explorer 8 32 IE9 = 1004, //!< Internet Explorer 9 33 IE10 = 1005, //!< Internet Explorer 10 34 IE11 = 1006, //!< Internet Explorer 11 35 Edge = 1100, //!< Edge 36 Opera = 3000, //!< Opera 37 Opera10 = 3010, //!< Opera 10 or later 38 WebKit = 4000, //!< WebKit 39 Safari = 4100, //!< Safari 2 or older 40 Safari3 = 4103, //!< Safari 3 41 Safari4 = 4104, //!< Safari 4 or later 42 Chrome0 = 4200, //!< Chrome 0 43 Chrome1 = 4201, //!< Chrome 1 44 Chrome2 = 4202, //!< Chrome 2 45 Chrome3 = 4203, //!< Chrome 3 46 Chrome4 = 4204, //!< Chrome 4 47 Chrome5 = 4205, //!< Chrome 5 or later 48 Arora = 4300, //!< Arora 49 MobileWebKit = 4400, //!< Mobile WebKit 50 MobileWebKitiPhone = 4450, //!< Mobile WebKit iPhone/iPad 51 MobileWebKitAndroid = 4500, //!< Mobile WebKit Android 52 Konqueror = 5000, //!< Konqueror 53 Gecko = 6000, //!< Gecko 54 Firefox = 6100, //!< Firefox 2 or older 55 Firefox3_0 = 6101, //!< Firefox 3.0 56 Firefox3_1 = 6102, //!< Firefox 3.1 57 Firefox3_1b = 6103, //!< Firefox 3.1b 58 Firefox3_5 = 6104, //!< Firefox 3.5 59 Firefox3_6 = 6105, //!< Firefox 3.6 60 Firefox4_0 = 6106, //!< Firefox 4.0 61 Firefox5_0 = 6107, //!< Firefox 5.0 or later 62 BotAgent = 10000 //!< Bot user agent 63 }; 64 65 /*! \brief Enumeration for HTML content type. 66 */ 67 enum class HtmlContentType { 68 XHTML1, //!< XHTML1.x 69 HTML4, //!< HTML4 70 HTML5 //!< HTML5 71 }; 72 73 class WSslInfo; 74 class WAbstractServer; 75 class Configuration; 76 class WServer; 77 class WebRequest; 78 class WebSession; 79 80 /*! \class WEnvironment Wt/WEnvironment.h Wt/WEnvironment.h 81 * \brief A class that captures information on the application environment. 82 * 83 * The environment provides information on the client, and gives access 84 * to startup arguments. 85 * 86 * Usage example: 87 * \if cpp 88 * \code 89 * const WEnvironment& env = WApplication::instance()->environment(); 90 * 91 * // read an application startup argument 92 * // (passed as argument in the URL or POST'ed to the application). 93 * if (!env.getParameterValues("login").empty()) { 94 * std::string login = env.getParameterValues("login")[0]; 95 * ... 96 * } 97 * 98 * // Check for JavaScript/AJAX availability before using AJAX-only 99 * // widgets 100 * std::unique_ptr<Wt::WTextArea> textEdit; 101 * if (!env.ajax()) 102 * textEdit = std::make_unique<Wt::WTextEdit>(); // provide an HTML text editor 103 * else 104 * textEdit = std::make_unique<Wt::WTextArea>(); // fall-back to a plain old text area. 105 * 106 * \endcode 107 * \elseif java 108 * \code 109 * WEnvironment env = WApplication.instance().environment(); 110 * 111 * // read an application startup argument 112 * // (passed as argument in the URL or POST'ed to the application). 113 * if (!env.getParameterValues("login").isEmpty()) { 114 * String login = env.getParameterValues("login").get(0); 115 * //... 116 * } 117 * 118 * // Check for JavaScript/AJAX availability before using JavaScript-only 119 * // widgets 120 * WTextArea textEdit; 121 * if (!env.isAjax()) 122 * textEdit = new WTextEdit(); // provide an HTML text editor 123 * else 124 * textEdit = new WTextArea(); // fall-back to a plain old text area. 125 * \endcode 126 * \endif 127 */ 128 class WT_API WEnvironment 129 { 130 public: 131 /*! \brief Cookie map. 132 * 133 * A std::map which associates a cookie name with a cookie value. 134 * 135 * \sa cookies() 136 */ 137 typedef std::map<std::string, std::string> CookieMap; 138 139 #ifdef WT_TARGET_JAVA 140 /*! \brief %Wt's JavaScript scope. 141 */ javaScriptWtScope()142 static std::string javaScriptWtScope() { return WT_CLASS; } 143 #endif //WT_TARGET_JAVA 144 145 /*! \brief Parameters passed to the application. 146 * 147 * Arguments passed to the application, either in the URL for a 148 * http GET, or in both the URL and data submitted in a http POST. 149 * 150 * \if cpp 151 * \note The parameter map will be updated when the page is refreshed 152 * (e.g. in non-Ajax sessions and when reload-is-new-session is false), 153 * so you will have to make a copy of values in the parameter map if you want 154 * to preserve them across different requests. 155 * \endif 156 * 157 * \sa getParameterValues() 158 */ getParameterMap()159 const Http::ParameterMap& getParameterMap() const { return parameters_; } 160 161 /*! \brief Returns values for a query parameter. 162 * 163 * Returns an empty list if the parameter was not defined. 164 * 165 * One or more values may be associated with a single argument. 166 * 167 * For example a %Wt application <tt>foo.wt</tt> started as 168 * <tt>http://.../foo.wt?hello=Hello&hello=World</tt> will result in 169 * both values <tt>"Hello"</tt> and <tt>"World"</tt> to be 170 * associated with the argument <tt>"hello"</tt>. 171 * 172 * \if cpp 173 * \note The parameter map will be updated when the page is refreshed 174 * (e.g. in non-Ajax sessions and when reload-is-new-session is false), 175 * so you will have to make a copy of these values to preserve it across 176 * different requests. 177 * \endif 178 * 179 * \sa getParameterMap() 180 */ 181 const Http::ParameterValues& getParameterValues(const std::string& name) 182 const; 183 184 /*! \brief Returns a single value for a query parameter. 185 * 186 * Returns the first value for a parameter, or \c 0 if the parameter is 187 * not found. 188 * 189 * \if cpp 190 * \note The parameter map will be updated when the page is refreshed 191 * (e.g. in non-Ajax sessions and when reload-is-new-session is false), 192 * so you will have to make a copy of the returned string if you want to 193 * preserve this parameter across different requests. 194 * \endif 195 * 196 * \sa getParameterValues() 197 */ 198 const std::string *getParameter(const std::string& name) const; 199 200 /*! \brief Returns the cookies from the environment. 201 * 202 * This returns all cookies that were present in initial request for 203 * the application. Cookies set with WApplication::setCookie() are 204 * not taken into consideration. 205 * 206 * Cookies allow you to persist information across sessions, but 207 * note that not all clients may support cookies or may some clients 208 * may be configured to block cookies. 209 * 210 * \sa supportsCookies(), getCookie(), getCookieValue() 211 */ cookies()212 const CookieMap& cookies() const { return cookies_; } 213 214 /*! \brief Returns a cookie value. 215 * 216 * Returns 0 if no value was set for the given cookie. 217 * 218 * \sa getCookie() 219 */ 220 const std::string *getCookie(const std::string& cookieName) const; 221 222 /*! \brief Returns a header value. 223 * 224 * Returns a header value, or an empty string if the header was 225 * present. 226 */ 227 const std::string headerValue(const std::string& field) const; 228 229 /*! \brief Returns whether the browser has enabled support for cookies. 230 * 231 * When the user disables cookies during the visit of the page, this 232 * value is not updated. 233 * 234 * \sa cookies(), getCookie() 235 */ supportsCookies()236 bool supportsCookies() const { return doesCookies_; } 237 238 /*! \brief Returns whether the browser has enabled support for JavaScript. 239 * 240 * This is the same as ajax(): %Wt only considers using JavaScript 241 * when it has detected AJAX support. 242 * 243 * \sa ajax() 244 */ javaScript()245 bool javaScript() const { return doesAjax_; } 246 247 /*! \brief Returns whether the browser has enabled support for AJAX. 248 * 249 * Without support for JavaScript/AJAX, %Wt will still be able to 250 * serve the application, but with one considerable limitation: only 251 * the WTimer::timeout(), WInteractWidget::clicked(), 252 * WApplication::internalPathChanged(), and WAbstractArea::clicked() 253 * signals (and any derived signals) will generate events. 254 * 255 * Every event will cause the complete page to be rerendered. 256 * 257 * \sa javaScript() 258 */ ajax()259 bool ajax() const { return doesAjax_; } 260 261 /*! \brief Returns whether the browser has support for WebGL. 262 * 263 * Support for WebGL is required for client-side rendering of 264 * WGLWidget. 265 */ webGL()266 bool webGL() const { return webGLsupported_; } 267 268 /*! \brief Returns the horizontal resolution of the client's screen. 269 * 270 * Returns -1 if screen width is not known. 271 * 272 * \sa screenHeight() 273 */ screenWidth()274 int screenWidth() const { return screenWidth_; } 275 276 /*! \brief Returns the vertical resolution of the client's screen. 277 * 278 * Returns -1 if screen height is not known. 279 * 280 * \sa screenWidth() 281 */ screenHeight()282 int screenHeight() const { return screenHeight_; } 283 284 /*! \brief Returns the browser-side DPI scaling factor 285 * 286 * Internet Explorer scales all graphics, fonts and other elements 287 * on high-density screens to make them readable. This is controlled 288 * by the DPI setting of the display. If all goes well, you do not 289 * have to worry about this scaling factor. Unfortunately, not 290 * all elements are scaled appropriately. The scaling factor is 291 * supposed to be used only internally in %Wt and is in this interface 292 * for informational purposes. 293 * 294 * \sa WVmlImage 295 */ dpiScale()296 double dpiScale() const { return dpiScale_; } 297 298 /*! \brief Returns the preferred language indicated in the request 299 * header. 300 * 301 * The language is parsed from the HTTP <tt>Accept-Language</tt> 302 * field, if present. If not, the locale is empty. 303 * 304 * If multiple languages are present, the one with the highest 305 * "q"uality is assumed, and if a tie is present, the first one 306 * is taken. 307 * 308 * \sa WApplication::setLocale() 309 */ locale()310 const WLocale& locale() const { return locale_; } 311 312 /*! \brief Returns the time zone offset as reported by the client. 313 * 314 * This returns the time offset that the client has relative to 315 * UTC. A positive value thus means that the local time is ahead of 316 * UTC. 317 * 318 * This requires JavaScript support. 319 * 320 * \sa WLocalDateTime::timeZoneOffset() 321 */ timeZoneOffset()322 std::chrono::minutes timeZoneOffset() const { return timeZoneOffset_; } 323 324 /*! \brief Returns the time zone name as reported by the client. 325 * 326 * \note This requires JavaScript support and is only supported by 327 * browsers that implement the JavaScript Internationalization API. 328 * No version of Internet Explorer supports this, but modern browsers 329 * do. If not supported, this will return the empty string. 330 */ timeZoneName()331 std::string timeZoneName() const { return timeZoneName_; } 332 333 /*! \brief Returns the server host name that is used by the client. 334 * 335 * The hostname is the unresolved host name with optional port number, 336 * which the browser used to connect to the application. 337 * 338 * Examples: 339 * - <tt>www.mydomain.com</tt> 340 * - <tt>localhost:8080</tt> 341 * 342 * For HTTP 1.1 requests, this information is fetched from the HTTP 343 * <tt>Host</tt> header. If %Wt is configured behind a reverse 344 * proxy, then the last entry in the HTTP <tt>X-Forwarded-Host</tt> 345 * header field is used instead (to infer the name of the reverse 346 * proxy instead). 347 * 348 * For HTTP 1.0 requests, the HTTP <tt>Host</tt> header is not 349 * required. When not present, the server host name is inferred from 350 * the configured server name, which defaults to the DNS name. 351 */ hostName()352 const std::string& hostName() const { return host_; } 353 354 /*! \brief Returns the URL scheme used for the current request 355 * (<tt>"http"</tt> or <tt>"https"</tt>). 356 */ urlScheme()357 const std::string& urlScheme() const { return urlScheme_; } 358 359 /*! \brief Returns the user agent. 360 * 361 * The user agent, as reported in the HTTP <tt>User-Agent</tt> field. 362 * 363 * \sa agent() 364 */ userAgent()365 const std::string& userAgent() const { return userAgent_; } 366 367 /*! \brief Returns the referer. 368 * 369 * The referer, as reported in the HTTP <tt>Referer</tt> field. 370 */ referer()371 const std::string& referer() const { return referer_; } 372 373 /*! \brief Returns the accept header. 374 * 375 * The accept header, as reported in the HTTP <tt>Accept</tt> field. 376 */ accept()377 const std::string& accept() const { return accept_; } 378 379 /*! \brief Returns if the user agent is a (known) indexing spider bot. 380 * 381 * Note: currently the list of know bots is quite small. This method 382 * is used internally to render the web application for optimal 383 * indexing by bots: 384 * - there is no detection for JavaScript, instead the application is 385 * directly served assuming no JavaScript support. 386 * - session information is omitted from the Urls. 387 * - no sessions are created (they are immediately stopped after the request 388 * has been handled). 389 * - auto-generated <tt>id</tt> and <tt>name</tt> attributes are omitted 390 * from DOM nodes. In this way, the generated page is always exactly the 391 * same. 392 */ agentIsSpiderBot()393 bool agentIsSpiderBot() const { return agent_ == UserAgent::BotAgent; } 394 395 /*! \brief Returns the web server signature. 396 * 397 * The value of the CGI variable <tt>SERVER_SIGNATURE</tt>. 398 * 399 * Example: <tt><address>Apache Server at localhost Port 80</address></tt>. 400 */ serverSignature()401 const std::string& serverSignature() const { return serverSignature_; } 402 403 /*! \brief Returns the web server software. 404 * 405 * The value of the CGI variable <tt>SERVER_SOFTWARE</tt>. 406 * 407 * Example: <tt>"Apache"</tt> 408 */ serverSoftware()409 const std::string& serverSoftware() const { return serverSoftware_; } 410 411 /*! \brief Returns the email address of the server admin. 412 * 413 * The value of the CGI variable <tt>SERVER_ADMIN</tt>. 414 * 415 * Example: <tt>"root@localhost"</tt> 416 */ serverAdmin()417 const std::string& serverAdmin() const { return serverAdmin_; } 418 419 /*! \brief Returns the IP address of the client. 420 * 421 * The (most likely) IP address of the client that is connected to 422 * this session. 423 * 424 * This is taken to be the first public address that is given in the 425 * Client-IP header, or in the X-Forwarded-For header (in case the 426 * client is behind a proxy). If none of these headers is present, 427 * the remote socket IP address is used. 428 */ clientAddress()429 const std::string& clientAddress() const { return clientAddress_; } 430 431 /*! \brief Returns the initial internal path. 432 * 433 * This is the internal path with which the application was started. 434 * 435 * For an application deployed at <tt>"/stuff/app.wt"</tt>, the following 436 * two URLs are considered equivalent, and indicate an internal path 437 * <tt>"/this/there"</tt>: 438 * \code 439 * http://www.mydomain.com/stuff/app.wt/this/there 440 * http://www.mydomain.com/stuff/app.wt/this/there 441 * \endcode 442 * 443 * \if cpp 444 * For the built-in httpd, when the application is deployed at a folder 445 * (ending with '/'), only an exact matching path is routed to 446 * the application (this can be changed since Wt 3.1.9, see 447 * \ref wthttpd), making clean URLs impossible. Then, also the 448 * following URL is supported (assuming deployment at <tt>"/stuff/"</tt>: 449 * \code 450 * http://www.mydomain.com/stuff/?_=/this/there 451 * \endcode 452 * \endif 453 * 454 * \sa WApplication::setInternalPath(), deploymentPath() 455 */ internalPath()456 const std::string& internalPath() const { return internalPath_; } 457 458 /*! \brief Returns the deployment path. 459 * 460 * This is the path at which the application is deployed. 461 * 462 * \sa internalPath(). 463 */ 464 const std::string& deploymentPath() const; 465 466 /*! \brief Returns the version of the %Wt library. 467 * 468 * Example: <tt>"1.99.2"</tt> 469 */ 470 static std::string libraryVersion(); 471 472 /*! \brief Returns the version of the %Wt library, broken down. 473 * 474 * The version of the %Wt library, broken down in its three numbers, 475 * 476 * Example: <i>series</i> = 1, <i>major</i> = 99, \p minor = 2. 477 */ 478 void libraryVersion(int& series, int& major, int& minor) const; 479 480 /*! \brief Returns a raw CGI environment variable. 481 * 482 * Retrieves the value for the given CGI environment variable (like 483 * <tt>"SSL_CLIENT_S_DN_CN"</tt>), if it is defined, otherwise an 484 * empty string. 485 * 486 * \sa serverSignature(), serverSoftware(), serverAdmin(), 487 */ 488 std::string getCgiValue(const std::string& varName) const; 489 490 /*! \brief The type of the content provided to the browser. 491 * 492 * This is here for backwards compatibility, but the implementation now 493 * alwasy returns HTML5. 494 */ contentType()495 HtmlContentType contentType() const { return HtmlContentType::HTML5; } 496 497 /*! \brief Returns the user agent type. 498 * 499 * This returns an interpretation of the userAgent(). It should be 500 * used only for user-agent specific work-arounds (as a last 501 * resort). 502 * 503 * \sa agentIsIE(), agentIsOpera(), agentIsGecko(), agentIsChrome(), 504 * agentIsSafari(), agentIsWebKit() 505 */ agent()506 UserAgent agent() const { return agent_; } 507 508 /*! \brief Returns whether the user agent is Microsoft Internet Explorer. 509 * 510 * \sa agent() 511 */ agentIsIE()512 bool agentIsIE() const { 513 return static_cast<unsigned int>(agent_) >= 514 static_cast<unsigned int>(UserAgent::IEMobile) && 515 static_cast<unsigned int>(agent_) < 516 static_cast<unsigned int>(UserAgent::Opera); 517 } 518 519 /*! \brief Returns whether the user agent is an older version of IE 520 * 521 * Returns whether the agent is an IE version older than the given version. 522 523 * \sa agentIsIE() 524 */ agentIsIElt(int version)525 bool agentIsIElt(int version) const { 526 if (agentIsIE()) 527 return static_cast<unsigned int>(agent_) < 528 static_cast<unsigned int>(UserAgent::IEMobile) + (version - 5); 529 else 530 return false; 531 } 532 533 /*! \brief Returns whether the user agent is Internet Explorer Mobile. 534 * 535 * Returns also \c true when the agent is Internet Explorer 5 or older. 536 * 537 * \sa agent() 538 */ agentIsIEMobile()539 bool agentIsIEMobile() const { 540 return agent_ == UserAgent::IEMobile; 541 } 542 543 /*! \brief Returns whether the user agent is Opera. 544 * 545 * \sa agent() 546 */ agentIsOpera()547 bool agentIsOpera() const { 548 return static_cast<unsigned int>(agent_) >= 549 static_cast<unsigned int>(UserAgent::Opera) && 550 static_cast<unsigned int>(agent_) < 551 static_cast<unsigned int>(UserAgent::Safari); 552 } 553 554 /*! \brief Returns whether the user agent is WebKit-based. 555 * 556 * Webkit-based browsers include Safari, Chrome, Arora and Konquerer 557 * browsers. 558 * 559 * \sa agent() 560 */ agentIsWebKit()561 bool agentIsWebKit() const { 562 return static_cast<unsigned int>(agent_) >= 563 static_cast<unsigned int>(UserAgent::WebKit) && 564 static_cast<unsigned int>(agent_) < 565 static_cast<unsigned int>(UserAgent::Konqueror); 566 } 567 568 /*! \brief Returns whether the user agent is Mobile WebKit-based. 569 * 570 * Mobile Webkit-based browsers include the Android Mobile WebKit 571 * and the iPhone Mobile WebKit browsers. 572 * 573 * \sa agent() 574 */ agentIsMobileWebKit()575 bool agentIsMobileWebKit() const { 576 return static_cast<unsigned int>(agent_) >= 577 static_cast<unsigned int>(UserAgent::MobileWebKit) && 578 static_cast<unsigned int>(agent_) < 579 static_cast<unsigned int>(UserAgent::Konqueror); 580 } 581 582 /*! \brief Returns whether the user agent is Safari. 583 * 584 * \sa agent() 585 */ agentIsSafari()586 bool agentIsSafari() const { 587 return static_cast<unsigned int>(agent_) >= 588 static_cast<unsigned int>(UserAgent::Safari) && 589 static_cast<unsigned int>(agent_) < 590 static_cast<unsigned int>(UserAgent::Chrome0); 591 } 592 593 /*! \brief Returns whether the user agent is Chrome. 594 * 595 * \sa agent() 596 */ agentIsChrome()597 bool agentIsChrome() const { 598 return static_cast<unsigned int>(agent_) >= 599 static_cast<unsigned int>(UserAgent::Chrome0) && 600 static_cast<unsigned int>(agent_) < 601 static_cast<unsigned int>(UserAgent::Konqueror); 602 } 603 604 /*! \brief Returns whether the user agent is Gecko-based. 605 * 606 * Gecko-based browsers include Firefox. 607 * 608 * \sa agent() 609 */ agentIsGecko()610 bool agentIsGecko() const { 611 return static_cast<unsigned int>(agent_) >= 612 static_cast<unsigned int>(UserAgent::Gecko) && 613 static_cast<unsigned int>(agent_) < 614 static_cast<unsigned int>(UserAgent::BotAgent); 615 } 616 617 #ifndef WT_TARGET_JAVA 618 /*! \brief Returns the server. 619 * 620 * This returns the server environment of this session. 621 */ 622 #else 623 /*! \brief Returns the servlet. 624 * 625 * This returns the servlet environment of this session. 626 */ 627 #endif // WT_TARGET_JAVA 628 WServer *server() const; 629 630 #ifndef WT_TARGET_JAVA 631 /*! \brief Returns information on the SSL client certificate or \c nullptr 632 * if no authentication took place. 633 * 634 * This function will return \c nullptr if no verification took place, %Wt 635 * was compiled without SSL support, or the web server was 636 * configured without client SSL certificates. 637 * 638 * This method may return a pointer to a WSslInfo object, while the 639 * authentication may have failed. This depends on the configuration 640 * of the web server. It is therefore important to always check the 641 * verification result with WSslInfo::clientVerificationResult(). 642 * 643 * Remember that WEnvironment is 'const', thus the object returned 644 * by this function will represent the SSL information of the 645 * first request for this session. It will not be updated during 646 * the lifetime of the session. 647 * 648 * The object returned is owned by WEnvironment and will be deleted 649 * when WEnvironment is destroyed (= at the end of the session). 650 * 651 * \includedoc ssl_client_headers.dox 652 * 653 * \sa Wt::Http::Request::sslInfo() 654 */ sslInfo()655 WSslInfo *sslInfo() const { 656 return sslInfo_.get(); 657 } 658 #endif 659 660 /*! \brief Returns whether internal paths are implemented using URI fragments. 661 * 662 * This may be the case for older non-HTML5 browsers which do not support 663 * HTML5 History APIs. 664 */ internalPathUsingFragments()665 bool internalPathUsingFragments() const { 666 return internalPathUsingFragments_; 667 } 668 669 /*! \brief Returns whether this agent supports CSS3 animations. 670 */ 671 bool supportsCss3Animations() const; 672 673 virtual Signal<WDialog *>& dialogExecuted() const; 674 virtual Signal<WPopupMenu *>& popupExecuted() const; 675 676 /*! \brief Returns whether this is a mocked test environment. 677 */ 678 virtual bool isTest() const; 679 680 protected: 681 WebSession *session_; 682 bool doesAjax_; 683 bool doesCookies_; 684 bool internalPathUsingFragments_; 685 UserAgent agent_; 686 int screenWidth_; 687 int screenHeight_; 688 double dpiScale_; 689 std::string queryString_; 690 bool webGLsupported_; 691 692 Http::ParameterMap parameters_; 693 CookieMap cookies_; 694 695 WLocale locale_; 696 std::chrono::minutes timeZoneOffset_; 697 std::string timeZoneName_; 698 std::string host_; 699 std::string userAgent_; 700 std::string urlScheme_; 701 std::string referer_; 702 std::string accept_; 703 std::string serverSignature_; 704 std::string serverSoftware_; 705 std::string serverAdmin_; 706 std::string clientAddress_; 707 std::string pathInfo_; 708 std::string internalPath_; 709 std::string publicDeploymentPath_; 710 711 #ifndef WT_TARGET_JAVA 712 std::unique_ptr<WSslInfo> sslInfo_; 713 #endif 714 715 WEnvironment(); 716 virtual ~WEnvironment(); 717 718 void setUserAgent(const std::string& agent); 719 void setInternalPath(const std::string& path); 720 721 private: 722 WEnvironment(WebSession *session); 723 724 void init(const WebRequest& request); 725 void updateHostName(const WebRequest& request); 726 void updateUrlScheme(const WebRequest& request); 727 void enableAjax(const WebRequest& request); 728 729 bool agentSupportsAjax() const; 730 static void parseCookies(const std::string& cookie, 731 std::map<std::string, std::string>& result); 732 733 friend class WebController; 734 friend class WebRenderer; 735 friend class WebSession; 736 friend class WApplication; 737 friend class Http::Request; 738 }; 739 740 } 741 742 #endif // WENVIRONMENT_H_ 743