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