Phasor  01.00.10.059
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Curl.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <sstream>
4 #include <vector>
5 #include <list>
6 #include "../Common/MyException.h"
7 #include "../../libcurl/curl/curl.h"
8 
9 namespace Curl
10 {
11  class CurlMulti;
12  class CurlSimple;
13  class CurlHttp;
14  class CurlDownload;
15 
16  typedef std::unique_ptr<CurlMulti> CurlMultiPtr;
17  typedef std::unique_ptr<CurlSimple> CurlPtr;
18  typedef std::unique_ptr<CurlHttp> CurlHttpPtr;
19  typedef std::unique_ptr<CurlDownload> CurlDownloadPtr;
20 
21  //-----------------------------------------------------------------------------------------
22  // Class: CurlMulti
23  // Purpose: Manages a non-blocking (ish) multi curl interface.
24  class CurlMulti
25  {
26  private:
27  CURLM* multi_curl; // the multi stack used
28  std::list<CurlPtr> simples; // simple connections tracked
29  int running; // number of connections active
30  bool started;
31 
32  protected:
33  // Returns the CurlSimple associated with the CURL connection
34  bool FindConnection(CURL* con, CurlSimple** out);
35 
36  public:
37 
38  CurlMulti();
39  ~CurlMulti();
40 
41  virtual void HandleError(const std::string& err);
42 
43  // Processes any waiting data
44  // Return: true (active connections), false (no active connections)
45  bool Process();
46 
47  // Removes a CurlSimple connection
48  void Remove(CurlSimple** simple_curl);
49 
50  // Add a request to the multi interface
51  bool AddRequest(CurlPtr simple_curl);
52 
53  friend class CurlSimple;
54  };
55 
56  //-----------------------------------------------------------------------------------------
57  // Class: CurlSimple
58  // Purpose: Manage simple curl connections for use in CurlMulti.
59  class CurlSimple
60  {
61  private:
62  CURL* curl; // the easy curl interface used
63  static const unsigned long DEFAULT_BUFFER_SIZE = 4096;
64  std::vector<BYTE> buffer;
65 
66  // Called by the curl object when there is data to be processed. This
67  // function is simply used to call OnDataWrite in a C++ context.
68  static size_t Curl_OnDataWrite(BYTE* data, size_t size, size_t nmemb, void* userdata);
69 
70  protected:
71  std::string url; // url the connection is to be made on
72 
73  // Returns the pointer to this curl instance
74  CURL* GetCurl() { return curl; };
75 
76  // Processes data received from the curl interface.
77  // Unless overridden this function will store all received data in
78  // the internal buffer. As such this method should be overridden if
79  // the expected data is too large to store into memory.
80  // The internal buffer is expanded as required.
81  virtual size_t OnDataWrite(BYTE* data, size_t size, size_t nmemb);
82 
83  // Called by CurlMulti when the current operation has completed,
84  // successfully or not. The connect is cleaned up after this call.
85  void ConnectionDone(CURLMsg* msg);
86 
87  // Classes should implement these functions for custom completion,
88  // or error handling. data may be null if the internal buffer wasn't
89  // used (ie in CurlDownload)
90  virtual void OnCompletion(bool success, const BYTE* data, size_t size) {}
91 
92  // Called by CurlMulti when this instance is added to the multistack
93  // Return values specifies whether or not it should be added.
94  virtual bool OnAdd() { return true; }
95 
96  public:
97 
98  CurlSimple(const std::string& url);
99  virtual ~CurlSimple();
100 
101  virtual void HandleError(const std::string& err);
102 
103  friend class CurlMulti;
104  };
105 
106  //-----------------------------------------------------------------------------------------
107  // Class: CurlSimpleHttp
108  // Purpose: Connects to and downloads a web page and (optionally) sends get or post data
109  class CurlHttp : public CurlSimple
110  {
111  private:
112  bool pair_added, do_post; // should & be prepended
113  std::stringstream ssurl; // used for building get urls
114  curl_httppost* form; // used for posts
115  curl_httppost* last;
116 
117  // Helper function for escaping strings
118  std::string wstring_to_utf8_hex(const std::wstring &input);
119 
120  // Escapes the input string for url encoding
121  std::string Escape(const std::wstring& input);
122  std::string Escape(const std::string& input);
123 
124  // Called by CurlMulti when this instance is added to the multistack
125  // Return values specifies whether or not it should be added.
126  virtual bool OnAdd();
127 
128  public:
129 
130  CurlHttp(const std::string& url);
131  virtual ~CurlHttp();
132 
133  // Adds data to the http request, any unicode strings are escaped.
134  void AddPostData(const std::string& key, const std::wstring& data);
135  void AddPostData(const std::string& key, const std::string& data, bool b=false);
136  void AddPostFile(const std::string& key, const std::string& path_to_file);
137  void AddGetData(const std::string& key, const std::wstring& data);
138  void AddGetData(const std::string& key, const std::string& data, bool b=false);
139  };
140 
141  //-----------------------------------------------------------------------------------------
142  // Class: CurlSimpleDownload
143  // Purpose: Downloads the file at the specified url
144  class CurlDownload : public CurlSimple
145  {
146  protected:
147  std::string file;
148  FILE* pFile;
149 
150  // Writes any received data to file with fwrite.
151  virtual size_t OnDataWrite(BYTE* data, size_t size, size_t nmemb);
152 
153  virtual void OnCompletion(bool success, const BYTE*, size_t size);
154 
155  public:
156  CurlDownload(const std::string& url, FILE* pFile);
157  virtual ~CurlDownload();
158  static FILE* OpenOutputFile(const std::string& file);
159  };
160 
161 
162  //-----------------------------------------------------------------------------------------
163  // Class: CurlSimpleFtp
164  // Purpose: Connects to an ftp server and uploads/downloads file(s)
165  /*class CurlSimpleFtp : CurlSimple
166  {
167  private:
168  std::string outFile;
169 
170  public:
171  CurlSimpleFtp(const char* outFile);
172  ~CurlSimpleFtp();
173  };*/
174 }