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