Dependents:   SimpleLCDClock readCard2Twitter_http AnalogClock_StepperMotor_NTP ServoCamV1

Revision:
0:a2dd0ba6cd2d
Child:
1:7043cc0db03c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/services/http/client/HttpClient.h	Mon May 24 10:24:38 2010 +0000
@@ -0,0 +1,180 @@
+#ifndef HTTP_CLIENT_H
+#define HTTP_CLIENT_H
+
+class HttpData;
+
+#include "if/net/net.h"
+#include "api/TcpSocket.h"
+#include "api/DnsRequest.h"
+#include "HttpData.h"
+#include "mbed.h"
+
+#include <string>
+using std::string;
+
+#include <map>
+using std::map;
+
+#define HTTP_REQUEST_TIMEOUT 30000//15000
+#define HTTP_PORT 80
+
+enum HttpResult
+{
+  HTTP_OK,
+  HTTP_PROCESSING,
+  HTTP_PARSE, //URI Parse error
+  HTTP_DNS, //Could not resolve name
+  HTTP_PRTCL, //Protocol error
+  HTTP_NOTFOUND, //404 Error
+  HTTP_REFUSED, //403 Error
+  HTTP_ERROR, //xxx error
+  HTTP_TIMEOUT, //Connection timeout
+  HTTP_CONN //Connection error
+};
+
+
+
+class HttpClient : protected NetService
+{
+public:
+  HttpClient();
+  virtual ~HttpClient();
+  
+  void basicAuth(const char* user, const char* password); //Basic Authentification
+  
+  //High Level setup functions
+  HttpResult get(const char* uri, HttpData* pDataIn); //Blocking
+  HttpResult get(const char* uri, HttpData* pDataIn, void (*pMethod)(HttpResult)); //Non blocking
+  template<class T> 
+  //Linker bug : Must be defined here :(
+  HttpResult get(const char* uri, HttpData* pDataIn, T* pItem, void (T::*pMethod)(HttpResult)) //Non blocking
+  {
+    setOnResult(pItem, pMethod);
+    doGet(uri, pDataIn);
+    return HTTP_PROCESSING;
+  }
+  
+  HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn); //Blocking
+  HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn, void (*pMethod)(HttpResult)); //Non blocking
+  template<class T> 
+  //Linker bug : Must be defined here :(
+  HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn, T* pItem, void (T::*pMethod)(HttpResult)) //Non blocking  
+  {
+    setOnResult(pItem, pMethod);
+    doPost(uri, dataOut, pDataIn);
+    return HTTP_PROCESSING;
+  }
+  
+  void doGet(const char* uri, HttpData* pDataIn);  
+  void doPost(const char* uri, const HttpData& dataOut, HttpData* pDataIn); 
+  
+  void setOnResult( void (*pMethod)(HttpResult) );
+  class CDummy;
+  template<class T> 
+  //Linker bug : Must be defined here :(
+  void setOnResult( T* pItem, void (T::*pMethod)(HttpResult) )
+  {
+    m_pCb = NULL;
+    m_pCbItem = (CDummy*) pItem;
+    m_pCbMeth = (void (CDummy::*)(HttpResult)) pMethod;
+  }
+  
+  void setTimeout(int ms);
+  
+  virtual void poll(); //Called by NetServices
+  
+  int getHttpResponseCode();
+  void setRequestHeader(const string& header, const string& value);
+  string& getResponseHeader(const string& header);
+  void resetRequestHeaders();
+  
+protected:
+  void resetTimeout();
+  
+  void init();
+  void close();
+  
+  void setup(const char* uri, HttpData* pDataOut, HttpData* pDataIn); //Setup request, make DNS Req if necessary
+  void connect(); //Start Connection
+  
+  int  tryRead(); //Read data and try to feed output
+  void readData(); //Data has been read
+  void writeData(); //Data has been written & buf is free
+  
+  void onTcpSocketEvent(TcpSocketEvent e);
+  void onDnsReply(DnsReply r);
+  void onResult(HttpResult r); //Called when exchange completed or on failure
+  void onTimeout(); //Connection has timed out
+  
+private:
+  HttpResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available
+
+  bool readHeaders(); //Called first when receiving data
+  bool writeHeaders(); //Called to create req
+  int readLine(char* str, int maxLen);
+  
+  enum HTTP_METH
+  {
+    HTTP_GET,
+    HTTP_POST,
+    HTTP_HEAD
+  };
+  
+  HTTP_METH m_meth;
+  
+  CDummy* m_pCbItem;
+  void (CDummy::*m_pCbMeth)(HttpResult);
+  
+  void (*m_pCb)(HttpResult);
+  
+  TcpSocket* m_pTcpSocket;
+  map<string, string> m_reqHeaders;
+  map<string, string> m_respHeaders;
+  
+  Timer m_watchdog;
+  int m_timeout;
+  
+  DnsRequest* m_pDnsReq;
+  
+  Host m_server;
+  string m_path;
+  
+  bool m_closed;
+  
+  enum HttpStep
+  {
+   // HTTP_INIT,
+    HTTP_WRITE_HEADERS,
+    HTTP_WRITE_DATA,
+    HTTP_READ_HEADERS,
+    HTTP_READ_DATA,
+    HTTP_READ_DATA_INCOMPLETE,
+    HTTP_DONE,
+    HTTP_CLOSED
+  };
+  
+  HttpStep m_state;
+  
+  HttpData* m_pDataOut;
+  HttpData* m_pDataIn;
+  
+  bool m_dataChunked; //Data is encoded as chunks
+  int m_dataPos; //Position in data
+  int m_dataLen; //Data length
+  char* m_buf;
+  char* m_pBufRemaining; //Remaining
+  int m_bufRemainingLen; //Data length in m_pBufRemaining
+  
+  int m_httpResponseCode;
+  
+  HttpResult m_blockingResult; //Result if blocking mode
+  
+};
+
+//Including data containers here for more convenience
+#include "data/HttpFile.h"
+#include "data/HttpStream.h"
+#include "data/HttpText.h"
+#include "data/HttpMap.h"
+
+#endif