]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Support for POST and POST JSON modes
authorAki Tuomi <cmouse@desteem.org>
Wed, 5 Jun 2013 07:15:31 +0000 (10:15 +0300)
committerAki Tuomi <cmouse@desteem.org>
Wed, 5 Jun 2013 07:15:31 +0000 (10:15 +0300)
modules/remotebackend/httpconnector.cc
modules/remotebackend/remotebackend.hh

index b52d858cb81885cc3505d5fc56128bfcf6323f92..93ce237ed21521f5b2e2829ddbc868ecdb9b5eef 100644 (file)
@@ -4,6 +4,8 @@
 #include <fcntl.h>
 #include <boost/foreach.hpp>
 #include <sstream>
+#include "rapidjson/stringbuffer.h"
+#include "rapidjson/writer.h"
 
 #ifdef REMOTEBACKEND_HTTP
 #include <curl/curl.h>
@@ -22,9 +24,24 @@ HTTPConnector::HTTPConnector(std::map<std::string,std::string> options) {
       this->d_url_suffix = "";
     }
     this->timeout = 2;
+    this->d_post = false;
+    this->d_post_json = false;
+
     if (options.find("timeout") != options.end()) { 
       this->timeout = boost::lexical_cast<int>(options.find("timeout")->second)/1000;
     }
+    if (options.find("post") != options.end()) {
+      std::string val = options.find("post")->second;
+      if (val == "yes" || val == "true" || val == "on" || val == "1") {
+        this->d_post = true;
+      }
+    }
+    if (options.find("post_json") != options.end()) {
+      std::string val = options.find("post_json")->second;
+      if (val == "yes" || val == "true" || val == "on" || val == "1") {
+        this->d_post_json = true;
+      }
+    }
 }
 
 HTTPConnector::~HTTPConnector() {
@@ -88,8 +105,8 @@ template <class T> std::string buildMemberListArgs(std::string prefix, const T*
     return stream.str();
 }
 
-// builds our request
-void HTTPConnector::requestbuilder(const std::string &method, const rapidjson::Value &parameters, struct curl_slist **slist)
+// builds our request (near-restful)
+void HTTPConnector::restful_requestbuilder(const std::string &method, const rapidjson::Value &parameters, struct curl_slist **slist)
 {
     std::stringstream ss;
     std::string sparam;
@@ -258,6 +275,35 @@ void HTTPConnector::requestbuilder(const std::string &method, const rapidjson::V
     curl_easy_setopt(d_c, CURLOPT_HTTPHEADER, *slist); 
 }
 
+void HTTPConnector::post_requestbuilder(const rapidjson::Document &input, struct curl_slist **slist) {
+    if (this->d_post_json) {
+        // simple case, POST JSON into url. nothing fancy. 
+        std::string out = makeStringFromDocument(input);
+        (*slist) = curl_slist_append((*slist), "Content-Type: text/javascript; charset=utf-8");
+        curl_easy_setopt(d_c, CURLOPT_POSTFIELDSIZE, out.size());
+        curl_easy_setopt(d_c, CURLOPT_COPYPOSTFIELDS, out.c_str());
+        curl_easy_setopt(d_c, CURLOPT_URL, d_url.c_str());
+        curl_easy_setopt(d_c, CURLOPT_HTTPHEADER, *slist);
+    } else {
+        std::stringstream url,content;
+        char *tmpstr;
+        // call url/method.suffix
+        rapidjson::StringBuffer output;
+        rapidjson::Writer<rapidjson::StringBuffer> w(output);
+        input["parameters"].Accept(w);
+        url << d_url << "/" << input["method"].GetString() << d_url_suffix;
+        // then build content
+        tmpstr = curl_easy_escape(d_c, output.GetString(), 0);
+        content << "parameters=" << tmpstr;
+        // convert into parameters=urlencoded
+        curl_easy_setopt(d_c, CURLOPT_POSTFIELDSIZE, content.str().size());
+        curl_easy_setopt(d_c, CURLOPT_COPYPOSTFIELDS, content.str().c_str());
+        free(tmpstr);
+        curl_easy_setopt(d_c, CURLOPT_URL, d_url.c_str());
+        curl_easy_setopt(d_c, CURLOPT_URL, url.str().c_str());
+    }
+}
+
 int HTTPConnector::send_message(const rapidjson::Document &input) {
     int rv;
     long rcode;
@@ -274,8 +320,12 @@ int HTTPConnector::send_message(const rapidjson::Document &input) {
 
     slist = NULL;
 
-    // build request
-    requestbuilder(input["method"].GetString(), input["parameters"], &slist);
+    // build request based on mode
+    
+    if (d_post) 
+      post_requestbuilder(input, &slist);
+    else
+      restful_requestbuilder(input["method"].GetString(), input["parameters"], &slist);
 
     // setup write function helper
     curl_easy_setopt(d_c, CURLOPT_WRITEFUNCTION, &(httpconnector_write_data));
index 9e7d052f6576ffaf036a7b139fdf5061f4c3befc..ee2f443d5b2bc93ba9de7aec4a4809e0a336afae 100644 (file)
@@ -66,8 +66,11 @@ class HTTPConnector: public Connector {
     CURL *d_c;
     std::string d_data;
     int timeout;
+    bool d_post; 
+    bool d_post_json;
     bool json2string(const rapidjson::Value &input, std::string &output);
-    void requestbuilder(const std::string &method, const rapidjson::Value &parameters, struct curl_slist **slist);
+    void restful_requestbuilder(const std::string &method, const rapidjson::Value &parameters, struct curl_slist **slist);
+    void post_requestbuilder(const rapidjson::Document &input, struct curl_slist **slist);
     void addUrlComponent(const rapidjson::Value &parameters, const char *element, std::stringstream& ss);
 };
 #endif