Drizzled Public API Documentation

http_functions.cc
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2011 Stewart Smith
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include <config.h>
21 
22 #include <drizzled/plugin/function.h>
23 #include <drizzled/function/str/strfunc.h>
24 #include <drizzled/charset.h>
25 #include <drizzled/error.h>
26 
27 #include <curl/curl.h>
28 
29 using namespace drizzled;
30 
32 {
33  String result;
34 public:
36  String *val_str(String *);
37  void fix_length_and_dec();
38  const char *func_name() const { return "http_get"; }
39 
40  bool check_argument_count(int n)
41  {
42  return n == 1;
43  }
44 };
45 
46 extern "C" size_t
47 http_get_result_cb(void *ptr, size_t size, size_t nmemb, void *data);
48 
49 extern "C" size_t
50 http_get_result_cb(void *ptr, size_t size, size_t nmemb, void *data)
51 {
52  size_t realsize= size * nmemb;
53  String *result= (String *)data;
54 
55  result->reserve(realsize + 1);
56  result->append((const char*)ptr, realsize);
57 
58  return realsize;
59 }
60 
61 
63 {
64  assert(fixed == 1);
65  String *url = args[0]->val_str(str);
66  CURL *curl;
67  CURLcode retref;
68 
69  if ((null_value=args[0]->null_value))
70  return NULL;
71 
72  curl= curl_easy_init();
73  curl_easy_setopt(curl, CURLOPT_URL, url->c_str());
74  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_result_cb);
75  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&result);
76  curl_easy_setopt(curl, CURLOPT_USERAGENT, "drizzle-http-functions/1.0");
77  retref= curl_easy_perform(curl);
78  curl_easy_cleanup(curl);
79 
80  if (retref != 0)
81  my_error(ER_GET_ERRMSG, MYF(0), retref, curl_easy_strerror(retref),
82  "http_get");
83 
84  return &result;
85 }
86 
87 void HttpGetFunction::fix_length_and_dec()
88 {
89  collation.set(args[0]->collation);
90  max_length = ~0;
91 }
92 
94 {
95  String result;
96 public:
98  String *val_str(String *);
99  void fix_length_and_dec();
100  const char *func_name() const { return "http_post"; }
101 
102  bool check_argument_count(int n)
103  {
104  return n == 2;
105  }
106 };
107 
109 {
110 private:
111  String *data;
112  size_t progress;
113 
114 public:
115  HttpPostData(String* d) : data(d), progress(0) {}
116 
117  size_t length() { return data->length(); }
118 
119  size_t write(void* dest, size_t size)
120  {
121  size_t to_write= size;
122 
123  if ((data->length() - progress) < to_write)
124  to_write= data->length() - progress;
125 
126  memcpy(dest, data->ptr() + progress, to_write);
127 
128  progress+= to_write;
129 
130  return to_write;
131  }
132 };
133 
134 extern "C" size_t
135 http_post_readfunc(void *ptr, size_t size, size_t nmemb, void *data);
136 
137 extern "C" size_t
138 http_post_readfunc(void *ptr, size_t size, size_t nmemb, void *data)
139 {
140  size_t realsize= size * nmemb;
141  HttpPostData *post_data= (HttpPostData *)data;
142 
143  return post_data->write(ptr, realsize);
144 }
145 
147 {
148  assert(fixed == 1);
149  String *url = args[0]->val_str(str);
150  CURL *curl;
151  String post_storage;
152  HttpPostData post_data(args[1]->val_str(&post_storage));
153 
154  if ((null_value=args[0]->null_value))
155  return NULL;
156 
157  curl= curl_easy_init();
158  curl_easy_setopt(curl, CURLOPT_URL, url->c_str());
159  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_result_cb);
160  curl_easy_setopt(curl, CURLOPT_POST, 1L);
161  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, post_data.length());
162  curl_easy_setopt(curl, CURLOPT_READDATA, &post_data);
163  curl_easy_setopt(curl, CURLOPT_READFUNCTION, http_post_readfunc);
164  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&result);
165  curl_easy_setopt(curl, CURLOPT_USERAGENT, "drizzle-http-functions/1.0");
166  /*CURLcode retref=*/ curl_easy_perform(curl);
167  curl_easy_cleanup(curl);
168 
169  return &result;
170 }
171 
172 void HttpPostFunction::fix_length_and_dec()
173 {
174  collation.set(args[0]->collation);
175  max_length = ~0;
176 }
177 
178 static int initialize(drizzled::module::Context &context)
179 {
180  curl_global_init(CURL_GLOBAL_ALL);
181  context.add(new plugin::Create_function<HttpGetFunction>("http_get"));
182  context.add(new plugin::Create_function<HttpPostFunction>("http_post"));
183  return 0;
184 }
185 
186 DRIZZLE_DECLARE_PLUGIN
187 {
188  DRIZZLE_VERSION_ID,
189  "http_functions",
190  "1.0",
191  "Stewart Smith",
192  N_("HTTP_GET and HTTP_POST functions"),
193  PLUGIN_LICENSE_GPL,
194  initialize,
195  NULL,
196  NULL
197 }
198 DRIZZLE_DECLARE_PLUGIN_END;