Norimasa Okamoto / WIZ820ioNetIf
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   static char* ResultStr (HTTPResult r);
00218 protected:
00219   void resetTimeout();
00220   
00221   void init();
00222   void close();
00223   
00224   void setup(const char* uri, HTTPData* pDataOut, HTTPData* pDataIn); //Setup request, make DNS Req if necessary
00225   void connect(); //Start Connection
00226   
00227   int  tryRead(); //Read data and try to feed output
00228   void readData(); //Data has been read
00229   void writeData(); //Data has been written & buf is free
00230   
00231   void onTCPSocketEvent(TCPSocketEvent e);
00232   void onDNSReply(DNSReply r);
00233   void onResult(HTTPResult r); //Called when exchange completed or on failure
00234   void onTimeout(); //Connection has timed out
00235   
00236 private:
00237   HTTPResult blockingProcess(); //Called in blocking mode, calls Net::poll() until return code is available
00238 
00239   bool readHeaders(); //Called first when receiving data
00240   bool writeHeaders(); //Called to create req
00241   int readLine(char* str, int maxLen, bool* pIncomplete = NULL);
00242   
00243   enum HTTP_METH
00244   {
00245     HTTP_GET,
00246     HTTP_POST,
00247     HTTP_HEAD
00248   };
00249   
00250   HTTP_METH m_meth;
00251   
00252   CDummy* m_pCbItem;
00253   void (CDummy::*m_pCbMeth)(HTTPResult);
00254   
00255   void (*m_pCb)(HTTPResult);
00256   
00257   TCPSocket* m_pTCPSocket;
00258   map<string, string> m_reqHeaders;
00259   map<string, string> m_respHeaders;
00260   
00261   Timer m_watchdog;
00262   int m_timeout;
00263   
00264   DNSRequest* m_pDnsReq;
00265   
00266   Host m_server;
00267   string m_path;
00268   
00269   bool m_closed;
00270   
00271   enum HTTPStep
00272   {
00273    // HTTP_INIT,
00274     HTTP_WRITE_HEADERS,
00275     HTTP_WRITE_DATA,
00276     HTTP_READ_HEADERS,
00277     HTTP_READ_DATA,
00278     HTTP_READ_DATA_INCOMPLETE,
00279     HTTP_DONE,
00280     HTTP_CLOSED
00281   };
00282   
00283   HTTPStep m_state;
00284   
00285   HTTPData* m_pDataOut;
00286   HTTPData* m_pDataIn;
00287   
00288   bool m_dataChunked; //Data is encoded as chunks
00289   int m_dataPos; //Position in data
00290   int m_dataLen; //Data length
00291   char* m_buf;
00292   char* m_pBufRemaining; //Remaining
00293   int m_bufRemainingLen; //Data length in m_pBufRemaining
00294   
00295   int m_httpResponseCode;
00296   
00297   HTTPResult m_blockingResult; //Result if blocking mode
00298   
00299 };
00300 
00301 //Including data containers here for more convenience
00302 #include "data/HTTPFile.h"
00303 #include "data/HTTPStream.h"
00304 #include "data/HTTPText.h"
00305 #include "data/HTTPMap.h"
00306 
00307 #endif