1 // 2 // This file is part of the aMule Project. 3 // 4 // Copyright (c) 2003-2011 Angel Vidal ( kry@amule.org ) 5 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 6 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net ) 7 // 8 // Any parts of this program derived from the xMule, lMule or eMule project, 9 // or contributed by third-party developers are copyrighted by their 10 // respective authors. 11 // 12 // This program is free software; you can redistribute it and/or modify 13 // it under the terms of the GNU General Public License as published by 14 // the Free Software Foundation; either version 2 of the License, or 15 // (at your option) any later version. 16 // 17 // This program is distributed in the hope that it will be useful, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 // GNU General Public License for more details. 21 // 22 // You should have received a copy of the GNU General Public License 23 // along with this program; if not, write to the Free Software 24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 25 // 26 27 #ifndef WEBSERVER_H 28 #define WEBSERVER_H 29 30 #ifdef HAVE_CONFIG_H 31 #include "config.h" // Needed for ASIO_SOCKETS 32 #endif 33 34 #ifdef WITH_LIBPNG 35 #include <png.h> 36 #endif 37 38 #include "WebInterface.h" 39 #include <map> // Needed for std::map 40 #include <set> // Needed for std::set 41 #include "RLE.h" 42 #include "OtherStructs.h" 43 #include <ec/cpp/ECID.h> // Needed for CECID 44 45 #ifdef ENABLE_UPNP 46 # include "UPnPBase.h" 47 #endif 48 49 #include <wx/datetime.h> // For DownloadFile::wxtLastSeenComplete 50 51 #ifdef _MSC_VER 52 #define strncasecmp _strnicmp 53 #define snprintf sprintf_s 54 #define atoll _atoi64 55 #define strdup _strdup 56 #endif 57 58 class CWebSocket; 59 class CMD4Hash; 60 61 #define SESSION_TIMEOUT_SECS 300 // 5 minutes session expiration 62 #define SHORT_FILENAME_LENGTH 40 // Max size of file name. 63 64 wxString _SpecialChars(wxString str); 65 66 class CEC_PartFile_Tag; 67 class CEC_SharedFile_Tag; 68 class CEC_UpDownClient_Tag; 69 class CEC_SearchFile_Tag; 70 class CProgressImage; 71 class CEC_KadNode_Tag; 72 73 class CURLDecoder 74 { 75 public: 76 static wxString Decode(const wxString& url); 77 }; 78 79 class DownloadFile : public CECID { 80 public: 81 wxString sFileName; 82 uint8 nFileStatus; 83 uint64 lFileSize; 84 uint64 lFileCompleted; 85 uint64 lFileTransferred; 86 unsigned long lFileSpeed; 87 long lSourceCount; 88 long lNotCurrentSourceCount; 89 long lTransferringSourceCount; 90 long lSourceCountA4AF; 91 double fCompleted; 92 uint32 lFilePrio; 93 bool bFileAutoPriority; 94 wxString sFileHash; 95 wxString sED2kLink; 96 uint8 nCat; 97 wxDateTime wxtLastSeenComplete; 98 99 CMD4Hash nHash; 100 101 CProgressImage *m_Image; 102 PartFileEncoderData m_Encoder; 103 ArrayOfUInts16 m_PartInfo; 104 std::vector<Gap_Struct> m_ReqParts; 105 ArrayOfUInts64 m_Gaps; 106 107 // container require this 108 static class DownloadFileInfo *GetContainerInstance(); 109 DownloadFile(CEC_PartFile_Tag *); 110 void ProcessUpdate(CEC_PartFile_Tag *); ID()111 uint32 ID() { return ECID(); } 112 }; 113 114 class SharedFile : public CECID { 115 public: 116 wxString sFileName; 117 uint64 lFileSize; 118 uint64 nFileTransferred; 119 uint64 nFileAllTimeTransferred; 120 uint16 nFileRequests; 121 uint32 nFileAllTimeRequests; 122 uint16 nFileAccepts; 123 uint32 nFileAllTimeAccepts; 124 uint8 nFilePriority; 125 bool bFileAutoPriority; 126 wxString sFileHash; 127 wxString sED2kLink; 128 129 CMD4Hash nHash; 130 131 static class SharedFileInfo *GetContainerInstance(); 132 SharedFile(CEC_SharedFile_Tag *); 133 void ProcessUpdate(CEC_SharedFile_Tag *); ID()134 uint32 ID() { return ECID(); } 135 }; 136 137 class ServerEntry { 138 public: 139 wxString sServerName; 140 wxString sServerDescription; 141 uint32 nServerIP; 142 uint16 nServerPort; 143 wxString sServerIP; 144 int nServerUsers; 145 int nServerMaxUsers; 146 int nServerFiles; 147 148 static class ServersInfo *GetContainerInstance(); ID()149 uint32 ID() { return nServerIP; } 150 }; 151 152 // This is a client we are uploading to, not a file 153 class UploadFile : public CECID { 154 public: 155 wxString sUserName; 156 uint32 nTransferredUp; 157 uint32 nTransferredDown; 158 uint32 nSpeed; 159 uint32 nUploadFile; // ECID of shared file uploading to client 160 161 UploadFile(CEC_UpDownClient_Tag *tag); 162 163 static class UploadsInfo *GetContainerInstance(); ID()164 uint32 ID() { return ECID(); } 165 }; 166 167 class SearchFile : public CECID { 168 public: 169 wxString sFileName; 170 uint64 lFileSize; 171 CMD4Hash nHash; 172 wxString sHash; 173 long lSourceCount; 174 bool bPresent; 175 176 SearchFile(CEC_SearchFile_Tag *); 177 178 void ProcessUpdate(CEC_SearchFile_Tag *); 179 static class SearchInfo *GetContainerInstance(); ID()180 uint32 ID() { return ECID(); } 181 }; 182 183 184 /*! 185 * T - type of items in container 186 */ 187 template <class T> 188 class ItemsContainer { 189 protected: 190 CamulewebApp *m_webApp; 191 std::list<T> m_items; 192 193 EraseAll()194 void EraseAll() 195 { 196 m_items.erase(m_items.begin(), m_items.end()); 197 } 198 public: ItemsContainer(CamulewebApp * webApp)199 ItemsContainer(CamulewebApp *webApp) 200 { 201 m_webApp = webApp; 202 } ~ItemsContainer()203 virtual ~ItemsContainer() { } 204 205 ItemCount()206 int ItemCount() 207 { 208 return m_items.size(); 209 } 210 211 AddItem(T & item)212 T *AddItem(T &item) 213 { 214 m_items.push_back(item); 215 T *real_ptr = &(m_items.back()); 216 return real_ptr; 217 } 218 219 /*! 220 * Re-query server: refresh all dataset 221 */ 222 virtual bool ReQuery() = 0; 223 224 typedef typename std::list<T>::iterator ItemIterator; GetBeginIterator()225 ItemIterator GetBeginIterator() 226 { 227 return m_items.begin(); 228 } GetEndIterator()229 ItemIterator GetEndIterator() 230 { 231 return m_items.end(); 232 } 233 }; 234 235 /*! 236 * T - type of items in container 237 * I - type of item ID 238 * G - type of tag in EC 239 */ 240 template <class T, class G, class I> 241 class UpdatableItemsContainer : public ItemsContainer<T> { 242 protected: 243 // need duplicate list with a map, so check "do we already have" 244 // will take O(log(n)) instead of O(n) 245 // map will contain pointers to items in list 246 std::map<I, T *> m_items_hash; 247 public: UpdatableItemsContainer(CamulewebApp * webApp)248 UpdatableItemsContainer(CamulewebApp *webApp) : ItemsContainer<T>(webApp) 249 { 250 } 251 AddItem(T & item)252 T *AddItem(T &item) 253 { 254 T *real_ptr = ItemsContainer<T>::AddItem(item); 255 m_items_hash[item.ID()] = real_ptr; 256 return real_ptr; 257 } 258 GetByID(I id)259 T *GetByID(I id) 260 { 261 // avoid creating nodes 262 return m_items_hash.count(id) ? m_items_hash[id] : NULL; 263 } 264 GetByHash(const CMD4Hash & fileHash)265 T * GetByHash(const CMD4Hash &fileHash) 266 { 267 T * ret = 0; 268 for (typename std::map<I, T *>::iterator it = m_items_hash.begin(); it != m_items_hash.end(); ++it) { 269 if (it->second->nHash == fileHash) { 270 ret = it->second; 271 break; 272 } 273 } 274 return ret; 275 } 276 277 /*! 278 * Process answer of update request, create list of new items for 279 * full request later. Also remove items that no longer exist in core 280 */ ProcessUpdate(const CECPacket * reply,CECPacket * full_req,int req_type)281 void ProcessUpdate(const CECPacket *reply, CECPacket *full_req, int req_type) 282 { 283 std::set<I> core_files; 284 for (CECPacket::const_iterator it = reply->begin(); it != reply->end(); ++it) { 285 G *tag = (G *) & *it; 286 287 core_files.insert(tag->ID()); 288 if ( m_items_hash.count(tag->ID()) ) { 289 T *item = m_items_hash[tag->ID()]; 290 item->ProcessUpdate(tag); 291 } else { 292 full_req->AddTag(CECTag(req_type, tag->ID())); 293 } 294 } 295 std::list<I> del_ids; 296 for(typename std::list<T>::iterator j = this->m_items.begin(); j != this->m_items.end(); ++j) { 297 if ( core_files.count(j->ID()) == 0 ) { 298 // item may contain data that need to be freed externally, before 299 // dtor is called and memory freed 300 301 T *real_ptr = &*j; 302 this->ItemDeleted(real_ptr); 303 304 del_ids.push_back(j->ID()); 305 } 306 } 307 for(typename std::list<I>::iterator j = del_ids.begin(); j != del_ids.end(); ++j) { 308 m_items_hash.erase(*j); 309 for(typename std::list<T>::iterator k = this->m_items.begin(); k != this->m_items.end(); ++k) { 310 if ( *j == k->ID() ) { 311 this->m_items.erase(k); 312 break; 313 } 314 } 315 } 316 } 317 ProcessFull(const CECPacket * reply)318 void ProcessFull(const CECPacket *reply) 319 { 320 for (CECPacket::const_iterator it = reply->begin(); it != reply->end(); ++it) { 321 G *tag = (G *) & *it; 322 // initialize item data from EC tag 323 T item(tag); 324 T *real_ptr = AddItem(item); 325 // initialize any external data that may depend on this item 326 this->ItemInserted(real_ptr); 327 } 328 } 329 DoRequery(int cmd,int tag)330 bool DoRequery(int cmd, int tag) 331 { 332 CECPacket req_sts(cmd, EC_DETAIL_UPDATE); 333 334 // 335 // Phase 1: request status 336 const CECPacket *reply = this->m_webApp->SendRecvMsg_v2(&req_sts); 337 if ( !reply ) { 338 return false; 339 } 340 341 // 342 // Phase 2: update status, mark new files for subsequent query 343 CECPacket req_full(cmd); 344 345 ProcessUpdate(reply, &req_full, tag); 346 347 delete reply; 348 349 // Phase 3: request full info about files we don't have yet 350 if ( req_full.HasChildTags() ) { 351 reply = this->m_webApp->SendRecvMsg_v2(&req_full); 352 if ( !reply ) { 353 return false; 354 } 355 ProcessFull(reply); 356 delete reply; 357 } 358 return true; 359 } 360 ItemDeleted(T *)361 virtual void ItemDeleted(T *) { } ItemInserted(T *)362 virtual void ItemInserted(T *) { } 363 }; 364 365 class UploadsInfo : public ItemsContainer<UploadFile> { 366 public: 367 // can be only one instance. 368 static UploadsInfo *m_This; 369 370 UploadsInfo(CamulewebApp *webApp); 371 372 virtual bool ReQuery(); 373 }; 374 375 class ServersInfo : public ItemsContainer<ServerEntry> { 376 public: 377 // can be only one instance. 378 static ServersInfo *m_This; 379 380 ServersInfo(CamulewebApp *webApp); 381 382 virtual bool ReQuery(); 383 384 }; 385 386 387 class SharedFileInfo : public UpdatableItemsContainer<SharedFile, CEC_SharedFile_Tag, uint32> { 388 public: 389 // can be only one instance. 390 static SharedFileInfo *m_This; 391 392 SharedFileInfo(CamulewebApp *webApp); 393 394 virtual bool ReQuery(); 395 396 }; 397 398 class SearchInfo : public UpdatableItemsContainer<SearchFile, CEC_SearchFile_Tag, uint32> { 399 public: 400 static SearchInfo *m_This; 401 402 SearchInfo(CamulewebApp *webApp); 403 404 virtual bool ReQuery(); 405 406 }; 407 408 409 class CImageLib; 410 class DownloadFileInfo : public UpdatableItemsContainer<DownloadFile, CEC_PartFile_Tag, uint32> { 411 CImageLib *m_ImageLib; 412 413 // parameters of progress images 414 wxString m_Template; 415 int m_width, m_height; 416 public: 417 // can be only one instance. 418 static DownloadFileInfo *m_This; 419 420 DownloadFileInfo(CamulewebApp *webApp, CImageLib *imlib); 421 422 void LoadImageParams(wxString &tpl, int width, int height); 423 424 virtual bool ReQuery(); 425 426 // container requirements 427 void ItemInserted(DownloadFile *item); 428 void ItemDeleted(DownloadFile *item); 429 }; 430 431 class CAnyImage { 432 protected: 433 unsigned char *m_data; 434 435 int m_width, m_height; 436 wxString m_name; 437 438 int m_size, m_alloc_size; 439 wxString m_Http; 440 441 void Realloc(int size); 442 443 void SetHttpType(wxString ext); 444 public: 445 CAnyImage(int size); 446 CAnyImage(int width, int height); 447 virtual ~CAnyImage(); 448 GetHTTP()449 const wxString& GetHTTP() const { return m_Http; } 450 451 virtual unsigned char *RequestData(int &size); 452 }; 453 454 class CFileImage : public virtual CAnyImage { 455 public: 456 CFileImage(const wxString& name); 457 OpenOk()458 bool OpenOk() { return m_size != 0; } 459 }; 460 461 class CImage3D_Modifiers { 462 unsigned char *m_modifiers; 463 int m_width; 464 public: 465 CImage3D_Modifiers(int width); 466 ~CImage3D_Modifiers(); 467 468 unsigned char operator[](int i) 469 { 470 return (i < m_width) ? m_modifiers[i] : 0; 471 } 472 }; 473 474 class CProgressImage : public virtual CAnyImage { 475 protected: 476 DownloadFile *m_file; 477 478 wxString m_template; 479 480 // 481 // Turn list of gaps, partstatus into array of color strips 482 typedef struct Color_Gap_Struct : public Gap_Struct { 483 uint32 color; 484 } Color_Gap_Struct; 485 486 // result of rendering - single line 487 uint32 *m_ColorLine; 488 void CreateSpan(); 489 public: 490 CProgressImage(int w, int h, wxString &tmpl, DownloadFile *file); 491 492 ~CProgressImage(); 493 Name()494 const wxString &Name() { return m_name; } 495 496 virtual wxString GetHTML() = 0; 497 }; 498 499 #ifdef WITH_LIBPNG 500 501 // 502 // Dynamic png image generation 503 // 504 class CDynPngImage : public virtual CAnyImage { 505 506 public: 507 CDynPngImage(int w, int h); 508 ~CDynPngImage(); 509 510 virtual unsigned char *RequestData(int &size); 511 512 protected: 513 png_bytep m_img_data; 514 png_bytep *m_row_ptrs; 515 516 static void png_write_fn(png_structp png_ptr, png_bytep data, png_size_t length); 517 518 }; 519 520 // 521 // Dynamic png image generation from gap info 522 class CDynProgressImage : public virtual CProgressImage, public virtual CDynPngImage { 523 CImage3D_Modifiers m_modifiers; 524 525 void DrawImage(); 526 public: 527 CDynProgressImage(int w, int h, wxString &tmpl, DownloadFile *file); 528 ~CDynProgressImage(); 529 530 virtual unsigned char *RequestData(int &size); 531 virtual wxString GetHTML(); 532 }; 533 534 #else 535 536 537 // 538 // Fallback to original implementation 539 class CDynProgressImage : public virtual CProgressImage { 540 public: 541 CDynProgressImage(int w, int h, wxString &tmpl, DownloadFile *file); 542 543 virtual wxString GetHTML(); 544 }; 545 546 #endif 547 548 // 549 // Representing statistical sample for some parameter. Circular buffer 550 // inside to avoid rellocations 551 // 552 class CStatsData { 553 uint32 *m_data; 554 uint32 m_max_value; 555 int m_size; 556 int m_start_index, m_end_index, m_curr_index; 557 public: 558 CStatsData(int size); 559 ~CStatsData(); 560 Size()561 int Size() const { return m_size; } Max()562 uint32 Max() const { return m_max_value; } 563 uint32 GetFirst(); 564 uint32 GetNext(); 565 566 void PushSample(uint32 sample); 567 }; 568 569 class CStatsCollection { 570 CStatsData *m_down_speed, *m_up_speed, 571 *m_conn_number, *m_kad_count; 572 573 CamulewebApp *m_iface; 574 double m_LastTimeStamp; 575 int m_size; 576 public: 577 CStatsCollection(int size, CamulewebApp *iface); 578 ~CStatsCollection(); 579 DownloadSpeed()580 CStatsData *DownloadSpeed() { return m_down_speed; } UploadSpeed()581 CStatsData *UploadSpeed() { return m_up_speed; } ConnCount()582 CStatsData *ConnCount() { return m_conn_number; } KadCount()583 CStatsData *KadCount() { return m_kad_count; } 584 585 void ReQuery(); 586 }; 587 588 #ifdef WITH_LIBPNG 589 590 // 591 // This gonna to represent data used to "write" numbers on 592 // dynamically generated images. 593 // Easiest way to represt numbers: 7-segments model 594 // 595 class CNumImageMask { 596 png_bytep *m_row_mask_ptrs; 597 int m_width, m_height; 598 int m_v_segsize, m_h_segsize; 599 600 // mask generation 601 void DrawHorzLine(int off); 602 void DrawVertLine(int offx, int offy); 603 void DrawSegment(int id); 604 605 static const int m_num_to_7_decode[10]; 606 public: 607 CNumImageMask(int number, int width, int height); 608 ~CNumImageMask(); 609 610 void Apply(png_bytep *image, int offx, int offy); 611 }; 612 613 class CDynStatisticImage : public virtual CDynPngImage { 614 CStatsData *m_data; 615 616 // size of "font" of imprinted numbers 617 int m_num_font_w_size, m_num_font_h_size; 618 619 int m_left_margin, m_bottom_margin; 620 int m_y_axis_size; 621 622 // hope nobody needs "define" for 10 ! 623 CNumImageMask *m_digits[10]; 624 625 // indicates whether data should be divided on 1024 before 626 // drawing graph. 627 bool m_scale1024; 628 629 // 630 // Prepared background 631 // 632 png_bytep m_background; 633 png_bytep *m_row_bg_ptrs; 634 635 void DrawImage(); 636 public: 637 CDynStatisticImage(int height, bool scale1024, CStatsData *data); 638 ~CDynStatisticImage(); 639 640 virtual unsigned char *RequestData(int &size); 641 virtual wxString GetHTML(); 642 }; 643 644 #endif 645 646 class CImageLib { 647 typedef std::map<wxString, CAnyImage *> ImageMap; 648 ImageMap m_image_map; 649 wxString m_image_dir; 650 public: 651 CImageLib(wxString image_dir); 652 ~CImageLib(); 653 654 CAnyImage *GetImage(const wxString &name); 655 void AddImage(CAnyImage *img, const wxString &name); 656 void RemoveImage(const wxString &name); 657 }; 658 659 class CParsedUrl { 660 wxString m_path, m_file; 661 std::map<wxString, wxString> m_params; 662 public: 663 CParsedUrl(const wxString &url); 664 Path()665 const wxString &Path() { return m_path; } File()666 const wxString &File() { return m_file; } 667 Param(const wxString & key)668 const wxString &Param(const wxString &key) 669 { 670 return m_params[key]; 671 } 672 673 void ConvertParams(std::map<std::string, std::string> &); 674 }; 675 676 // Changing this to a typedef struct{} makes egcs compiler do it all wrong and crash on run 677 struct ThreadData { 678 CParsedUrl parsedURL; 679 wxString sURL; 680 int SessionID; 681 CWebSocket *pSocket; 682 }; 683 684 #ifndef ASIO_SOCKETS 685 enum { 686 // Socket handlers 687 ID_WEBLISTENSOCKET_EVENT = wxID_HIGHEST+123, // random safe ID 688 ID_WEBCLIENTSOCKET_EVENT, 689 }; 690 #endif 691 692 #ifdef ENABLE_UPNP 693 class CUPnPControlPoint; 694 class CUPnPPortMapping; 695 #endif 696 697 class CWebLibSocketServer : public CLibSocketServer { 698 public: 699 CWebLibSocketServer(const class amuleIPV4Address& adr, int flags, CWebServerBase * webServerBase); 700 701 virtual void OnAccept(); 702 private: 703 CWebServerBase * m_webServerBase; 704 }; 705 706 class CWebServerBase : public wxEvtHandler { 707 protected: 708 CWebLibSocketServer *m_webserver_socket; 709 710 ServersInfo m_ServersInfo; 711 SharedFileInfo m_SharedFileInfo; 712 DownloadFileInfo m_DownloadFileInfo; 713 UploadsInfo m_UploadsInfo; 714 SearchInfo m_SearchInfo; 715 716 CStatsCollection m_Stats; 717 718 CImageLib m_ImageLib; 719 720 virtual void ProcessURL(ThreadData) = 0; 721 virtual void ProcessImgFileReq(ThreadData) = 0; 722 723 int GzipCompress(Bytef *dest, uLongf *destLen, 724 const Bytef *source, uLong sourceLen, int level); 725 726 friend class CWebSocket; 727 friend class CPhPLibContext; 728 729 bool m_upnpEnabled; 730 int m_upnpTCPPort; 731 #ifdef ENABLE_UPNP 732 CUPnPControlPoint *m_upnp; 733 std::vector<CUPnPPortMapping> m_upnpMappings; 734 #endif 735 #ifdef ASIO_SOCKETS 736 CAsioService *m_AsioService; 737 #else 738 void OnWebSocketServerEvent(wxSocketEvent& event); 739 void OnWebSocketEvent(wxSocketEvent& event); 740 DECLARE_EVENT_TABLE(); 741 #endif 742 public: 743 CWebServerBase(CamulewebApp *webApp, const wxString& templateDir); 744 virtual ~CWebServerBase(); 745 746 void Send_Discard_V2_Request(CECPacket *request); 747 748 void StartServer(); 749 void StopServer(); 750 751 void Print(const wxString &s); 752 753 long GetWSPrefs(); 754 755 // 756 // Command interface 757 // 758 void Send_ReloadSharedFile_Cmd(); 759 760 void Send_SharedFile_Cmd(wxString file_hash, wxString cmd, uint32 opt_arg = 0); 761 void Send_DownloadFile_Cmd(wxString file_hash, wxString cmd, uint32 opt_arg = 0); 762 763 void Send_DownloadSearchFile_Cmd(wxString file_hash, uint8 cat); 764 765 void Send_Server_Cmd(uint32 ip, uint16 port, wxString cmd); 766 void Send_AddServer_Cmd(wxString addr, wxString port, wxString name); 767 768 void Send_Search_Cmd(wxString search, wxString extention, wxString type, 769 EC_SEARCH_TYPE search_type, uint32 avail, uint32 min_size, uint32 max_size); 770 771 bool Send_DownloadEd2k_Cmd(wxString link, uint8 cat); 772 Reload_Stats()773 void Reload_Stats() 774 { 775 m_Stats.ReQuery(); 776 } 777 778 CamulewebApp *webInterface; 779 780 }; 781 782 class CSession { 783 public: 784 bool m_loggedin; 785 time_t m_last_access; 786 std::map<std::string, std::string> m_vars, m_get_vars; 787 788 void LoadVars(CParsedUrl &url); 789 }; 790 791 /* 792 * Script based webserver 793 */ 794 class CScriptWebServer : public CWebServerBase { 795 wxString m_wwwroot; 796 wxString m_index; 797 798 char *ProcessHtmlRequest(const char *filename, long &size); 799 char *ProcessPhpRequest(const char *filename, CSession *sess, long &size); 800 801 char *GetErrorPage(const char *message, long &size); 802 char *Get_404_Page(long &size); 803 804 std::map<int, CSession> m_sessions; 805 806 CSession *CheckLoggedin(ThreadData &); 807 protected: 808 virtual void ProcessURL(ThreadData); 809 virtual void ProcessImgFileReq(ThreadData); 810 public: 811 CScriptWebServer(CamulewebApp *webApp, const wxString& templateDir); 812 ~CScriptWebServer(); 813 814 }; 815 816 class CNoTemplateWebServer : public CScriptWebServer { 817 protected: 818 virtual void ProcessURL(ThreadData); 819 public: 820 CNoTemplateWebServer(CamulewebApp *webApp); 821 ~CNoTemplateWebServer(); 822 }; 823 824 #endif // WEBSERVER_H 825 // File_checked_for_headers 826