浏览代码

A Http lite interface .. allow asynce responces.

Roger Hughston 18 年之前
父节点
当前提交
795c46b32d

+ 2 - 0
direct/src/http/application_log.h

@@ -0,0 +1,2 @@
+#define LOGINFO    printf
+#define LOGWARNING printf

+ 65 - 0
direct/src/http/baseincomingset.h

@@ -0,0 +1,65 @@
+#ifndef __BASEINCOMINGSET_H__
+#define __BASEINCOMINGSET_H__
+
+#include <list>
+#include "socket_base.h"
+
+enum CloseState 
+{
+		ConnectionDoNotClose,
+		ConnectionDoClose
+};
+// RHH
+////////////////////////////////////////////////////////////////////
+// 	 Template :BaseIncomingSet
+//
+// Description :  A base structre for a listening socket and a
+//				set of connection that have been received with there read functions..
+//
+//	Think of this like a web server with 1 listening socket and 0-n open reacting conections..
+//
+//	The general operation if get connection..
+//			do you have a message
+//			process message 
+//			go back to do you have a message or close connection
+//
+//
+////////////////////////////////////////////////////////////////////
+template < class _INCLASS1,class _IN_LISTEN, class MESSAGE_READER_BUF, class MESSAGE_READER_UPPASS> class BaseIncomingSet : public  std::list<_INCLASS1 *>
+{
+	_IN_LISTEN					_Listener;
+
+	inline void AddFromListener(void);
+	inline int PumpReader(Time_Clock  &currentTime);
+	inline void AddAConection(_INCLASS1 * newt);
+
+public:
+
+//	typedef typename BaseIncomingSet<_INCLASS1, _IN_LISTEN, MESSAGE_READER_BUF, MESSAGE_READER_UPPASS>::LinkNode LinkNode;
+
+//	typedef SentDblLinkListNode_Gm   SentDblLinkListNode_Gm; 
+	inline BaseIncomingSet(void);
+	inline BaseIncomingSet(BaseIncomingSet &in);
+	virtual ~BaseIncomingSet();
+
+	inline _IN_LISTEN & GetListener(void);
+	inline bool init(Socket_Address &WhereFrom);
+	inline void PumpAll(Time_Clock  &currentTime);
+	virtual CloseState ProcessNewConnection(SOCKET  socket);
+	inline  void AddToFDSet(Socket_fdset &set);
+
+    
+
+
+
+//	inline	LinkNode *          GetRoot(void) {  return &this->sentenal; };
+	BaseIncomingSet &operator=( BaseIncomingSet &inval);
+    void Reset();
+};
+
+#include "baseincomingset.i"
+
+#endif //__BASEINCOMINGSET_H__
+
+
+

+ 202 - 0
direct/src/http/baseincomingset.i

