Dependents:   TimeZoneDemo EthernetJackTestCode MMEx_Challenge ntp_mem ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPClient.h Source File

HTTPClient.h

Go to the documentation of this file.
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 /** \file
00025 HTTP Client header file
00026 */
00027 
00028 #ifndef HTTP_CLIENT_H
00029 #define HTTP_CLIENT_H
00030 
00031 class HTTPData;
00032 
00033 #include "core/net.h"
00034 #include "api/TCPSocket.h"
00035 #include "api/DNSRequest.h"
00036 #include "HTTPData.h"
00037 #include "mbed.h"
00038 
00039 #include <string>
00040 using std::string;
00041 
00042 #include <map>
00043 using std::map;
00044 
00045 ///HTTP client results
00046 enum HTTPResult
00047 {
00048   HTTP_OK, ///<Success
00049   HTTP_PROCESSING, ///<Processing
00050   HTTP_PARSE, ///<URI Parse error
00051   HTTP_DNS, ///<Could not resolve name
00052   HTTP_PRTCL, ///<Protocol error
00053   HTTP_NOTFOUND, ///<HTTP 404 Error
00054   HTTP_REFUSED, ///<HTTP 403 Error
00055   HTTP_ERROR, ///<HTTP xxx error
00056   HTTP_TIMEOUT, ///<Connection timeout
00057   HTTP_CONN ///<Connection error
00058 };
00059 
00060 #include "core/netservice.h"
00061 
00062 ///A simple HTTP Client
00063 /**
00064 The HTTPClient is composed of:
00065 - The actual client (HTTPClient)
00066 - Classes that act as a data repository, each of which deriving from the HTTPData class (HTTPText for short text content, HTTPFile for file I/O, HTTPMap for key/value pairs, and HTTPStream for streaming purposes)
00067 */
00068 class HTTPClient : protected NetService
00069 {
00070 public:
00071   ///Instantiates the HTTP client
00072   HTTPClient();
00073   virtual ~HTTPClient();
00074   
00075   ///Provides a basic authentification feature (Base64 encoded username and password)
00076   void basicAuth(const char* user, const char* password); //Basic Authentification
00077   
00078   //High Level setup functions
00079   ///Executes a GET Request (blocking)
00080   /**
00081   Executes a GET request on the URI uri
00082   @param uri : URI on which to execute the request
00083   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00084   Blocks until completion
00085   */
00086   HTTPResult get(const char* uri, HTTPData* pDataIn); //Blocking
00087   
00088   ///Executes a GET Request (non blocking)
00089   /**
00090   Executes a GET request on the URI uri
00091   @param uri : URI on which to execute the request
00092   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00093   @param pMethod : callback function
00094   The function returns immediately and calls the callback on completion or error
00095   */
00096   HTTPResult get(const char* uri, HTTPData* pDataIn, void (*pMethod)(HTTPResult)); //Non blocking
00097   
00098   ///Executes a GET Request (non blocking)
00099   /**
00100   Executes a GET request on the URI uri
00101   @param uri : URI on which to execute the request
00102   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00103   @param pItem : instance of class on which to execute the callback method
00104   @param pMethod : callback method
00105   The function returns immediately and calls the callback on completion or error
00106   */
00107   template<class T> 
00108   HTTPResult get(const char* uri, HTTPData* pDataIn, T* pItem, void (T::*pMethod)(HTTPResult)) //Non blocking
00109   {
00110     setOnResult(pItem, pMethod);
00111     doGet(uri, pDataIn);
00112     return HTTP_PROCESSING;
00113   }
00114   
00115   ///Executes a POST Request (blocking)
00116   /**
00117   Executes a POST request on the URI uri
00118   @param uri : URI on which to execute the request
00119   @param dataOut : a HTTPData instance that contains the data that will be posted
00120   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00121   Blocks until completion
00122   */
00123   HTTPResult post(const char* uri, const HTTPData& dataOut, HTTPData* pDataIn); //Blocking
00124   
00125   ///Executes a POST Request (non blocking)
00126   /**
00127   Executes a POST request on the URI uri
00128   @param uri : URI on which to execute the request
00129   @param dataOut : a HTTPData instance that contains the data that will be posted
00130   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00131   @param pMethod : callback function
00132   The function returns immediately and calls the callback on completion or error
00133   */
00134   HTTPResult post(const char* uri, const HTTPData& dataOut, HTTPData* pDataIn, void (*pMethod)(HTTPResult)); //Non blocking
00135   
00136   ///Executes a POST Request (non blocking)
00137   /**
00138   Executes a POST request on the URI uri
00139   @param uri : URI on which to execute the request
00140   @param dataOut : a HTTPData instance that contains the data that will be posted
00141   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00142   @param pItem : instance of class on which to execute the callback method
00143   @param pMethod : callback method
00144   The function returns immediately and calls the callback on completion or error
00145   */
00146   template<class T> 
00147   HTTPResult post(const char* uri, const HTTPData& dataOut, HTTPData* pDataIn, T* pItem, void (T::*pMethod)(HTTPResult)) //Non blocking  
00148   {
00149     setOnResult(pItem, pMethod);
00150     doPost(uri, dataOut, pDataIn);
00151     return HTTP_PROCESSING;
00152   }
00153 
00154   ///Executes a GET Request (non blocking)
00155   /**
00156   Executes a GET request on the URI uri
00157   @param uri : URI on which to execute the request
00158   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00159   The function returns immediately and calls the previously set callback on completion or error
00160   */  
00161   void doGet(const char* uri, HTTPData* pDataIn);  
00162   
00163   ///Executes a POST Request (non blocking)
00164   /**
00165   Executes a POST request on the URI uri
00166   @param uri : URI on which to execute the request
00167   @param dataOut : a HTTPData instance that contains the data that will be posted
00168   @param pDataIn : pointer to an HTTPData instance that will collect the data returned by the request, can be NULL
00169   @param pMethod : callback function
00170   The function returns immediately and calls the previously set callback on completion or error
00171   */
00172   void doPost(const char* uri, const HTTPData& dataOut, HTTPData* pDataIn); 
00173   
00174   ///Setups the result callback
00175   /**
00176   @param pMethod : callback function
00177   */
00178   void setOnResult( void (*pMethod)(HTTPResult) );
00179   
00180   ///Setups the result callback
00181   /**
00182   @param pItem : instance of class on which to execute the callback method
00183   @param pMethod : callback method
00184   */
00185   class CDummy;
00186   template<class T> 
00187   void setOnResult( T* pItem, void (T::*pMethod)(HTTPResult) )
00188   {
00189     m_pCb = NULL;
00190     m_pCbItem = (CDummy*) pItem;
00191     m_pCbMeth = (void (CDummy::*)(HTTPResult)) pMethod;
00192   }
00193 
00194   ///Setups timeout
00195   /**
00196   @param ms : time of connection inactivity in ms after which the request should timeout
00197   */
00198   void setTimeout(int ms);
00199   
00200   virtual void poll(); //Called by NetServices
00201   
00202   ///Gets last request's HTTP response code
00203   /**
00204   @return The HTTP response code of the last request
00205   */
00206   int getHTTPResponseCode();
00207   
00208   ///Sets a specific request header
00209   void setRequestHeader(const string& header, const string& value);
00210   
00211   ///Gets a response header
00212   string& getResponseHeader(const string& header);
00213   
00214   ///Clears request headers
00215   void resetRequestHeaders();
00216   
00217 protected:
00218   void resetTimeout();
00219   
00220   void init();
00221   void close();
00222   
00223   void setup(const char* uri, HTTPData* pDataOut, HTTPData* pDataIn); //Setup request, make DNS Req if necessary
00224   void connect(); //Start Connection
00225   
00226   int  tryRead(); //Read data and try to feed output
00227   void readData(); //Data has been read
00228   void writeData(); //Data has been written & buf is free
00229   
00230   void onTCPSocketEvent(TCPSocketEvent e);
00231   void onDNSReply(DNSReply r);
00232   void onResult(HTTPResult r); //Called when exchange completed or on failure
00233   void onTimeout(); //Connection has timed out
00234   
00235 private:
00236   HTTPResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available
00237 
00238   bool readHeaders(); //Called first when receiving data
00239   bool writeHeaders(); //Called to create req
00240   int readLine(char* str, int maxLen, bool* pIncomplete = NULL);
00241   
00242   enum HTTP_METH
00243   {
00244     HTTP_GET,
00245     HTTP_POST,
00246     HTTP_HEAD
00247   };
00248   
00249   HTTP_METH m_meth;
00250   
00251   CDummy* m_pCbItem;
00252   void (CDummy::*m_pCbMeth)(HTTPResult);
00253   
00254   void (*m_pCb)(HTTPResult);
00255   
00256   TCPSocket* m_pTCPSocket;
00257   map<string, string> m_reqHeaders;
00258   map<string, string> m_respHeaders;
00259   
00260   Timer m_watchdog;
00261   int m_timeout;
00262   
00263   DNSRequest* m_pDnsReq;
00264   
00265   Host m_server;
00266   string m_path;
00267   
00268   bool m_closed;
00269   
00270   enum HTTPStep
00271   {
00272    // HTTP_INIT,
00273     HTTP_WRITE_HEADERS,
00274     HTTP_WRITE_DATA,
00275     HTTP_READ_HEADERS,
00276     HTTP_READ_DATA,
00277     HTTP_READ_DATA_INCOMPLETE,
00278     HTTP_DONE,
00279     HTTP_CLOSED
00280   };
00281   
00282   HTTPStep m_state;
00283   
00284   HTTPData* m_pDataOut;
00285   HTTPData* m_pDataIn;
00286   
00287   bool m_dataChunked; //Data is encoded as chunks
00288   int m_dataPos; //Position in data
00289   int m_dataLen; //Data length
00290   char* m_buf;
00291   char* m_pBufRemaining; //Remaining
00292   int m_bufRemainingLen; //Data length in m_pBufRemaining
00293   
00294   int m_httpResponseCode;
00295   
00296   HTTPResult m_blockingResult; //Result if blocking mode
00297   
00298 };
00299 
00300 //Including data containers here for more convenience
00301 #include "data/HTTPFile.h"
00302 #include "data/HTTPStream.h"
00303 #include "data/HTTPText.h"
00304 #include "data/HTTPMap.h"
00305 
00306 #endif