Dependents:   SimpleLCDClock readCard2Twitter_http AnalogClock_StepperMotor_NTP ServoCamV1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HttpClient.h Source File

HttpClient.h

00001 
00002 /*
00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00004  
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011  
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014  
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #ifndef HTTP_CLIENT_H
00025 #define HTTP_CLIENT_H
00026 
00027 class HttpData;
00028 
00029 #include "if/net/net.h"
00030 #include "api/TcpSocket.h"
00031 #include "api/DnsRequest.h"
00032 #include "HttpData.h"
00033 #include "mbed.h"
00034 
00035 #include <string>
00036 using std::string;
00037 
00038 #include <map>
00039 using std::map;
00040 
00041 #define HTTP_REQUEST_TIMEOUT 30000//15000
00042 #define HTTP_PORT 80
00043 
00044 enum HttpResult
00045 {
00046   HTTP_OK,
00047   HTTP_PROCESSING,
00048   HTTP_PARSE, //URI Parse error
00049   HTTP_DNS, //Could not resolve name
00050   HTTP_PRTCL, //Protocol error
00051   HTTP_NOTFOUND, //404 Error
00052   HTTP_REFUSED, //403 Error
00053   HTTP_ERROR, //xxx error
00054   HTTP_TIMEOUT, //Connection timeout
00055   HTTP_CONN //Connection error
00056 };
00057 
00058 
00059 
00060 class HttpClient : protected NetService
00061 {
00062 public:
00063   HttpClient();
00064   virtual ~HttpClient();
00065   
00066   void basicAuth(const char* user, const char* password); //Basic Authentification
00067   
00068   //High Level setup functions
00069   HttpResult get(const char* uri, HttpData* pDataIn); //Blocking
00070   HttpResult get(const char* uri, HttpData* pDataIn, void (*pMethod)(HttpResult)); //Non blocking
00071   template<class T> 
00072   HttpResult get(const char* uri, HttpData* pDataIn, T* pItem, void (T::*pMethod)(HttpResult)) //Non blocking
00073   {
00074     setOnResult(pItem, pMethod);
00075     doGet(uri, pDataIn);
00076     return HTTP_PROCESSING;
00077   }
00078   
00079   HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn); //Blocking
00080   HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn, void (*pMethod)(HttpResult)); //Non blocking
00081   template<class T> 
00082   HttpResult post(const char* uri, const HttpData& dataOut, HttpData* pDataIn, T* pItem, void (T::*pMethod)(HttpResult)) //Non blocking  
00083   {
00084     setOnResult(pItem, pMethod);
00085     doPost(uri, dataOut, pDataIn);
00086     return HTTP_PROCESSING;
00087   }
00088   
00089   void doGet(const char* uri, HttpData* pDataIn);  
00090   void doPost(const char* uri, const HttpData& dataOut, HttpData* pDataIn); 
00091   
00092   void setOnResult( void (*pMethod)(HttpResult) );
00093   class CDummy;
00094   template<class T> 
00095   //Linker bug : Must be defined here :(
00096   void setOnResult( T* pItem, void (T::*pMethod)(HttpResult) )
00097   {
00098     m_pCb = NULL;
00099     m_pCbItem = (CDummy*) pItem;
00100     m_pCbMeth = (void (CDummy::*)(HttpResult)) pMethod;
00101   }
00102   
00103   void setTimeout(int ms);
00104   
00105   virtual void poll(); //Called by NetServices
00106   
00107   int getHttpResponseCode();
00108   void setRequestHeader(const string& header, const string& value);
00109   string& getResponseHeader(const string& header);
00110   void resetRequestHeaders();
00111   
00112 protected:
00113   void resetTimeout();
00114   
00115   void init();
00116   void close();
00117   
00118   void setup(const char* uri, HttpData* pDataOut, HttpData* pDataIn); //Setup request, make DNS Req if necessary
00119   void connect(); //Start Connection
00120   
00121   int  tryRead(); //Read data and try to feed output
00122   void readData(); //Data has been read
00123   void writeData(); //Data has been written & buf is free
00124   
00125   void onTcpSocketEvent(TcpSocketEvent e);
00126   void onDnsReply(DnsReply r);
00127   void onResult(HttpResult r); //Called when exchange completed or on failure
00128   void onTimeout(); //Connection has timed out
00129   
00130 private:
00131   HttpResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available
00132 
00133   bool readHeaders(); //Called first when receiving data
00134   bool writeHeaders(); //Called to create req
00135   int readLine(char* str, int maxLen, bool* pIncomplete = NULL);
00136   
00137   enum HTTP_METH
00138   {
00139     HTTP_GET,
00140     HTTP_POST,
00141     HTTP_HEAD
00142   };
00143   
00144   HTTP_METH m_meth;
00145   
00146   CDummy* m_pCbItem;
00147   void (CDummy::*m_pCbMeth)(HttpResult);
00148   
00149   void (*m_pCb)(HttpResult);
00150   
00151   TcpSocket* m_pTcpSocket;
00152   map<string, string> m_reqHeaders;
00153   map<string, string> m_respHeaders;
00154   
00155   Timer m_watchdog;
00156   int m_timeout;
00157   
00158   DnsRequest* m_pDnsReq;
00159   
00160   Host m_server;
00161   string m_path;
00162   
00163   bool m_closed;
00164   
00165   enum HttpStep
00166   {
00167    // HTTP_INIT,
00168     HTTP_WRITE_HEADERS,
00169     HTTP_WRITE_DATA,
00170     HTTP_READ_HEADERS,
00171     HTTP_READ_DATA,
00172     HTTP_READ_DATA_INCOMPLETE,
00173     HTTP_DONE,
00174     HTTP_CLOSED
00175   };
00176   
00177   HttpStep m_state;
00178   
00179   HttpData* m_pDataOut;
00180   HttpData* m_pDataIn;
00181   
00182   bool m_dataChunked; //Data is encoded as chunks
00183   int m_dataPos; //Position in data
00184   int m_dataLen; //Data length
00185   char* m_buf;
00186   char* m_pBufRemaining; //Remaining
00187   int m_bufRemainingLen; //Data length in m_pBufRemaining
00188   
00189   int m_httpResponseCode;
00190   
00191   HttpResult m_blockingResult; //Result if blocking mode
00192   
00193 };
00194 
00195 //Including data containers here for more convenience
00196 #include "data/HttpFile.h"
00197 #include "data/HttpStream.h"
00198 #include "data/HttpText.h"
00199 #include "data/HttpMap.h"
00200 
00201 #endif