@@ -0,0 +1,202 @@
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddFromListener
+// Description	    : Read incoming connections off the listener
+//  
+// Return type		: inline void 
+// Argument         : void
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddFromListener(void)
+{
+	Socket_Address	Addr1;
+	SOCKET			newsck;
+	
+	
+	while(_Listener.GetIncomingConnection(newsck,Addr1) == true)
+	{	
+		CloseState cl= ProcessNewConnection(newsck);
+		if(cl == ConnectionDoNotClose)
+		{
+			_INCLASS1 * newt = new _INCLASS1(newsck,Addr1);
+			AddAConection(newt);
+		}
+		else
+			DO_CLOSE(newsck);
+	}		
+		
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpReader
+// Description	    : Tries to read a record off the incoming socket
+//  
+// Return type		: inline void 
+// Argument         : Time_Clock  currentTime
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline int BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpReader(Time_Clock  &currentTime)
+{		
+	MESSAGE_READER_BUF		message;
+	
+	iterator lpNext, lp;
+	for (lpNext  = lp = begin(); lp != end() ; lp = lpNext)
+	{
+		lpNext++;	
+		
+		int ans = (*lp)->ReadIt(message, sizeof(message),currentTime);
+		if(ans < 0)
+		{
+			delete *lp;
+			erase(lp);
+		}				
+		if(ans > 0)
+		{
+			CloseState cs = (*lp)->ProcessMessage(message,currentTime);
+			if( cs == ConnectionDoClose)
+			{
+				delete *lp;
+				erase(lp);
+			}
+		}
+	}	
+	return 0;			
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddAConection
+// Description	    : Adds a member to the base container
+//  
+// Return type		: inline void 
+// Argument         : _INCLASS1 * newt
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddAConection(_INCLASS1 * newt)
+{
+	push_back(newt);
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::BaseIncomingSet
+// Description	    :  core constructor
+//  
+// Return type		: inline 
+// Argument         : void
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::BaseIncomingSet(void)
+{
+	
+}
+
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::BaseIncomingSet(BaseIncomingSet &in)
+{
+
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::~BaseIncomingSet
+// Description	    : The Destructot .. will delete all members.. ??
+//  
+// Return type		: 
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::~BaseIncomingSet()
+{
+    for(iterator ii = begin(); ii != end(); ii++)
+        delete *ii;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: & BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::GetListener
+// Description	    : Retyurns a pointer to the listener in this class
+//  
+// Return type		: inline _IN_LISTEN 
+// Argument         : void
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline _IN_LISTEN & BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::GetListener(void) 
+{ 
+	return this->Listener; 
+};
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::init
+// Description	    : the second part of the 2 phase power up.. Opends the listener
+//  
+// Return type		: inline bool 
+// Argument         : Socket_Address &WhereFrom
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline bool BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::init(Socket_Address &WhereFrom)
+{
+	if(_Listener.OpenForListen(WhereFrom,true) != true)
+		return false;		
+	_Listener.SetNonBlocking();
+	return true;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpAll
+// Description	    : THis is the polled interface to this class
+//  
+// Return type		: inline void 
+// Argument         : Time_Clock  &currentTime
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::PumpAll(Time_Clock  &currentTime)
+{
+	PumpReader(currentTime); // I MOVED ORDER TO FINE TUNE THE READ OPERATIONS
+	AddFromListener();		 
+}
+
+////////////////////////////////////////////////////////////////////
+// Function name	: BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::ProcessNewConnection
+// Description	    :  this is the vertual function call when a new connection is created 
+//						manly here for loging if needed...
+//  
+// Return type		: CloseState 
+// Argument         : SOCKET  socket
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+CloseState BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::ProcessNewConnection(SOCKET  socket)
+{
+	return ConnectionDoNotClose;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddToFDSet
+// Description	    : Add LIstener and Client to the FD set for polled reading 
+//  
+// Return type		: inline  
+// Argument         : Socket_Selector &set
+////////////////////////////////////////////////////////////////////
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline  void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::AddToFDSet(Socket_fdset &set1)
+{	
+	if(_Listener.Active())
+		set1.setForSocket(_Listener);
+	iterator lp;
+	
+	for (lp = begin(); lp != end(); lp = lp++)
+		set1.setForSocket((*lp)->val);
+}
+
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS> &BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::operator=
+	(BaseIncomingSet &inval)
+{
+	 if (&inval == this) return *this;
+	_Listener = inval._Listener;
+	return *this;
+}
+
+
+template <class _INCLASS1,class _IN_LISTEN,typename  MESSAGE_READER_BUF, typename  MESSAGE_READER_UPPASS> 
+inline void BaseIncomingSet<_INCLASS1,_IN_LISTEN,MESSAGE_READER_BUF,MESSAGE_READER_UPPASS>::Reset()
+{
+	_Listener.Close();
+	iterator lpNext, lp;
+	for (lpNext  = lp = begin(); lp != end() ; lp = lpNext)
+	{
+		lpNext++;	
+		(*lp)->Reset();
+		delete *lp;
+		erase(lp);
+	}				
+}
+
+
+

+ 117 - 0
direct/src/http/bufferedwriter_growable.h

@@ -0,0 +1,117 @@
+#ifndef __BufferedWriter_Growable_H__
+#define __BufferedWriter_Growable_H__
+///////////////////////////////////////////////////////
+// this class is for the usage of growable output...
+// it is slower than buffered writer but more robust..
+// it also allows for writes to take more time to the out putt..
+// ie.. Write buffering.. Not just one write..
+///////////////////////////////////////////////////
+
+class BufferedWriter_Growable : public std::string 
+{
+	int				_write_offset;
+public:
+
+	BufferedWriter_Growable(void); 
+	~BufferedWriter_Growable(void);
+	int AmountBuffered(void);
+	void AppendData(const char * buf, int len);
+    void Reset() { clear(); _write_offset = 0; };
+	const char * GetMessageHead(void);
+	int  Flush(Socket_TCP &sck) ; // this is the ugly part
+};
+
+
+//////////////////////////////////////////////////////////////
+// Function name	: BufferedWriter_Growable::BufferedWriter_Growable
+// Description	    : 
+// Return type		: inline 
+// Argument         : void
+//////////////////////////////////////////////////////////////
+inline BufferedWriter_Growable::BufferedWriter_Growable(void) 
+{
+	_write_offset = 0;
+};
+
+
+//////////////////////////////////////////////////////////////
+// Function name	: ~BufferedWriter_Growable::BufferedWriter_Growable
+// Description	    : 
+// Return type		: inline 
+// Argument         : void
+//////////////////////////////////////////////////////////////
+inline BufferedWriter_Growable::~BufferedWriter_Growable(void)
+{
+}
+
+
+//////////////////////////////////////////////////////////////
+// Function name	: BufferedWriter_Growable::AmountBuffered
+// Description	    : 
+// Return type		: inline int 
+// Argument         : void
+//////////////////////////////////////////////////////////////
+inline int BufferedWriter_Growable::AmountBuffered(void)
+{
+	return (int) (size() - _write_offset);
+}
+
+
+//////////////////////////////////////////////////////////////
+// Function name	: BufferedWriter_Growable::AppendData
+// Description	    : 
+// Return type		: inline void 
+// Argument         : const char * buf
+// Argument         : int len
+//////////////////////////////////////////////////////////////
+inline void BufferedWriter_Growable::AppendData(const char * buf, int len)
+{
+	append(buf, len);
+}
+
+
+//////////////////////////////////////////////////////////////
+// Function name	: char * BufferedWriter_Growable::GetMessageHead
+// Description	    : 
+// Return type		: inline const 
+// Argument         : void
+//////////////////////////////////////////////////////////////
+inline const char * BufferedWriter_Growable::GetMessageHead(void)
+{
+	return data() + _write_offset;
+}
+
+
+//////////////////////////////////////////////////////////////
+// Function name	:  BufferedWriter_Growable::Flush
+// Description	    : 
+// Return type		: inline int 
+// Argument         : SocketTCP_Gm &sck
+//////////////////////////////////////////////////////////////
+inline int  BufferedWriter_Growable::Flush(Socket_TCP &sck)  // this is the ugly part
+{	
+	int answer = 0;	
+	int Writesize = AmountBuffered();
+	
+	if(Writesize > 0)
+	{
+		const char * out1 = GetMessageHead();
+		int Writen = sck.SendData(out1,Writesize);
+		if(Writen > 0)
+		{
+			_write_offset += Writen;
+			answer = 1;
+		}
+		else if(Writen < 0)
+		{
+			if(GETERROR() != LOCAL_BLOCKING_ERROR) 
+				answer = -1;
+		}
+	}		
+	return answer;
+}
+
+
+#endif //__BufferedWriter_Growable_H__
+
+

+ 96 - 0
direct/src/http/http_bufferedreader.h

@@ -0,0 +1,96 @@
+#ifndef __WEBBUFFEREDREADER_GM_H__
+#define __WEBBUFFEREDREADER_GM_H__
+// RHH
+
+#include  <string>
+#include   "strtargetbuffer.h"
+#include   "ringbuffer_slide.h"
+#include   "application_log.h"
+
+
+class   Http_BufferedReader : protected RingBuffer_Slide
+{
+	inline bool GetTermedString(char * outdata, size_t maxlen,char termchar1, char termchar2);
+	inline bool GetDoubleTermedString(char * outdata, int maxlen,char termchar1, char termchar2);
+	inline bool GetTermedStringInPLace(char ** outdata,char termchars);
+	inline bool GetTermedString(char * outdata, int maxlen,char * termchars);
+	inline bool GetSizeString(StrTargetBuffer  & outdata);
+public:
+	inline Http_BufferedReader(int in_size = 8192) ;
+//
+// The Read Message Interface
+//
+	inline void ReSet(void); 
+	inline int PumpCRRead(char * data, int   maxdata, Socket_TCP &sck);
+	inline int PumpHTTPHeaderRead(char * data, int   maxdata, Socket_TCP &sck);
+    inline int PumpSizeRead(StrTargetBuffer  & outdata,Socket_TCP &sck);
+    inline int PumpEofRead(StrTargetBuffer  & outdata,Socket_TCP &sck);
+	//inline int PumpMessageReader(CoreMessage &inmsg, Socket_TCP &sck);
+
+
+    template < class SOCK_TYPE>
+        inline int ReadPump(SOCK_TYPE &sck)
+    {		
+        int		answer = 0;
+        size_t		readsize = BufferAvailabe();
+
+        if(readsize < 1)
+        {
+            FullCompress();
+            readsize = BufferAvailabe();
+        }
+
+
+        if(readsize > 0)
+        {
+            char * ff = GetBufferOpen();
+            int gotbytes = sck.RecvData(ff,(int)readsize);
+
+
+            if(gotbytes < 0)  // some error
+            {
+                int er = GETERROR(); 
+                // if(err != LOCAL_BLOCKING_ERROR )
+                if(!sck.ErrorIs_WouldBlocking(gotbytes) )
+                {
+                    answer = -3; 
+                    LOGINFO("Http_BufferedReader::ReadPump->Socket Level Read Error %d %d %d %s",er,gotbytes,errno,sck.GetPeerName().get_ip_port().c_str());
+                }
+                else
+                {
+                    answer = 0; // try again nothing to read
+                }
+            }
+            else if(gotbytes > 0) // ok got some lets process it
+            {
+
+                _EndPos	+=  gotbytes;
+                answer = 1;
+            }
+            else   // 0 mean other end disconect arggggg
+            {
+                answer = -1;
+                LOGWARNING("Http_BufferedReader::ReadPump->Other End Closed Normal [%s]",sck.GetPeerName().get_ip_port().c_str());
+            }
+        }		
+        else
+        {
+            std::string addstr = sck.GetPeerName().get_ip_port();
+            LOGWARNING("Http_BufferedReader::ReadPump->** Very Important** No Internal buffer left for read[%s] BufferSIze=[%d][%d]",
+                addstr.c_str(),
+                AmountBuffered(),
+                BufferAvailabe()
+                );
+
+            answer = -2;
+        }
+        return answer;
+    }
+
+};
+
+#include "http_bufferedreader.i"
+
+#endif //__BUFFEREDREADER_GM_H__
+
+

+ 296 - 0
direct/src/http/http_bufferedreader.i

@@ -0,0 +1,296 @@
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::GetTermedString
+// Description	    :  a function that will peal a terminated string from the buffer
+//  
+// Return type		: inline bool 
+// Argument         : char * outdata
+// Argument         : int maxlen
+// Argument         : char termchar1
+// Argument         : char termchar2
+////////////////////////////////////////////////////////////////////
+inline bool Http_BufferedReader::GetTermedString(char * outdata, size_t maxlen,char termchar1, char termchar2)
+{
+	bool answer = false;
+	size_t DataAvail = FastAmountBeffered();
+	size_t MaxRead = maxlen;
+	if(MaxRead > DataAvail)
+		MaxRead = DataAvail;
+	
+	char	 * wrk = FastGetMessageHead();
+	for(size_t x=0; x< MaxRead; x++)
+	{
+		if(wrk[x] == termchar1 || wrk[x] == termchar2)
+		{
+			memcpy(outdata,wrk,x);
+			outdata[x] = '\0';
+			_StartPos += x+1;				
+			Compress();
+			answer = true;
+			break;
+		}			
+	}
+	return answer;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::GetDoubleTermedString
+// Description	    : a function that will peal a terminated string from the buffer
+//
+//			This is the interface for a web request....
+//  
+// Return type		: inline bool 
+// Argument         : char * outdata
+// Argument         : int maxlen
+// Argument         : char termchar1
+// Argument         : char termchar2
+////////////////////////////////////////////////////////////////////
+inline bool Http_BufferedReader::GetDoubleTermedString(char * outdata, int maxlen,char termchar1, char termchar2)
+{
+	bool answer = false;
+	size_t DataAvail = FastAmountBeffered();
+	size_t MaxRead = maxlen;
+	if(MaxRead > DataAvail)
+		MaxRead = DataAvail;
+	
+	char	 * wrk = FastGetMessageHead();
+	for(size_t x=1; x< MaxRead; x++)
+	{
+		if(
+			(wrk[x] == termchar1 && wrk[x-1] == termchar1) ||
+			(wrk[x] == termchar2 && wrk[x-1] == termchar2) ||
+			( x >= 3 && wrk[x] == termchar1 && wrk[x-2] == termchar1 &&  wrk[x-1] == termchar2 && wrk[x-3] == termchar2 ) ||
+			( x >= 3 && wrk[x] == termchar2 && wrk[x-2] == termchar2 &&  wrk[x-1] == termchar1 && wrk[x-3] == termchar1 ) 
+			)
+		{
+			memcpy(outdata,wrk,x);
+			outdata[x] = '\0';
+			_StartPos += x+1;				
+			Compress();
+			answer = true;
+			break;
+		}			
+	}
+	return answer;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::GetTermedStringInPLace
+// Description	    :  Will peal a string inplace for reading
+//  
+// Return type		: inline bool 
+// Argument         : char ** outdata
+// Argument         : char termchars
+////////////////////////////////////////////////////////////////////
+inline bool Http_BufferedReader::GetTermedStringInPLace(char ** outdata,char termchars)
+{
+	bool answer = false;
+	Compress();
+	size_t MaxRead = FastAmountBeffered();
+	char	 * wrk = FastGetMessageHead();
+	for(size_t x=0; x< MaxRead; x++)
+	{
+		if(wrk[x] == termchars)
+		{				
+			*outdata = wrk;		
+			wrk[x] = '\0';
+			_StartPos += x+1;				
+			answer = true;
+			break;
+		}			
+	}
+	return answer;
+}
+
+
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::GetTermedString
+// Description	    : do a read of a termed string not in place
+//  
+// Return type		: bool 
+// Argument         : char * outdata
+// Argument         : int maxlen
+// Argument         : char * termchars
+////////////////////////////////////////////////////////////////////
+bool Http_BufferedReader::GetTermedString(char * outdata, int maxlen,char * termchars)
+{
+	bool answer = false;
+	size_t DataAvail = FastAmountBeffered();
+	size_t MaxRead = maxlen;
+	if(MaxRead > DataAvail)
+		MaxRead = DataAvail;
+	int tstrsize = (int)strlen(termchars);
+	
+	char	 * wrk = FastGetMessageHead();
+	for(size_t x=0; x< MaxRead; x++)
+	{
+		if(memcmp(&wrk[x],termchars,tstrsize) == 0)
+		{
+			memcpy(outdata,wrk,x);
+			outdata[x] = '\0';
+			_StartPos += x+tstrsize;				
+			Compress();
+			answer = true;
+			break;
+		}			
+	}
+	return answer;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::Http_BufferedReader
+// Description	    :  constructore .. passes size up to ring buffer
+//  
+// Return type		: inline 
+// Argument         : int in_size
+////////////////////////////////////////////////////////////////////
+inline Http_BufferedReader::Http_BufferedReader(int in_size) : RingBuffer_Slide(in_size)
+{	
+	
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::ReSet
+// Description	    :  Reaset all read content.. IE zero's out buffer...
+//  
+//	If you lose framing this will not help
+//
+// Return type		: inline void 
+// Argument         : void
+////////////////////////////////////////////////////////////////////
+inline void Http_BufferedReader::ReSet(void) 
+{
+	ResetContent();
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::PumpCRRead
+// Description	    :  a upcall function to read a CR object off buffer
+//  
+// Return type		: inline int 
+// Argument         : char * data
+// Argument         : int   maxdata
+// Argument         : Socket_TCP &sck
+////////////////////////////////////////////////////////////////////
+inline int Http_BufferedReader::PumpCRRead(char * data, int   maxdata, Socket_TCP &sck)
+{	
+	if(GetTermedString(data,maxdata,'\r','\n') == true)
+		return 1;
+	
+	int rp = ReadPump(sck);
+	if(rp == 0)
+		return 0;
+	
+	if(rp < 1)
+		return -1;
+	
+	if(GetTermedString(data,maxdata,'\r','\n') == true)
+		return 1;
+	
+	
+	return 0;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: Http_BufferedReader::PumpHTTPHeaderRead
+// Description	    :  Will read a HTTP head ,, GET ..... or responce from web server
+//  
+// Return type		: inline int 
+// Argument         : char * data
+// Argument         : int   maxdata
+// Argument         : Socket_TCP &sck
+////////////////////////////////////////////////////////////////////
+inline int Http_BufferedReader::PumpHTTPHeaderRead(char * data, int   maxdata, Socket_TCP &sck)
+{
+	
+	if(GetDoubleTermedString(data,maxdata,'\r','\n') == true)
+		return 1;
+	
+	
+	int rp = ReadPump(sck);
+	if(rp == 0)
+		return 0;
+	
+	if(rp < 1)
+		return -1;
+	
+	if(GetDoubleTermedString(data,maxdata,'\r','\n') == true)
+		return 1;
+	
+	return 0;
+}
+
+inline int Http_BufferedReader::PumpSizeRead(StrTargetBuffer  & outdata,Socket_TCP &sck)
+{
+	    if(GetSizeString(outdata) == true)
+		    return 1;	
+	
+	    int rp = ReadPump(sck);
+	    if(rp == 0)
+		    return 0;
+	
+	    if(rp < 1)
+		    return -1;
+	
+	    if(GetSizeString(outdata) == true)
+		    return 1;
+	
+    	return 0;
+}
+
+inline int Http_BufferedReader::PumpEofRead(StrTargetBuffer  & outdata,Socket_TCP &sck)
+{	
+    // do a quick read
+    {		
+      	size_t MaxRead = FastAmountBeffered();
+        if(MaxRead > 0)
+        {
+		    char *ff = FastGetMessageHead();
+		    outdata.append(ff,MaxRead);
+		    _StartPos += MaxRead;				
+       		Compress();
+        }
+    }		
+	
+    // pump the reader	
+	int rp = ReadPump(sck);
+	if(rp == 0)
+		return 0;
+	
+	if(rp== -1) // eof
+	{
+	    // if eof clean the mess
+        size_t MaxRead = FastAmountBeffered();
+        if(MaxRead > 0)
+        {
+		    char *ff = FastGetMessageHead();
+		    outdata.append(ff,MaxRead);
+		    _StartPos += MaxRead;				
+       		Compress();
+        }
+	    return 1;
+	}
+	    
+	
+	if(rp < 1)
+		return -1;
+	
+	
+	return 0;
+}
+//////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+inline bool Http_BufferedReader::GetSizeString(StrTargetBuffer  & outdata)
+{
+  	size_t DataAvail = FastAmountBeffered();
+	size_t MaxRead = outdata.left_to_fill();
+	if(MaxRead > DataAvail)
+		MaxRead = DataAvail;
+	
+	char	 * wrk = FastGetMessageHead(); 	 
+	if(MaxRead > 0)
+	{
+	
+		char *ff = FastGetMessageHead();
+		outdata.append(ff,MaxRead);
+		_StartPos += MaxRead;				
+		return true;
+	}	
+	
+    return false;	
+};
+
+

+ 4 - 0
direct/src/http/http_composite1.cxx

@@ -0,0 +1,4 @@
+#include   "http_connection.cxx"       
+#include   "parsedhttprequest.cxx"
+#include   "http_request.cxx"
+

+ 166 - 0
direct/src/http/http_connection.cxx

@@ -0,0 +1,166 @@
+#include "http_connection.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+HttpConnection::HttpConnection(SOCKET sck,Socket_Address &inaddr) :
+    _Timer(Time_Span(10,0)) ,
+    _MyAddress(inaddr),
+    _state(READING_HEADER)
+{
+    SetSocket(sck);
+    SetNonBlocking();
+    SetReuseAddress();
+
+    _writer.reserve(102400);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+HttpConnection::~HttpConnection(void)
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+const Socket_Address & HttpConnection::GetMyAddress(void)
+{
+    return _MyAddress;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int  HttpConnection::DoReadHeader(char * message, int buffersize,Time_Clock &currentTime)
+{
+    int ans = _Reader.PumpHTTPHeaderRead(message,buffersize,*this);
+
+    if(ans != 0)
+    {
+        if(ans > 0)
+            _headerDetail.assign(message,buffersize);
+
+        return ans;
+    }
+
+    if(_Timer.Expired(currentTime) == true)
+    {
+		return -1;
+    }
+
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int  HttpConnection::DoReadBody(char * message1, int buffersize,Time_Clock &currentTime)
+{
+    int ans = _Reader.PumpSizeRead(_bodyDetail,*this);
+
+    if(ans != 0)
+    {
+
+        return ans;
+    }
+
+    if(_Timer.Expired(currentTime) == true)
+    {
+		return -1;
+    }
+
+    // ok lets process this thing..
+    _state = WAITING_TO_FINALIZE;
+
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int HttpConnection::ReadIt(char * message, int buffersize,Time_Clock &currentTime)
+{		
+    switch (_state)
+    {
+    case(READING_HEADER):
+        return DoReadHeader(message, buffersize,currentTime);
+        break;
+
+    case(READING_POST):
+        return DoReadBody(message, buffersize,currentTime);
+        break;
+
+    case(WAITING_TO_FINALIZE):
+        return TryAndFinalize();
+        break;
+
+    case(WRITING_DATA):
+        return CloseStateWriter(currentTime);
+        break;
+    default:
+        break;
+
+    };
+    return ConnectionDoClose;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CloseState HttpConnection::ProcessMessage(char * message,Time_Clock &currentTime)
+{
+    if(_state == READING_POST )
+    {
+         _state = WAITING_TO_FINALIZE;
+         return ConnectionDoClose;
+    }
+
+
+    if(_parser.ParseThis(message) != true)
+    {
+        Reset();
+        return ConnectionDoClose;
+    }
+    // if it is a post go into read details mode and 
+    // wait to get the post data..
+    // we do not support any other methoid today
+    if(_parser.GetRequestType() == "POST")
+    {
+        int context_length = _parser.getContentLength();
+        if(context_length > 0)
+        {
+            //_DoingExtraRead = true;
+            _state = READING_POST;
+            _bodyDetail.SetDataSize(context_length);
+            return ConnectionDoNotClose;
+        }
+    }
+
+    _state = WAITING_TO_FINALIZE;
+  
+    _parser.SetBodyText(_bodyDetail);
+    _Timer.ResetTime(currentTime);
+
+    if(BuildPage(_writer,_parser) != true)
+        return ConnectionDoClose;
+
+    if(_state == WRITING_DATA)
+    {
+        if(CloseStateWriter(currentTime) <0)
+            return ConnectionDoClose;
+    }
+
+    return ConnectionDoNotClose;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int HttpConnection::CloseStateWriter(Time_Clock &currentTime)
+{
+    int fans = _writer.Flush(*this);	// write error
+    if(fans < 0)
+        return -1;		
+
+    if(_writer.AmountBuffered() <= 0)	// all done
+        return -1;		
+
+    if(_Timer.Expired(currentTime) == true)	// too long
+        return -1;
+
+    return 0;	// keep trying
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void HttpConnection::Reset()
+{
+    _state = ABORTING;
+    Close();
+    _Timer.ForceToExpired();
+}
+
+

+ 61 - 0
direct/src/http/http_connection.h

@@ -0,0 +1,61 @@
+#ifndef HttpConnection_H 
+#define HttpConnection_H 
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+#include "parsedhttprequest.h"
+#include "baseincomingset.h"
+
+#include "bufferedwriter_growable.h"
+#include "http_bufferedreader.h"
+
+
+class HttpConnection : public Socket_TCP 
+{
+protected:
+    Http_BufferedReader			    _Reader;
+    BufferedWriter_Growable     _writer;
+    Socket_Address				_MyAddress;
+
+    Time_Out					_Timer;
+
+    enum    STATE_CONNECTIONS {  
+        READING_HEADER =1, 
+        READING_POST =2, 
+        WAITING_TO_FINALIZE =3,
+        WRITING_DATA =4,
+        ABORTING = 5,
+    };
+
+
+    STATE_CONNECTIONS                    _state;        
+
+
+    ParsedHttpRequest           _parser;
+
+    StrTargetBuffer         _bodyDetail;
+    std::string             _headerDetail;
+
+    int                    CloseStateWriter(Time_Clock &currentTime);
+
+public:
+    virtual ~HttpConnection(void);
+    const Socket_Address & GetMyAddress(void);
+    virtual bool BuildPage(	BufferedWriter_Growable	&_writer, ParsedHttpRequest  &parser) = 0;
+    HttpConnection(SOCKET sck,Socket_Address &inaddr) ;
+
+    CloseState             ProcessMessage(char * message,Time_Clock &currentTime);
+    int                    DoReadHeader(char * message, int buffersize,Time_Clock &currentTime);	
+    int                    DoReadBody(char * message, int buffersize,Time_Clock &currentTime);	
+    int                    ReadIt(char * message, int buffersize,Time_Clock &currentTime);
+    void                   Reset();
+
+    virtual CloseState      TryAndFinalize()  {  _state = WRITING_DATA;  ;return ConnectionDoNotClose; };
+
+    std::string             GetFullmessage() { return _headerDetail + _bodyDetail; };
+};
+
+
+#endif  // HttpConnection_H 
+
+
+

+ 37 - 0
direct/src/http/http_request.cxx

@@ -0,0 +1,37 @@
+#include "socket_base.h"
+
+
+#include "http_connection.h"
+#include "baseincomingset.h"
+#include "socket_base.h"
+
+
+#include "http_request.h"
+
+
+typedef BaseIncomingSet< Http_Request , Socket_TCP_Listen , char [10240], char *>  Http_Source_BaseIncomingSet;
+static std::set< Http_Request * >                       Global_WebRequests_pendingNotify;
+static Http_Source_BaseIncomingSet                      Global_HttpManager;
+
+bool Http_Request::HttpManager_Initialize( unsigned short port)
+{
+    init_network();
+    Socket_Address address;
+    address.set_port(port);
+    return Global_HttpManager.init(address);
+}
+
+Http_Request * Http_Request::HttpManager_GetARequest()
+{
+    Time_Clock  Know;
+    Global_HttpManager.PumpAll(Know);
+    Http_Request * answer = NULL;
+    std::set< Http_Request * >::iterator ii = Global_WebRequests_pendingNotify.begin();
+    if(ii != Global_WebRequests_pendingNotify.end())
+    {   
+        answer = *ii;
+        Global_WebRequests_pendingNotify.erase(ii);   
+    }
+    return   answer;
+}
+

+ 108 - 0
direct/src/http/http_request.h

@@ -0,0 +1,108 @@
+#ifndef  Http_Request_H_
+#define  Http_Request_H_
+
+class Http_Request;
+extern std::set< Http_Request * >                       Global_WebRequests_pendingNotify;
+ 
+class Http_Request : public HttpConnection
+{
+public:
+    Http_Request(SOCKET sck,Socket_Address &inaddr) : HttpConnection(sck,inaddr) 
+    {
+    };
+
+    ~Http_Request() 
+    {
+        Global_WebRequests_pendingNotify.erase(this);
+    };
+	bool BuildPage(	BufferedWriter_Growable	&_writer, ParsedHttpRequest  &parser)
+    {
+        Global_WebRequests_pendingNotify.insert((Http_Request *)this);
+
+        _state = WAITING_TO_FINALIZE;
+        _Timer.ResetAll(Time_Clock::GetCurrentTime(),Time_Span(9999999,0));
+        return true;
+    };
+
+    CloseState      TryAndFinalize()  
+    {
+        return  ConnectionDoNotClose;
+    };
+
+PUBLISHED:
+
+    std::string GetRequestType() 
+    {
+        return _parser.GetRequestType();
+    }
+
+    std::string GetRawRequest()
+    {
+        return _parser.GetRawRequest();
+    }
+
+    std::string GetRequestURL()
+    {
+        return _parser.GetRequestURL();
+    }
+
+    std::string GetSourceAddress() 
+    {
+        return _MyAddress.get_ip_port();
+    }
+
+    void   AppendToResponce(const std::string &in)
+    {
+        _writer+=in;
+    }
+
+
+    void SendThisResponce(const std::string &in)
+    {
+        _writer+=in;
+        Finish();
+    }
+
+    void Finish()  
+    {    
+        _Timer.ResetAll(Time_Clock::GetCurrentTime(),Time_Span(10,0));
+        _state  =  WRITING_DATA; 
+    };
+    void Abort()   
+    {
+        _state =   ABORTING; 
+    };
+
+
+    bool HasOption(std::string in)
+    {
+        const std::string * answer = _parser.GetOption(in);
+        if(answer != NULL)
+	   return true;
+        return false;
+    }
+
+    char * GetOption(std::string in)
+    {
+        const std::string * answer = _parser.GetOption(in);
+        if(answer != NULL)
+	   return (char *)answer->c_str();
+        return "";
+    }
+    std::string   GetRequestOptionString()
+    {
+        return _parser.GetRequestOptionString();
+    }
+
+   static bool HttpManager_Initialize( unsigned short port);
+   static Http_Request * HttpManager_GetARequest();
+
+
+};
+
+
+
+
+
+
+#endif  // Http_Request_H_

+ 214 - 0
direct/src/http/parsedhttprequest.cxx

@@ -0,0 +1,214 @@
+#pragma warning(disable : 4789)
+#pragma warning(disable : 4786)
+
+#include "parsedhttprequest.h"
+
+////////////////////////////////////////////////////////////////////
+inline std::string & trimleft_inplace(std::string & s)
+{
+	s.erase(0, s.find_first_not_of(" \t\n\r"));
+	return s;
+}
+
+
+////////////////////////////////////////////////////////////////////
+inline std::string & trimright_inplace(std::string & s)
+{
+	size_t idx = s.find_last_not_of(" \t\n\r");
+
+	if (std::string::npos == idx)
+	{
+		s.erase();
+	}
+	else
+	{
+		char c	= s.at(idx);
+		s.erase(idx, std::string::npos);	
+		s.append(1, c);
+	}
+
+	return s;
+}
+////////////////////////////////////////////////////////////////////
+inline std::string & trim_inplace(std::string & s)
+{
+	trimleft_inplace(s);
+	trimright_inplace(s);
+	return s;
+}
+
+inline std::string  trim_tonew(const std::string &in)
+{
+	std::string ss = in;
+	return trim_inplace(ss);	
+}
+
+
+
+
+std::string ParsedHttpRequest::deCanonicalize(std::string &inval)
+{
+	std::string work("");
+	unsigned int x=0;
+	while (x < inval.size())
+	{
+		switch(inval[x])
+		{
+		case('+'):
+			work+=' ';
+			x++;
+			break;
+			
+		case('%'):
+			if(x+2 < inval.size())
+			{
+				x++;
+				char aa[5];
+				char * end;
+				aa[0] = inval[x++];
+				aa[1] = inval[x++];
+				aa[2] = '\0';
+				char	c = ( char ) strtoul(aa,&end,16);
+				work+=c;
+			}
+			else
+				x+=3;
+			break;
+			
+		default:
+			work+=inval[x++]; 
+			break;
+		}			
+	}
+	return work;
+}
+
+size_t  ParsedHttpRequest::PullCR(std::string &src, std::string &dst)
+{
+	size_t offset = src.find(' ');
+	if(offset >= 0 )
+	{
+		dst = src.substr(0,offset);
+		src = src.substr(offset+1);
+	}
+	return offset;
+}
+
+
+void ParsedHttpRequest::clear(void)
+{
+	_RequestType = "";
+	_parameters.clear();
+}
+
+const std::string * ParsedHttpRequest::GetOption(const std::string & query)
+{
+	std::map<std::string,std::string>::iterator ii;
+	ii = _parameters.find(query);
+	if(ii == _parameters.end())
+		return NULL;
+	
+	return &ii->second;
+}
+
+
+bool ParsedHttpRequest::GetOption(const std::string & query, std::string & out_value)
+{
+	std::map<std::string,std::string>::iterator ii;
+	ii = _parameters.find(query);
+	if(ii == _parameters.end())
+	{
+		out_value	= "";
+		return false;
+	}
+	out_value = ii->second;
+	return true;
+}
+
+bool ParsedHttpRequest::ParseThis(char * request)
+{
+    _Raw_Text = request;
+//    printf("%s\n\n",request);
+    
+
+    std::string work1(_Raw_Text);
+    for(size_t pos = work1.find_first_of("\n\r\0") ; pos != std::string::npos ;   pos = work1.find_first_of("\n\r\0") )
+    {
+        std::string  line1 = work1.substr(0,pos);
+        work1 = work1.substr(pos+1);
+        if(line1.size() > 2)
+        {
+//            printf(" Line[%s]\n",line1.c_str());
+            size_t i_pos = line1.find(':');
+            if(i_pos != std::string::npos && i_pos > 1)
+            {
+                std::string noune = trim_tonew(line1.substr(0,i_pos));
+                std::string verb  = trim_tonew(line1.substr(i_pos+1));
+
+                //printf(" Noune [%s][%s]\n",noune.c_str(),verb.c_str());
+                _header_Lines[noune] = verb;
+
+            }
+        }
+    }
+
+    //
+    // Get the url for the request ..
+    //
+	std::string work(request);
+	std::string line1 = work.substr(0,work.find_first_of("\n\r\0"));
+	if(line1.size() < 4)
+		return false;
+	
+	if(PullCR(line1,_RequestType) < 3)
+		return false;
+	
+	if(PullCR(line1,_RequestText) < 1)
+		return false;
+	
+	size_t loc = (int)_RequestText.find('?');
+    if(loc != std::string::npos)
+	{
+		_Requestoptions = _RequestText.substr(loc+1);
+		_RequestText =  _RequestText.substr(0,loc);
+	}
+	
+	return ProcessOptionString(_Requestoptions);
+}
+
+std::string & ParsedHttpRequest::GetRequestURL(void) 
+{ 
+	return _RequestText; 
+};
+
+bool ParsedHttpRequest::ProcessOptionString(std::string str)
+{
+	size_t loc;
+    for(loc = str.find('&'); loc != std::string::npos; loc = str.find('&'))
+	{
+		std::string valset = str.substr(0,loc);
+		str = str.substr(loc+1);
+		if(ProcessParamSet(valset) != true)
+			return false;
+	}
+	return ProcessParamSet(str);
+};
+
+bool ParsedHttpRequest::ProcessParamSet(std::string &str)
+{
+	std::string val("");
+	size_t loc = str.find('=');
+	
+    if(loc != std::string::npos)
+	{
+		val = str.substr(loc+1);
+		str = str.substr(0,loc);	
+		
+		std::string ind1 = deCanonicalize(str);
+		_parameters[ind1] = deCanonicalize(val);
+	}
+	return true;
+}
+
+
+

+ 143 - 0
direct/src/http/parsedhttprequest.h

@@ -0,0 +1,143 @@
+#ifndef __PARSEDHTTPREQUEST_GM_H__
+#define __PARSEDHTTPREQUEST_GM_H__
+
+#include "string"
+#include "map"
+
+
+class ParsedHttpRequest
+{
+protected:
+    std::string             _Raw_Text;
+	std::string				_RequestType;
+	std::string				_RequestText;
+	std::string				_Requestoptions;
+    std::string             _BodyText;
+
+
+	std::map<std::string,std::string>	_parameters;
+    std::map<std::string,std::string>   _header_Lines;
+
+	std::string deCanonicalize(std::string &inval);
+	size_t  PullCR(std::string &src, std::string &dst);
+
+public:
+	void clear(void);
+    const std::string   GetRequestOptionString() { return _Requestoptions; };
+	const std::string * GetOption(const std::string & query);
+	bool GetOption(const std::string & query, std::string & out_value);
+	bool ParseThis(char * request);
+	std::string & GetRequestURL(void);
+    const std::string & GetRawRequest(void) const { return _Raw_Text; };
+    const std::string & GetRequestType(void) const { return _RequestType; };
+	bool ProcessOptionString(std::string str);
+	bool ProcessParamSet(std::string &str);
+
+
+    void SetBodyText(const std::string &  text)
+    {
+        _BodyText = text;
+    }
+
+    const std::string & getBodyText() { return _BodyText; };
+
+    int getContentLength()
+    {
+        int answer = 0;
+        std::map<std::string,std::string>::iterator ii = _header_Lines.find("Content-Length");
+        if(ii != _header_Lines.end())
+            answer = atol(ii->second.c_str());
+
+        return answer;
+    };
+};
+
+/*
+class ParsedHttpResponce
+{
+    std::string             _Raw_Text;
+    std::string             _responce_header;
+    
+    std::map<std::string,std::string>   _header_Lines;
+
+
+public:
+
+    std::string GetresponceCode()
+    {
+        std::string answer;
+
+        size_t pos = _responce_header.find_first_of(" ");
+        if(pos != std::string::npos)
+            answer =   support::trim_tonew(_responce_header.substr(pos,100));
+
+
+        pos = answer.find_first_of(" \t\n\r\0");
+        if(pos != std::string::npos)
+            answer =   support::trim_tonew(answer.substr(0,pos));
+
+
+        return answer;
+    }
+
+    bool ParseThis(const std::string &responce)
+    {   
+        _Raw_Text = responce;
+
+        int line_number = 0;
+        std::string work1(_Raw_Text);
+        for(size_t pos = work1.find_first_of("\n\r\0") ; pos != std::string::npos ;   pos = work1.find_first_of("\n\r\0") )
+        {
+            std::string  line1 = work1.substr(0,pos);
+            work1 = work1.substr(pos+1);
+            if(line1.size() > 2)
+            {
+
+                if(line_number == 0 && line1.substr(0,4) == "HTTP")
+                {
+                    // the first line...
+                    _responce_header = line1;
+//                    printf("[%s]\n",line1.c_str());
+                }
+
+                size_t i_pos = line1.find(':');
+                if(i_pos != std::string::npos && i_pos > 1)
+                {
+                    std::string noune = support::trim_tonew(line1.substr(0,i_pos));
+                    std::string verb  = support::trim_tonew(line1.substr(i_pos+1));
+                    _header_Lines[noune] = verb;
+                }
+                line_number++;
+            }
+        }
+
+
+        return !_responce_header.empty();
+    }
+
+    size_t  PullCR(std::string &src, std::string &dst)
+    {
+        size_t offset = src.find(' ');
+        if(offset >= 0 )
+        {
+            dst = src.substr(0,offset);
+            src = src.substr(offset+1);
+        }
+        return offset;
+    }
+
+    int getContentLength()
+    {
+        int answer = 0;
+        std::map<std::string,std::string>::iterator ii = _header_Lines.find("Content-Length");
+        if(ii != _header_Lines.end())
+            answer = atol(ii->second.c_str());
+
+        return answer;
+    };
+
+};
+*/
+
+#endif //__PARSEDHTTPREQUEST_GM_H__
+

+ 48 - 0
direct/src/http/ringbuffer_slide.h

@@ -0,0 +1,48 @@
+#ifndef __RINGBUFFER_GM_H__
+#define __RINGBUFFER_GM_H__
+////////////////////////////////////////////
+
+// RHH
+////////////////////////////////////////////////////////////////////
+// 	 Class : GmRingBuffer
+// Description :	This is an implemention of the membuffer with ring 
+//	 				buffer interface on it....	
+//					
+//					Main target right know is base class for network
+//					stream buffering both input and output
+//					
+//	see			BufferedReader_Gm
+//				BufferedWriter_Gm
+//
+////////////////////////////////////////////////////////////////////
+#include "membuffer.h"
+class   RingBuffer_Slide   : protected MemBuffer
+{
+protected:
+	size_t			_StartPos;
+	size_t			_EndPos;
+	inline char	*	GetMessageHead(void);
+	inline char	*	GetBufferOpen(void);
+	inline void ForceWindowSlide(void);
+#define FastGetMessageHead() (_Buffer+_StartPos)
+#define FastAmountBeffered() (_EndPos - _StartPos)
+
+inline bool PutFast(const char * data, size_t len);
+
+public:
+	inline size_t		AmountBuffered(void);
+	inline size_t      BufferAvailabe(void);
+	inline void		ResetContent(void);
+
+	inline RingBuffer_Slide(size_t in_size = 4096);
+	inline void FullCompress(void);
+	inline void Compress(void);
+	inline bool Put(const char * data, size_t len);
+	inline bool Get(char * data, size_t len);
+};
+
+#include "ringbuffer_slide.i"
+
+#endif //__RINGBUFFER_GM_H__
+
+

+ 187 - 0
direct/src/http/ringbuffer_slide.i

@@ -0,0 +1,187 @@
+
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::GetMessageHead
+// Description	    :  This will get a pointer to the fist undelivered data in buffer
+// Return type		: char *
+// Argument         : void
+//////////////////////////////////////////////////////////
+inline char	*	RingBuffer_Slide::GetMessageHead(void) 
+{ 
+	return _Buffer+_StartPos;
+}
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::GetBufferOpen
+// Description	    : This will get the first writabe section of the buffer space
+// Return type		: 
+// Argument         : void
+//////////////////////////////////////////////////////////
+inline char	*	RingBuffer_Slide::GetBufferOpen(void) 
+{
+	return _Buffer+_EndPos; 
+}
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::ForceWindowSlide
+// Description	    :  Will force a compression of data // shift left to start position
+// Return type		: inline void 
+// Argument         : void
+//////////////////////////////////////////////////////////
+inline void RingBuffer_Slide::ForceWindowSlide(void)
+{
+	size_t len = AmountBuffered();
+	if(len > 0 && _StartPos != 0)  // basic flush left..
+	{
+		memmove(_Buffer,GetMessageHead(),len);
+		_StartPos = 0;
+		_EndPos = len;		
+	}
+}
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::AmountBuffered
+// Description	    : Will report the number of unread chars in buffer
+// Return type		: int
+// Argument         : void
+//////////////////////////////////////////////////////////
+inline size_t		RingBuffer_Slide::AmountBuffered(void) 
+{ 
+	return _EndPos - _StartPos; 
+}
+
+
+/////////////////////////////////////////////////////////////
+// Function name	:      RingBuffer_Slide::BufferAvailabe
+// Description	    : Will report amount of data that is contiguas that can be writen at
+//						the location returned by GetBufferOpen
+// Return type		: inline int 
+// Argument         : void
+//////////////////////////////////////////////////////////
+inline size_t      RingBuffer_Slide::BufferAvailabe(void) 
+{ 
+	return GetBufferSize() - _EndPos; 
+}
+
+
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::ResetContent
+// Description	    : Throw away all inread information
+// Return type		: void 
+// Argument         : void
+//////////////////////////////////////////////////////////
+void RingBuffer_Slide::ResetContent(void) 
+{ 
+	_StartPos = 0; 
+	_EndPos = 0; 
+}
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::RingBuffer_Slide
+// Description	    : 
+// Return type		: inline 
+// Argument         : int in_size
+//////////////////////////////////////////////////////////
+inline RingBuffer_Slide::RingBuffer_Slide(size_t in_size) : MemBuffer(in_size)
+{			
+	_EndPos = 0;
+	_StartPos = 0;
+}
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::FullCompress
+// Description	    : Force a compress of the data
+// Return type		: inline void 
+// Argument         : void
+//////////////////////////////////////////////////////////
+inline void RingBuffer_Slide::FullCompress(void)
+{
+	if(_StartPos == _EndPos)
+	{
+		_StartPos = 0;
+		_EndPos = 0;
+	}
+	else 
+	{
+		ForceWindowSlide();
+	}	
+}
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::Compress
+// Description	    : Try and do a intelegent compress of the data space
+//						the algorithem is really stupid right know.. just say if i have 
+//							read past 1/2 my space do a compress...Im open for sugestions
+//	
+//
+// Return type		: inline void 
+// Argument         : void
+//////////////////////////////////////////////////////////
+inline void RingBuffer_Slide::Compress(void)
+{
+	if(_StartPos == _EndPos)
+	{
+		_StartPos = 0;
+		_EndPos = 0;
+	}
+	else if(_StartPos >= GetBufferSize() / 2) 
+	{
+		ForceWindowSlide();
+	}	
+}
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::Put
+// Description	    : Adds Data to a ring Buffer
+//						Will do a compress if needed so pointers suplied by Get Call are no longer valide
+//
+// Return type		: inline bool 
+// Argument         : char * data
+// Argument         : int len
+//////////////////////////////////////////////////////////
+inline bool RingBuffer_Slide::Put(const char * data, size_t len)
+{
+	bool answer = false;
+	
+	if(len > BufferAvailabe() )
+		Compress();
+	
+	if(len <= BufferAvailabe() )
+	{
+		memcpy(GetBufferOpen(),data,len);
+		_EndPos += len;
+		answer = true;
+	}
+	return answer;
+}
+////////////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::PutFast
+// Description	    : 
+//  
+// Return type		: inline bool 
+// Argument         : const char * data
+// Argument         : int len
+////////////////////////////////////////////////////////////////////
+inline bool RingBuffer_Slide::PutFast(const char * data, size_t len)
+{
+	// no checking be carefull
+	memcpy(GetBufferOpen(),data,len); // should i be using memcopy..
+	_EndPos += len;
+	return true;
+}
+
+/////////////////////////////////////////////////////////////
+// Function name	: RingBuffer_Slide::Get
+// Description	    : will copy the data ..
+//				false indicates not enogh data to read .. sorry...
+//
+// Return type		: inline bool 
+// Argument         : char * data
+// Argument         : int len
+//////////////////////////////////////////////////////////
+inline bool RingBuffer_Slide::Get(char * data, size_t len)
+{
+	bool answer = false;
+	
+	if(len <= AmountBuffered() )
+	{
+		memcpy(data,GetMessageHead(),len);
+		_StartPos += len;
+		Compress();
+		answer = true;
+	}
+	return answer;
+}
+

+ 31 - 0
direct/src/http/strtargetbuffer.h

@@ -0,0 +1,31 @@
+#ifndef   StrTargetBuffer_h_
+#define   StrTargetBuffer_h_
+
+#include <string>
+
+class  StrTargetBuffer : public std::string 
+{
+    size_t     _target_size;
+public:
+    StrTargetBuffer() : std::string(), _target_size(0)
+    {
+    }
+
+    size_t  left_to_fill() 
+    { 
+        if(_target_size < size())
+            return 0;
+
+        return _target_size - size();
+    };
+
+    void SetDataSize(size_t  target)
+    {
+        _target_size = target;
+    }
+
+    size_t  GetTargetSize() { return _target_size; };
+};
+
+#endif   // StrTargetBuffer_h_
+