From 38e8795e068fbf89bb79c2795c61a6937138c651 Mon Sep 17 00:00:00 2001 From: keita Date: Fri, 19 Mar 2021 22:18:39 +0900 Subject: [PATCH] =?UTF-8?q?HTTP/GET=E3=81=AE=E5=AE=9F=E8=A3=85(#66)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cocoatweet/api/interface/httpGet.cc | 98 +++++++++++++++++++++++++ src/cocoatweet/api/interface/httpGet.h | 23 ++++++ 2 files changed, 121 insertions(+) create mode 100644 src/cocoatweet/api/interface/httpGet.cc create mode 100644 src/cocoatweet/api/interface/httpGet.h diff --git a/src/cocoatweet/api/interface/httpGet.cc b/src/cocoatweet/api/interface/httpGet.cc new file mode 100644 index 0000000..4dbdf0f --- /dev/null +++ b/src/cocoatweet/api/interface/httpGet.cc @@ -0,0 +1,98 @@ +#include +#include "cocoatweet/util/util.h" +#include +#include +#include +#include +#include +extern "C" { +#include +} + +#ifndef NDEBUG +#include +#endif + +namespace CocoaTweet::API::Interface { +void HttpGet::process(std::weak_ptr _oauth, + std::function _callback) { + auto url = url_; + + // エンドポイントへのパラメータにOAuthパラメータを付加して署名作成 + auto oauth = _oauth.lock(); + auto oauthParam = oauth->oauthParam(); + auto sigingParam = oauthParam; + if (contentType_ == "application/x-www-form-urlencoded") { + for (const auto [k, v] : bodyParam_) { + sigingParam.insert_or_assign(k, v); + } + } + + auto signature = oauth->signature(sigingParam, "GET", url_); + + // 作成した署名をエンドポイントへのパラメータ及びOAuthパラメータに登録 + oauthParam.merge(signature); + + // URLの構築 + { + std::vector tmp; + for (const auto& [key, value] : bodyParam_) { + tmp.push_back(key + "=" + value); + } + url_ += std::string("?" + CocoaTweet::Util::join(tmp, "&")); + } + + // ヘッダの構築 + std::string oauthHeader = "authorization: OAuth "; + { + std::vector tmp; + for (const auto& [key, value] : oauthParam) { + tmp.push_back(key + "=" + CocoaTweet::Util::urlEncode(value)); + } + oauthHeader += CocoaTweet::Util::join(tmp, ","); + } + + // do post + CURL* curl; + CURLcode res; + std::string rcv; + long responseCode; + curl = curl_easy_init(); + url_ = url_; + if (curl) { + curl_easy_setopt(curl, CURLOPT_URL, url_.c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlCallback_); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (std::string*)&rcv); +#ifndef NDEBUG + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); +#endif + // Headerを保持するcurl_slist*を初期化 + struct curl_slist* headers = NULL; + // Authorizationをヘッダに追加 + headers = curl_slist_append(headers, oauthHeader.c_str()); + + std::string contentType = ""; + if (contentType_ == "application/x-www-form-urlencoded") { + contentType = contentType_; + } else if (contentType_ == "multipart/form-data") { + contentType = contentType_ + "; boundary=milkcocoa0902"; + } + + headers = curl_slist_append(headers, ("Content-Type: " + contentType).c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + res = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode); + curl_easy_cleanup(curl); + } + + if (res != CURLE_OK) { + throw std::runtime_error(std::string("INTERNAL ERROR : curl(") + std::to_string(res) + ")"); + exit(1); + } + + if (_callback) { + _callback(responseCode, rcv); + } +} +} // namespace CocoaTweet::API::Interface diff --git a/src/cocoatweet/api/interface/httpGet.h b/src/cocoatweet/api/interface/httpGet.h new file mode 100644 index 0000000..86f2668 --- /dev/null +++ b/src/cocoatweet/api/interface/httpGet.h @@ -0,0 +1,23 @@ +#ifndef COCOATWEET_API_INTERFACE_HTTPGET_H_ +#define COCOATWEET_API_INTERFACE_HTTPGET_H_ + +#include +#include "cocoatweet/oauth/oauth.h" +#include + +namespace CocoaTweet::API::Interface { +/// @brief class for Send request with POST method +class HttpGet : public virtual HttpBase { +public: +protected: + /// @brief Send HTTP/POST using OAuth object + /// @param[in] std::weak_ptr _oauth : pointer to OAuth object to + /// authenticate + /// @param[in] std::function _callback : + /// callback method for processing to response + void process(std::weak_ptr _oauth, + std::function _callback); +}; +} // namespace CocoaTweet::API::Interface + +#endif