Compare commits
No commits in common. "3fb8491555f5f687102e310722aa56163d1a9fbd" and "6f894cb9b1aa593cb28a39b73ce6f27f34b9481f" have entirely different histories.
3fb8491555
...
6f894cb9b1
Before Width: | Height: | Size: 502 KiB |
|
@ -1,264 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_BASE_H__
|
|
||||||
#define __AIP_BASE_H__
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <cstring>
|
|
||||||
#include "http.h"
|
|
||||||
#include "json/json.h"
|
|
||||||
#include "base64.h"
|
|
||||||
#include "curl/curl.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
static const char* AIP_SDK_VERSION = "0.3.3";
|
|
||||||
static const char* CURL_ERROR_CODE = "curl_error_code";
|
|
||||||
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
|
|
||||||
static const std::map<std::string, std::string> null;
|
|
||||||
|
|
||||||
class AipBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string _app_id;
|
|
||||||
int _expired_time;
|
|
||||||
bool _is_bce;
|
|
||||||
bool _has_decide_type;
|
|
||||||
std::string _scope;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string getAccessToken()
|
|
||||||
{
|
|
||||||
time_t now = time(NULL);
|
|
||||||
if (!access_token.empty())
|
|
||||||
{
|
|
||||||
return this->access_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now < this->_expired_time - 60 * 60 * 24)
|
|
||||||
{
|
|
||||||
return this->access_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string response;
|
|
||||||
std::map<std::string, std::string> params;
|
|
||||||
|
|
||||||
params["grant_type"] = "client_credentials";
|
|
||||||
params["client_id"] = this->ak;
|
|
||||||
params["client_secret"] = this->sk;
|
|
||||||
int status_code = this->client.get(
|
|
||||||
ACCESS_TOKEN_URL,
|
|
||||||
¶ms,
|
|
||||||
nullptr,
|
|
||||||
&response
|
|
||||||
);
|
|
||||||
Json::Value obj;
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj.toStyledString();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
this->access_token = obj["access_token"].asString();
|
|
||||||
this->_expired_time = obj["expires_in"].asInt() + (int) now;
|
|
||||||
this->_scope = obj["scope"].asString();
|
|
||||||
return this->access_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::string ak;
|
|
||||||
std::string sk;
|
|
||||||
HttpClient client;
|
|
||||||
Json::CharReaderBuilder crbuilder;
|
|
||||||
std::string access_token;
|
|
||||||
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
|
|
||||||
_app_id(app_id),
|
|
||||||
_is_bce(false),
|
|
||||||
_has_decide_type(false),
|
|
||||||
ak(ak),
|
|
||||||
sk(sk)
|
|
||||||
{
|
|
||||||
if (_app_id == "")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setConnectionTimeoutInMillis(int connect_timeout)
|
|
||||||
{
|
|
||||||
this->client.setConnectTimeout(connect_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSocketTimeoutInMillis(int socket_timeout)
|
|
||||||
{
|
|
||||||
this->client.setSocketTimeout(socket_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDebug(bool debug)
|
|
||||||
{
|
|
||||||
this->client.setDebug(debug);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getAk() {
|
|
||||||
return ak;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value request(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const & params,
|
|
||||||
std::string const & data,
|
|
||||||
std::map<std::string, std::string> const & headers)
|
|
||||||
{
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
std::string body;
|
|
||||||
auto headers_for_sign = headers;
|
|
||||||
|
|
||||||
auto temp_params = params;
|
|
||||||
|
|
||||||
temp_params["charset"] = "UTF-8";
|
|
||||||
|
|
||||||
this->prepare_request(url, temp_params, headers_for_sign);
|
|
||||||
|
|
||||||
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
|
||||||
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value request(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const & params,
|
|
||||||
std::map<std::string, std::string> const & data,
|
|
||||||
std::map<std::string, std::string> const & headers)
|
|
||||||
{
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
|
|
||||||
auto headers_for_sign = headers;
|
|
||||||
auto temp_params = params;
|
|
||||||
|
|
||||||
this->prepare_request(url, temp_params, headers_for_sign);
|
|
||||||
|
|
||||||
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
|
||||||
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void prepare_request(std::string url,
|
|
||||||
std::map<std::string, std::string> & params,
|
|
||||||
std::map<std::string, std::string> & headers)
|
|
||||||
{
|
|
||||||
|
|
||||||
params["aipSdk"] = "C";
|
|
||||||
params["aipSdkVersion"] = AIP_SDK_VERSION;
|
|
||||||
|
|
||||||
if (_has_decide_type) {
|
|
||||||
if (_is_bce) {
|
|
||||||
std::string method = "POST";
|
|
||||||
sign(method, url, params, headers, ak, sk);
|
|
||||||
} else {
|
|
||||||
params["access_token"] = this->getAccessToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getAccessToken() == "") {
|
|
||||||
_is_bce = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
|
|
||||||
|
|
||||||
if (t == NULL)
|
|
||||||
{
|
|
||||||
_is_bce = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_has_decide_type = true;
|
|
||||||
prepare_request(url, params, headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Json::Value requestjson(
|
|
||||||
std::string url,
|
|
||||||
Json::Value & data,
|
|
||||||
std::map<std::string, std::string> & params,
|
|
||||||
std::map<std::string, std::string> const & headers)
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
auto headers_for_sign = headers;
|
|
||||||
auto temp_params = params;
|
|
||||||
this->prepare_request(url, temp_params, headers_for_sign);
|
|
||||||
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[aip::CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value request_com(
|
|
||||||
std::string const & url,
|
|
||||||
Json::Value & data)
|
|
||||||
{
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
|
||||||
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[aip::CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,130 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_BASE64_H__
|
|
||||||
#define __AIP_BASE64_H__
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
static const std::string base64_chars =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
|
||||||
"0123456789+/";
|
|
||||||
|
|
||||||
|
|
||||||
static inline bool is_base64(const char c)
|
|
||||||
{
|
|
||||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
|
|
||||||
{
|
|
||||||
std::string ret;
|
|
||||||
int i = 0;
|
|
||||||
int j = 0;
|
|
||||||
unsigned char char_array_3[3];
|
|
||||||
unsigned char char_array_4[4];
|
|
||||||
|
|
||||||
while (in_len--)
|
|
||||||
{
|
|
||||||
char_array_3[i++] = *(bytes_to_encode++);
|
|
||||||
if(i == 3)
|
|
||||||
{
|
|
||||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
||||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
||||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
||||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
||||||
|
|
||||||
for(i = 0; (i <4) ; i++)
|
|
||||||
{
|
|
||||||
ret += base64_chars[char_array_4[i]];
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i)
|
|
||||||
{
|
|
||||||
for(j = i; j < 3; j++)
|
|
||||||
{
|
|
||||||
char_array_3[j] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
||||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
||||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
||||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
||||||
|
|
||||||
for(j = 0; (j < i + 1); j++)
|
|
||||||
{
|
|
||||||
ret += base64_chars[char_array_4[j]];
|
|
||||||
}
|
|
||||||
|
|
||||||
while((i++ < 3))
|
|
||||||
{
|
|
||||||
ret += '=';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string base64_decode(std::string const & encoded_string)
|
|
||||||
{
|
|
||||||
int in_len = (int) encoded_string.size();
|
|
||||||
int i = 0;
|
|
||||||
int j = 0;
|
|
||||||
int in_ = 0;
|
|
||||||
unsigned char char_array_4[4], char_array_3[3];
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
|
||||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
|
||||||
if (i ==4) {
|
|
||||||
for (i = 0; i <4; i++)
|
|
||||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
|
||||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
|
||||||
|
|
||||||
for (i = 0; (i < 3); i++)
|
|
||||||
ret += char_array_3[i];
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i) {
|
|
||||||
for (j = i; j <4; j++)
|
|
||||||
char_array_4[j] = 0;
|
|
||||||
|
|
||||||
for (j = 0; j <4; j++)
|
|
||||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
|
||||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
|
||||||
|
|
||||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,234 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_HTTP_H__
|
|
||||||
#define __AIP_HTTP_H__
|
|
||||||
|
|
||||||
#include "curl/curl.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <json/json.h>
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
|
|
||||||
{
|
|
||||||
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
|
|
||||||
str->append((char *)buffer, size * nmemb);
|
|
||||||
return nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
class HttpClient
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool debug = false;
|
|
||||||
int connect_timeout = 10000;
|
|
||||||
int socket_timeout = 10000;
|
|
||||||
|
|
||||||
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
|
|
||||||
{
|
|
||||||
content->clear();
|
|
||||||
std::map<std::string, std::string>::const_iterator it;
|
|
||||||
for(it=params.begin(); it!=params.end(); it++)
|
|
||||||
{
|
|
||||||
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
|
|
||||||
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
|
|
||||||
*content += key;
|
|
||||||
*content += '=';
|
|
||||||
*content += value;
|
|
||||||
*content += '&';
|
|
||||||
curl_free(key);
|
|
||||||
curl_free(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
|
|
||||||
{
|
|
||||||
if(params.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string content;
|
|
||||||
this->makeUrlencodedForm(params, &content);
|
|
||||||
bool url_has_param = false;
|
|
||||||
for (const auto& ch : *url) {
|
|
||||||
if (ch == '?') {
|
|
||||||
url_has_param = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (url_has_param) {
|
|
||||||
url->append("&");
|
|
||||||
} else {
|
|
||||||
url->append("?");
|
|
||||||
}
|
|
||||||
url->append(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
|
|
||||||
{
|
|
||||||
std::ostringstream ostr;
|
|
||||||
std::map<std::string, std::string>::const_iterator it;
|
|
||||||
for(it=headers.begin(); it!=headers.end(); it++)
|
|
||||||
{
|
|
||||||
ostr << it->first << ":" << it->second;
|
|
||||||
*slist = curl_slist_append(*slist, ostr.str().c_str());
|
|
||||||
ostr.str("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
HttpClient() = default;
|
|
||||||
|
|
||||||
HttpClient(const HttpClient &) = delete;
|
|
||||||
HttpClient & operator=(const HttpClient &) = delete;
|
|
||||||
|
|
||||||
void setConnectTimeout(int connect_timeout)
|
|
||||||
{
|
|
||||||
this->connect_timeout = connect_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSocketTimeout(int socket_timeout)
|
|
||||||
{
|
|
||||||
this->socket_timeout = socket_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDebug(bool debug)
|
|
||||||
{
|
|
||||||
this->debug = debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
CURL * curl = curl_easy_init();
|
|
||||||
struct curl_slist * slist = NULL;
|
|
||||||
if (headers) {
|
|
||||||
this->appendHeaders(*headers, &slist);
|
|
||||||
}
|
|
||||||
if (params) {
|
|
||||||
this->appendUrlParams(*params, &url);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
|
||||||
|
|
||||||
int status_code = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_slist_free_all(slist);
|
|
||||||
|
|
||||||
return status_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
const std::string & body,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
struct curl_slist * slist = NULL;
|
|
||||||
CURL * curl = curl_easy_init();
|
|
||||||
if (headers) {
|
|
||||||
this->appendHeaders(*headers, &slist);
|
|
||||||
}
|
|
||||||
if (params) {
|
|
||||||
this->appendUrlParams(*params, &url);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POST, true);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
|
||||||
|
|
||||||
int status_code = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_slist_free_all(slist);
|
|
||||||
|
|
||||||
return status_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
std::map<std::string, std::string> const & data,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string body;
|
|
||||||
this->makeUrlencodedForm(data, &body);
|
|
||||||
return this->post(std::move(url), params, body, headers, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
Json::Value const & data,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
std::string body;
|
|
||||||
Json::StreamWriterBuilder swb;
|
|
||||||
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
|
|
||||||
std::ostringstream os;
|
|
||||||
writer->write(data, &os);
|
|
||||||
body = os.str();
|
|
||||||
std::map<std::string, std::string> temp_headers;
|
|
||||||
if (headers) {
|
|
||||||
std::map<std::string, std::string> temp_headers(*headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_headers["Content-Type"] = "application/json";
|
|
||||||
return this->post(url.c_str(), params, body, &temp_headers, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
const static std::string EMPTY_STRING;
|
|
||||||
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,283 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_UTILS_H__
|
|
||||||
#define __AIP_UTILS_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <openssl/md5.h>
|
|
||||||
|
|
||||||
const int __BCE_VERSION__ = 1;
|
|
||||||
const int __BCE_EXPIRE__ = 1800;
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
template<class CharT, class Traits, class Allocator>
|
|
||||||
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
|
|
||||||
std::basic_string<CharT, Traits, Allocator>& str) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << input.rdbuf();
|
|
||||||
str.assign(oss.str());
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int get_file_content(const char *filename, std::string* out) {
|
|
||||||
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
|
||||||
if (in) {
|
|
||||||
getall(in, *out);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string to_upper(std::string src)
|
|
||||||
{
|
|
||||||
std::transform(src.begin(), src.end(), src.begin(), toupper);
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string to_lower(std::string src)
|
|
||||||
{
|
|
||||||
std::transform(src.begin(), src.end(), src.begin(), tolower);
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string to_hex(unsigned char c, bool lower = false)
|
|
||||||
{
|
|
||||||
const std::string hex = "0123456789ABCDEF";
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << hex[c >> 4] << hex[c & 0xf];
|
|
||||||
|
|
||||||
return lower ? to_lower(ss.str()) : ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline time_t now()
|
|
||||||
{
|
|
||||||
return time(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string utc_time(time_t timestamp)
|
|
||||||
{
|
|
||||||
struct tm result_tm;
|
|
||||||
char buffer[32];
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
gmtime_s(&result_tm, ×tamp);
|
|
||||||
#else
|
|
||||||
gmtime_r(×tamp, &result_tm);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
|
|
||||||
|
|
||||||
return std::string(buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void url_parse(
|
|
||||||
const std::string & url,
|
|
||||||
std::map<std::string, std::string> & params)
|
|
||||||
{
|
|
||||||
int pos = (int)url.find("?");
|
|
||||||
if (pos != -1)
|
|
||||||
{
|
|
||||||
int key_start = pos + 1,
|
|
||||||
key_len = 0,
|
|
||||||
val_start = 0;
|
|
||||||
for (int i = key_start; i <= (int)url.size(); ++i)
|
|
||||||
{
|
|
||||||
switch (url[i])
|
|
||||||
{
|
|
||||||
case '=':
|
|
||||||
key_len = i - key_start;
|
|
||||||
val_start = i + 1;
|
|
||||||
break;
|
|
||||||
case '\0':
|
|
||||||
case '&':
|
|
||||||
if (key_len != 0)
|
|
||||||
{
|
|
||||||
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
|
|
||||||
key_start = i + 1;
|
|
||||||
key_len = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string url_encode(const std::string & input, bool encode_slash=true)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
const char *str = input.c_str();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < input.size(); i++)
|
|
||||||
{
|
|
||||||
unsigned char c = str[i];
|
|
||||||
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
|
|
||||||
{
|
|
||||||
ss << c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss << "%" << to_hex(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string canonicalize_params(std::map<std::string, std::string> & params)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
v.reserve(params.size());
|
|
||||||
|
|
||||||
for (auto & it : params) {
|
|
||||||
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
|
|
||||||
}
|
|
||||||
std::sort(v.begin(), v.end());
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
for (auto & it : v)
|
|
||||||
{
|
|
||||||
result.append((result.empty() ? "" : "&") + it);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
v.reserve(headers.size());
|
|
||||||
|
|
||||||
for (auto & it : headers) {
|
|
||||||
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
|
|
||||||
}
|
|
||||||
std::sort(v.begin(), v.end());
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
for (auto & it : v)
|
|
||||||
{
|
|
||||||
result.append((result.empty() ? "" : "\n") + it);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string get_headers_keys(std::map<std::string, std::string> & headers)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
v.reserve(headers.size());
|
|
||||||
|
|
||||||
for (auto & it : headers) {
|
|
||||||
v.push_back(to_lower(it.first));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
for (auto & it : v)
|
|
||||||
{
|
|
||||||
result.append((result.empty() ? "" : ";") + it);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string get_host(const std::string & url)
|
|
||||||
{
|
|
||||||
int pos = (int)url.find("://") + 3;
|
|
||||||
return url.substr(
|
|
||||||
pos,
|
|
||||||
url.find('/', pos) - pos
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string get_path(const std::string & url)
|
|
||||||
{
|
|
||||||
int path_start = (int)url.find('/', url.find("://") + 3);
|
|
||||||
int path_end = (int)url.find('?');
|
|
||||||
path_end = path_end == -1 ? (int)url.size() : path_end;
|
|
||||||
|
|
||||||
return url.substr(path_start, path_end - path_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string hmac_sha256(
|
|
||||||
const std::string & src,
|
|
||||||
const std::string & sk)
|
|
||||||
{
|
|
||||||
const EVP_MD *evp_md = EVP_sha256();
|
|
||||||
unsigned char md[EVP_MAX_MD_SIZE];
|
|
||||||
unsigned int md_len = 0;
|
|
||||||
|
|
||||||
if (HMAC(evp_md,
|
|
||||||
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
|
|
||||||
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
|
|
||||||
md, &md_len) == NULL)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
for (int i = 0; i < (int)md_len; ++i)
|
|
||||||
{
|
|
||||||
ss << to_hex(md[i], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sign(
|
|
||||||
std::string method,
|
|
||||||
std::string & url,
|
|
||||||
std::map<std::string, std::string> & params,
|
|
||||||
std::map<std::string, std::string> & headers,
|
|
||||||
std::string & ak,
|
|
||||||
std::string & sk)
|
|
||||||
{
|
|
||||||
url_parse(url, params);
|
|
||||||
headers["Host"] = get_host(url);
|
|
||||||
std::string timestamp = utc_time(now());
|
|
||||||
headers["x-bce-date"] = timestamp;
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
|
||||||
<< timestamp << "/" << __BCE_EXPIRE__;
|
|
||||||
|
|
||||||
std::string val = ss.str();
|
|
||||||
std::string sign_key = hmac_sha256(val, sk);
|
|
||||||
|
|
||||||
ss.str("");
|
|
||||||
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
|
|
||||||
<< '\n' << canonicalize_params(params)
|
|
||||||
<< '\n' << canonicalize_headers(headers);
|
|
||||||
|
|
||||||
std::string signature = hmac_sha256(ss.str(), sign_key);
|
|
||||||
|
|
||||||
ss.str("");
|
|
||||||
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
|
||||||
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
|
|
||||||
<< get_headers_keys(headers) << "/" << signature;
|
|
||||||
|
|
||||||
headers["authorization"] = ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,38 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
#include "ocr.h" // 用于调用接口
|
|
||||||
#include <string> // 用于 string 的操作
|
|
||||||
#include <codecvt> // 用于转码
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main(int argc, char const *argv[]) // argc: 参数个数, argv: 参数列表
|
|
||||||
{
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
cout << "Usage: " << argv[0] << "车牌照片路径" << endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
string app_id = "35458273"; // 你的 App ID
|
|
||||||
string api_key = "i45yQx4IaGoxxULLDVPl4iNj"; // 你的 Api Key
|
|
||||||
string secret_key = "jnt90aTbXCOp9L7gRB1xq1C3iT0bLuie"; // 你的 Secret Key
|
|
||||||
|
|
||||||
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
|
||||||
cout << "ok" << endl;
|
|
||||||
|
|
||||||
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
|
||||||
Json::Value result;
|
|
||||||
string image;
|
|
||||||
|
|
||||||
// 加载本地的车牌图片内容到 image 对象中, 用于调用车牌识别
|
|
||||||
// aip::get_file_content("R-C.jpg", &image);
|
|
||||||
aip::get_file_content(argv[1], &image);
|
|
||||||
|
|
||||||
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
|
||||||
result = client.license_plate(image, aip::null);
|
|
||||||
// cout << result << endl;
|
|
||||||
cout << "车牌颜色: " << result["words_result"]["color"] << endl;
|
|
||||||
cout << "车牌号码: " << result["words_result"]["number"].asString() << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
1551
day13/LPR/ocr.h
|
@ -1,55 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
#include "ocr.h" // 用于调用接口
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
string cardType(int);
|
|
||||||
|
|
||||||
int main(int argc, char const *argv[])
|
|
||||||
{
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
cout << "用法: " << argv[0] << " 银行卡照片" << endl;
|
|
||||||
return -1; // 返回 -1 表示程序异常退出
|
|
||||||
}
|
|
||||||
|
|
||||||
string app_id = "35475147"; // 你的 App ID
|
|
||||||
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
|
|
||||||
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
|
|
||||||
|
|
||||||
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
|
||||||
// cout << "ok" << endl;
|
|
||||||
|
|
||||||
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
|
||||||
Json::Value result;
|
|
||||||
string image; // 用于存储图片内容
|
|
||||||
|
|
||||||
// 加载本地的银行卡图片内容到 image 对象中, 用于调用银行卡识别
|
|
||||||
aip::get_file_content(argv[1], &image);
|
|
||||||
|
|
||||||
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
|
||||||
result = client.bankcard(image, aip::null);
|
|
||||||
|
|
||||||
int cardTypeNum = result["result"]["bank_card_type"].asInt(); // 卡类型判定 0:不能识别; 1: 借记卡; 2: 信用卡
|
|
||||||
|
|
||||||
cout << "识别到的银行卡信息如下: " << endl;
|
|
||||||
cout << "发卡行: " << result["result"]["bank_name"].asString() << endl;
|
|
||||||
cout << "卡号: " << result["result"]["bank_card_number"].asString() << endl;
|
|
||||||
cout << "卡类型: " << cardType(cardTypeNum) << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卡类型判定 0:不能识别; 1: 借记卡; 2: 信用卡
|
|
||||||
string cardType(int type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return "不能识别";
|
|
||||||
case 1:
|
|
||||||
return "借记卡";
|
|
||||||
case 2:
|
|
||||||
return "信用卡";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,264 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_BASE_H__
|
|
||||||
#define __AIP_BASE_H__
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <cstring>
|
|
||||||
#include "http.h"
|
|
||||||
#include "json/json.h"
|
|
||||||
#include "base64.h"
|
|
||||||
#include "curl/curl.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
static const char* AIP_SDK_VERSION = "0.3.3";
|
|
||||||
static const char* CURL_ERROR_CODE = "curl_error_code";
|
|
||||||
static const std::string ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
|
|
||||||
static const std::map<std::string, std::string> null;
|
|
||||||
|
|
||||||
class AipBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string _app_id;
|
|
||||||
int _expired_time;
|
|
||||||
bool _is_bce;
|
|
||||||
bool _has_decide_type;
|
|
||||||
std::string _scope;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string getAccessToken()
|
|
||||||
{
|
|
||||||
time_t now = time(NULL);
|
|
||||||
if (!access_token.empty())
|
|
||||||
{
|
|
||||||
return this->access_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (now < this->_expired_time - 60 * 60 * 24)
|
|
||||||
{
|
|
||||||
return this->access_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string response;
|
|
||||||
std::map<std::string, std::string> params;
|
|
||||||
|
|
||||||
params["grant_type"] = "client_credentials";
|
|
||||||
params["client_id"] = this->ak;
|
|
||||||
params["client_secret"] = this->sk;
|
|
||||||
int status_code = this->client.get(
|
|
||||||
ACCESS_TOKEN_URL,
|
|
||||||
¶ms,
|
|
||||||
nullptr,
|
|
||||||
&response
|
|
||||||
);
|
|
||||||
Json::Value obj;
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj.toStyledString();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
this->access_token = obj["access_token"].asString();
|
|
||||||
this->_expired_time = obj["expires_in"].asInt() + (int) now;
|
|
||||||
this->_scope = obj["scope"].asString();
|
|
||||||
return this->access_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::string ak;
|
|
||||||
std::string sk;
|
|
||||||
HttpClient client;
|
|
||||||
Json::CharReaderBuilder crbuilder;
|
|
||||||
std::string access_token;
|
|
||||||
AipBase(const std::string & app_id, const std::string & ak, const std::string & sk):
|
|
||||||
_app_id(app_id),
|
|
||||||
_is_bce(false),
|
|
||||||
_has_decide_type(false),
|
|
||||||
ak(ak),
|
|
||||||
sk(sk)
|
|
||||||
{
|
|
||||||
if (_app_id == "")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setConnectionTimeoutInMillis(int connect_timeout)
|
|
||||||
{
|
|
||||||
this->client.setConnectTimeout(connect_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSocketTimeoutInMillis(int socket_timeout)
|
|
||||||
{
|
|
||||||
this->client.setSocketTimeout(socket_timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDebug(bool debug)
|
|
||||||
{
|
|
||||||
this->client.setDebug(debug);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getAk() {
|
|
||||||
return ak;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value request(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const & params,
|
|
||||||
std::string const & data,
|
|
||||||
std::map<std::string, std::string> const & headers)
|
|
||||||
{
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
std::string body;
|
|
||||||
auto headers_for_sign = headers;
|
|
||||||
|
|
||||||
auto temp_params = params;
|
|
||||||
|
|
||||||
temp_params["charset"] = "UTF-8";
|
|
||||||
|
|
||||||
this->prepare_request(url, temp_params, headers_for_sign);
|
|
||||||
|
|
||||||
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
|
||||||
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value request(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const & params,
|
|
||||||
std::map<std::string, std::string> const & data,
|
|
||||||
std::map<std::string, std::string> const & headers)
|
|
||||||
{
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
|
|
||||||
auto headers_for_sign = headers;
|
|
||||||
auto temp_params = params;
|
|
||||||
|
|
||||||
this->prepare_request(url, temp_params, headers_for_sign);
|
|
||||||
|
|
||||||
int status_code = this->client.post(url, &temp_params, data, &headers_for_sign, &response);
|
|
||||||
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void prepare_request(std::string url,
|
|
||||||
std::map<std::string, std::string> & params,
|
|
||||||
std::map<std::string, std::string> & headers)
|
|
||||||
{
|
|
||||||
|
|
||||||
params["aipSdk"] = "C";
|
|
||||||
params["aipSdkVersion"] = AIP_SDK_VERSION;
|
|
||||||
|
|
||||||
if (_has_decide_type) {
|
|
||||||
if (_is_bce) {
|
|
||||||
std::string method = "POST";
|
|
||||||
sign(method, url, params, headers, ak, sk);
|
|
||||||
} else {
|
|
||||||
params["access_token"] = this->getAccessToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getAccessToken() == "") {
|
|
||||||
_is_bce = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const char * t = std::strstr(this->_scope.c_str(), "brain_all_scope");
|
|
||||||
|
|
||||||
if (t == NULL)
|
|
||||||
{
|
|
||||||
_is_bce = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_has_decide_type = true;
|
|
||||||
prepare_request(url, params, headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Json::Value requestjson(
|
|
||||||
std::string url,
|
|
||||||
Json::Value & data,
|
|
||||||
std::map<std::string, std::string> & params,
|
|
||||||
std::map<std::string, std::string> const & headers)
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
auto headers_for_sign = headers;
|
|
||||||
auto temp_params = params;
|
|
||||||
this->prepare_request(url, temp_params, headers_for_sign);
|
|
||||||
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[aip::CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value request_com(
|
|
||||||
std::string const & url,
|
|
||||||
Json::Value & data)
|
|
||||||
{
|
|
||||||
std::string response;
|
|
||||||
Json::Value obj;
|
|
||||||
int status_code = this->client.post(url, nullptr, data, nullptr, &response);
|
|
||||||
|
|
||||||
if (status_code != CURLcode::CURLE_OK) {
|
|
||||||
obj[aip::CURL_ERROR_CODE] = status_code;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
std::string error;
|
|
||||||
std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
|
|
||||||
reader->parse(response.data(), response.data() + response.size(), &obj, &error);
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,130 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_BASE64_H__
|
|
||||||
#define __AIP_BASE64_H__
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
static const std::string base64_chars =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
|
||||||
"0123456789+/";
|
|
||||||
|
|
||||||
|
|
||||||
static inline bool is_base64(const char c)
|
|
||||||
{
|
|
||||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string base64_encode(const char * bytes_to_encode, unsigned int in_len)
|
|
||||||
{
|
|
||||||
std::string ret;
|
|
||||||
int i = 0;
|
|
||||||
int j = 0;
|
|
||||||
unsigned char char_array_3[3];
|
|
||||||
unsigned char char_array_4[4];
|
|
||||||
|
|
||||||
while (in_len--)
|
|
||||||
{
|
|
||||||
char_array_3[i++] = *(bytes_to_encode++);
|
|
||||||
if(i == 3)
|
|
||||||
{
|
|
||||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
||||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
||||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
||||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
||||||
|
|
||||||
for(i = 0; (i <4) ; i++)
|
|
||||||
{
|
|
||||||
ret += base64_chars[char_array_4[i]];
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i)
|
|
||||||
{
|
|
||||||
for(j = i; j < 3; j++)
|
|
||||||
{
|
|
||||||
char_array_3[j] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
|
||||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
|
||||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
|
||||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
|
||||||
|
|
||||||
for(j = 0; (j < i + 1); j++)
|
|
||||||
{
|
|
||||||
ret += base64_chars[char_array_4[j]];
|
|
||||||
}
|
|
||||||
|
|
||||||
while((i++ < 3))
|
|
||||||
{
|
|
||||||
ret += '=';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string base64_decode(std::string const & encoded_string)
|
|
||||||
{
|
|
||||||
int in_len = (int) encoded_string.size();
|
|
||||||
int i = 0;
|
|
||||||
int j = 0;
|
|
||||||
int in_ = 0;
|
|
||||||
unsigned char char_array_4[4], char_array_3[3];
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
|
||||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
|
||||||
if (i ==4) {
|
|
||||||
for (i = 0; i <4; i++)
|
|
||||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
|
||||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
|
||||||
|
|
||||||
for (i = 0; (i < 3); i++)
|
|
||||||
ret += char_array_3[i];
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i) {
|
|
||||||
for (j = i; j <4; j++)
|
|
||||||
char_array_4[j] = 0;
|
|
||||||
|
|
||||||
for (j = 0; j <4; j++)
|
|
||||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
|
||||||
|
|
||||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
|
||||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
|
||||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
|
||||||
|
|
||||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,234 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_HTTP_H__
|
|
||||||
#define __AIP_HTTP_H__
|
|
||||||
|
|
||||||
#include "curl/curl.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <json/json.h>
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
inline size_t onWriteData(void * buffer, size_t size, size_t nmemb, void * userp)
|
|
||||||
{
|
|
||||||
std::string * str = dynamic_cast<std::string *>((std::string *)userp);
|
|
||||||
str->append((char *)buffer, size * nmemb);
|
|
||||||
return nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
class HttpClient
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool debug = false;
|
|
||||||
int connect_timeout = 10000;
|
|
||||||
int socket_timeout = 10000;
|
|
||||||
|
|
||||||
void makeUrlencodedForm(std::map<std::string, std::string> const & params, std::string * content) const
|
|
||||||
{
|
|
||||||
content->clear();
|
|
||||||
std::map<std::string, std::string>::const_iterator it;
|
|
||||||
for(it=params.begin(); it!=params.end(); it++)
|
|
||||||
{
|
|
||||||
char * key = curl_escape(it->first.c_str(), (int) it->first.size());
|
|
||||||
char * value = curl_escape(it->second.c_str(),(int) it->second.size());
|
|
||||||
*content += key;
|
|
||||||
*content += '=';
|
|
||||||
*content += value;
|
|
||||||
*content += '&';
|
|
||||||
curl_free(key);
|
|
||||||
curl_free(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendUrlParams(std::map<std::string, std::string> const & params, std::string* url) const
|
|
||||||
{
|
|
||||||
if(params.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string content;
|
|
||||||
this->makeUrlencodedForm(params, &content);
|
|
||||||
bool url_has_param = false;
|
|
||||||
for (const auto& ch : *url) {
|
|
||||||
if (ch == '?') {
|
|
||||||
url_has_param = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (url_has_param) {
|
|
||||||
url->append("&");
|
|
||||||
} else {
|
|
||||||
url->append("?");
|
|
||||||
}
|
|
||||||
url->append(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendHeaders(std::map<std::string, std::string> const & headers, curl_slist ** slist) const
|
|
||||||
{
|
|
||||||
std::ostringstream ostr;
|
|
||||||
std::map<std::string, std::string>::const_iterator it;
|
|
||||||
for(it=headers.begin(); it!=headers.end(); it++)
|
|
||||||
{
|
|
||||||
ostr << it->first << ":" << it->second;
|
|
||||||
*slist = curl_slist_append(*slist, ostr.str().c_str());
|
|
||||||
ostr.str("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
HttpClient() = default;
|
|
||||||
|
|
||||||
HttpClient(const HttpClient &) = delete;
|
|
||||||
HttpClient & operator=(const HttpClient &) = delete;
|
|
||||||
|
|
||||||
void setConnectTimeout(int connect_timeout)
|
|
||||||
{
|
|
||||||
this->connect_timeout = connect_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSocketTimeout(int socket_timeout)
|
|
||||||
{
|
|
||||||
this->socket_timeout = socket_timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDebug(bool debug)
|
|
||||||
{
|
|
||||||
this->debug = debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
int get(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
CURL * curl = curl_easy_init();
|
|
||||||
struct curl_slist * slist = NULL;
|
|
||||||
if (headers) {
|
|
||||||
this->appendHeaders(*headers, &slist);
|
|
||||||
}
|
|
||||||
if (params) {
|
|
||||||
this->appendUrlParams(*params, &url);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
|
||||||
|
|
||||||
int status_code = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_slist_free_all(slist);
|
|
||||||
|
|
||||||
return status_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
const std::string & body,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
struct curl_slist * slist = NULL;
|
|
||||||
CURL * curl = curl_easy_init();
|
|
||||||
if (headers) {
|
|
||||||
this->appendHeaders(*headers, &slist);
|
|
||||||
}
|
|
||||||
if (params) {
|
|
||||||
this->appendUrlParams(*params, &url);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POST, true);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, this->connect_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, this->socket_timeout);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, this->debug);
|
|
||||||
|
|
||||||
int status_code = curl_easy_perform(curl);
|
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_slist_free_all(slist);
|
|
||||||
|
|
||||||
return status_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
std::map<std::string, std::string> const & data,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string body;
|
|
||||||
this->makeUrlencodedForm(data, &body);
|
|
||||||
return this->post(std::move(url), params, body, headers, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
Json::Value const & data,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
std::string body;
|
|
||||||
Json::StreamWriterBuilder swb;
|
|
||||||
std::unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
|
|
||||||
std::ostringstream os;
|
|
||||||
writer->write(data, &os);
|
|
||||||
body = os.str();
|
|
||||||
std::map<std::string, std::string> temp_headers;
|
|
||||||
if (headers) {
|
|
||||||
std::map<std::string, std::string> temp_headers(*headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_headers["Content-Type"] = "application/json";
|
|
||||||
return this->post(url.c_str(), params, body, &temp_headers, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int post(
|
|
||||||
std::string url,
|
|
||||||
std::map<std::string, std::string> const * params,
|
|
||||||
std::map<std::string, std::string> const * headers,
|
|
||||||
std::string * response) const
|
|
||||||
{
|
|
||||||
const static std::string EMPTY_STRING;
|
|
||||||
return this->post(std::move(url), params, EMPTY_STRING, headers, response);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,283 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* @author baidu aip
|
|
||||||
*/
|
|
||||||
#ifndef __AIP_UTILS_H__
|
|
||||||
#define __AIP_UTILS_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <openssl/md5.h>
|
|
||||||
|
|
||||||
const int __BCE_VERSION__ = 1;
|
|
||||||
const int __BCE_EXPIRE__ = 1800;
|
|
||||||
|
|
||||||
namespace aip {
|
|
||||||
|
|
||||||
template<class CharT, class Traits, class Allocator>
|
|
||||||
std::basic_istream<CharT, Traits>& getall(std::basic_istream<CharT, Traits>& input,
|
|
||||||
std::basic_string<CharT, Traits, Allocator>& str) {
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << input.rdbuf();
|
|
||||||
str.assign(oss.str());
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int get_file_content(const char *filename, std::string* out) {
|
|
||||||
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
|
||||||
if (in) {
|
|
||||||
getall(in, *out);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string to_upper(std::string src)
|
|
||||||
{
|
|
||||||
std::transform(src.begin(), src.end(), src.begin(), toupper);
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline std::string to_lower(std::string src)
|
|
||||||
{
|
|
||||||
std::transform(src.begin(), src.end(), src.begin(), tolower);
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string to_hex(unsigned char c, bool lower = false)
|
|
||||||
{
|
|
||||||
const std::string hex = "0123456789ABCDEF";
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << hex[c >> 4] << hex[c & 0xf];
|
|
||||||
|
|
||||||
return lower ? to_lower(ss.str()) : ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline time_t now()
|
|
||||||
{
|
|
||||||
return time(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string utc_time(time_t timestamp)
|
|
||||||
{
|
|
||||||
struct tm result_tm;
|
|
||||||
char buffer[32];
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
gmtime_s(&result_tm, ×tamp);
|
|
||||||
#else
|
|
||||||
gmtime_r(×tamp, &result_tm);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t size = strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &result_tm);
|
|
||||||
|
|
||||||
return std::string(buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void url_parse(
|
|
||||||
const std::string & url,
|
|
||||||
std::map<std::string, std::string> & params)
|
|
||||||
{
|
|
||||||
int pos = (int)url.find("?");
|
|
||||||
if (pos != -1)
|
|
||||||
{
|
|
||||||
int key_start = pos + 1,
|
|
||||||
key_len = 0,
|
|
||||||
val_start = 0;
|
|
||||||
for (int i = key_start; i <= (int)url.size(); ++i)
|
|
||||||
{
|
|
||||||
switch (url[i])
|
|
||||||
{
|
|
||||||
case '=':
|
|
||||||
key_len = i - key_start;
|
|
||||||
val_start = i + 1;
|
|
||||||
break;
|
|
||||||
case '\0':
|
|
||||||
case '&':
|
|
||||||
if (key_len != 0)
|
|
||||||
{
|
|
||||||
params[url.substr(key_start, key_len)] = url.substr(val_start, i - val_start);
|
|
||||||
key_start = i + 1;
|
|
||||||
key_len = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string url_encode(const std::string & input, bool encode_slash=true)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
const char *str = input.c_str();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < input.size(); i++)
|
|
||||||
{
|
|
||||||
unsigned char c = str[i];
|
|
||||||
if (isalnum(c) || c == '_' || c == '-' || c == '~' || c == '.' || (!encode_slash && c == '/'))
|
|
||||||
{
|
|
||||||
ss << c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss << "%" << to_hex(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string canonicalize_params(std::map<std::string, std::string> & params)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
v.reserve(params.size());
|
|
||||||
|
|
||||||
for (auto & it : params) {
|
|
||||||
v.push_back(url_encode(it.first) + "=" + url_encode(it.second));
|
|
||||||
}
|
|
||||||
std::sort(v.begin(), v.end());
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
for (auto & it : v)
|
|
||||||
{
|
|
||||||
result.append((result.empty() ? "" : "&") + it);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string canonicalize_headers(std::map<std::string, std::string> & headers)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
v.reserve(headers.size());
|
|
||||||
|
|
||||||
for (auto & it : headers) {
|
|
||||||
v.push_back(url_encode(to_lower(it.first)) + ":" + url_encode(it.second));
|
|
||||||
}
|
|
||||||
std::sort(v.begin(), v.end());
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
for (auto & it : v)
|
|
||||||
{
|
|
||||||
result.append((result.empty() ? "" : "\n") + it);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string get_headers_keys(std::map<std::string, std::string> & headers)
|
|
||||||
{
|
|
||||||
std::vector<std::string> v;
|
|
||||||
v.reserve(headers.size());
|
|
||||||
|
|
||||||
for (auto & it : headers) {
|
|
||||||
v.push_back(to_lower(it.first));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string result;
|
|
||||||
for (auto & it : v)
|
|
||||||
{
|
|
||||||
result.append((result.empty() ? "" : ";") + it);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string get_host(const std::string & url)
|
|
||||||
{
|
|
||||||
int pos = (int)url.find("://") + 3;
|
|
||||||
return url.substr(
|
|
||||||
pos,
|
|
||||||
url.find('/', pos) - pos
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string get_path(const std::string & url)
|
|
||||||
{
|
|
||||||
int path_start = (int)url.find('/', url.find("://") + 3);
|
|
||||||
int path_end = (int)url.find('?');
|
|
||||||
path_end = path_end == -1 ? (int)url.size() : path_end;
|
|
||||||
|
|
||||||
return url.substr(path_start, path_end - path_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string hmac_sha256(
|
|
||||||
const std::string & src,
|
|
||||||
const std::string & sk)
|
|
||||||
{
|
|
||||||
const EVP_MD *evp_md = EVP_sha256();
|
|
||||||
unsigned char md[EVP_MAX_MD_SIZE];
|
|
||||||
unsigned int md_len = 0;
|
|
||||||
|
|
||||||
if (HMAC(evp_md,
|
|
||||||
reinterpret_cast<const unsigned char *>(sk.data()), (int)sk.size(),
|
|
||||||
reinterpret_cast<const unsigned char *>(src.data()), src.size(),
|
|
||||||
md, &md_len) == NULL)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
for (int i = 0; i < (int)md_len; ++i)
|
|
||||||
{
|
|
||||||
ss << to_hex(md[i], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sign(
|
|
||||||
std::string method,
|
|
||||||
std::string & url,
|
|
||||||
std::map<std::string, std::string> & params,
|
|
||||||
std::map<std::string, std::string> & headers,
|
|
||||||
std::string & ak,
|
|
||||||
std::string & sk)
|
|
||||||
{
|
|
||||||
url_parse(url, params);
|
|
||||||
headers["Host"] = get_host(url);
|
|
||||||
std::string timestamp = utc_time(now());
|
|
||||||
headers["x-bce-date"] = timestamp;
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
|
||||||
<< timestamp << "/" << __BCE_EXPIRE__;
|
|
||||||
|
|
||||||
std::string val = ss.str();
|
|
||||||
std::string sign_key = hmac_sha256(val, sk);
|
|
||||||
|
|
||||||
ss.str("");
|
|
||||||
ss << to_upper(method) << '\n' << url_encode(get_path(url), false)
|
|
||||||
<< '\n' << canonicalize_params(params)
|
|
||||||
<< '\n' << canonicalize_headers(headers);
|
|
||||||
|
|
||||||
std::string signature = hmac_sha256(ss.str(), sign_key);
|
|
||||||
|
|
||||||
ss.str("");
|
|
||||||
ss << "bce-auth-v" << __BCE_VERSION__ << "/" << ak << "/"
|
|
||||||
<< timestamp << "/" << __BCE_EXPIRE__ << "/"
|
|
||||||
<< get_headers_keys(headers) << "/" << signature;
|
|
||||||
|
|
||||||
headers["authorization"] = ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,44 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
#include "ocr.h" // 用于调用接口
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main(int argc, char const *argv[])
|
|
||||||
{
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
cout << "用法: " << argv[0] << " 驾驶证照片" << endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
string app_id = "35475147"; // 你的 App ID
|
|
||||||
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
|
|
||||||
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
|
|
||||||
|
|
||||||
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
|
||||||
// cout << "ok" << endl;
|
|
||||||
|
|
||||||
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
|
||||||
Json::Value result;
|
|
||||||
string image;
|
|
||||||
|
|
||||||
// 加载本地的驾驶证图片内容到 image 对象中, 用于调用驾驶证识别
|
|
||||||
aip::get_file_content(argv[1], &image);
|
|
||||||
|
|
||||||
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
|
||||||
result = client.driving_license(image, aip::null);
|
|
||||||
cout << "识别到的驾驶证信息如下: " << endl;
|
|
||||||
// cout << result << endl;
|
|
||||||
cout << "姓名: " << result["words_result"]["姓名"]["words"].asString() << endl;
|
|
||||||
cout << "出生日期: " << result["words_result"]["出生日期"]["words"].asString() << endl;
|
|
||||||
cout << "证号: " << result["words_result"]["证号"]["words"].asString() << endl;
|
|
||||||
cout << "住址: " << result["words_result"]["住址"]["words"].asString() << endl;
|
|
||||||
cout << "发证单位: " << result["words_result"]["发证单位"]["words"].asString() << endl;
|
|
||||||
cout << "初次领证日期: " << result["words_result"]["初次领证日期"]["words"].asString() << endl;
|
|
||||||
cout << "国籍: " << result["words_result"]["国籍"]["words"].asString() << endl;
|
|
||||||
cout << "准驾车型: " << result["words_result"]["准驾车型"]["words"].asString() << endl;
|
|
||||||
cout << "性别: " << result["words_result"]["性别"]["words"].asString() << endl;
|
|
||||||
cout << "有效期限: " << result["words_result"]["有效期限"]["words"].asString() << " 至 " << result["words_result"]["至"]["words"].asString() << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
#include "ocr.h" // 用于调用接口
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int main(int argc, char const *argv[])
|
|
||||||
{
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
cout << "用法: " << argv[0] << " 身份证照片" << endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
string app_id = "35475147"; // 你的 App ID
|
|
||||||
string api_key = "CSneGCoRs8zMD1F1PPnXyzPP"; // 你的 Api Key
|
|
||||||
string secret_key = "wlKjVS2lE9xPFVV7G5EI3gYm7Zk3tnu1"; // 你的 Secret Key
|
|
||||||
|
|
||||||
aip::Ocr client(app_id, api_key, secret_key); // 新建一个对象, 用于调用接口, 调用通用文字识别, 图片参数为本地图片
|
|
||||||
// cout << "ok" << endl;
|
|
||||||
|
|
||||||
// 定义 json 格式的数据类型 Value, result 是 json 类型的 Value 类实例, 用于存储返回的结果
|
|
||||||
Json::Value result;
|
|
||||||
string image;
|
|
||||||
|
|
||||||
// 加载本地的身份证图片内容到 image 对象中, 用于调用身份证识别
|
|
||||||
aip::get_file_content(argv[1], &image);
|
|
||||||
|
|
||||||
// 客户端发送图片内容到百度服务器, 并返回结果到 result 对象中
|
|
||||||
result = client.idcard(image, "front", aip::null); // front: 正面, back: 背面
|
|
||||||
|
|
||||||
cout << "识别到的身份证信息如下: " << endl;
|
|
||||||
cout << "姓名: " << result["words_result"]["姓名"]["words"].asString() << endl;
|
|
||||||
cout << "性别: " << result["words_result"]["性别"]["words"].asString() << endl;
|
|
||||||
cout << "民族: " << result["words_result"]["民族"]["words"].asString() << endl;
|
|
||||||
cout << "出生: " << result["words_result"]["出生"]["words"].asString() << endl;
|
|
||||||
cout << "住址: " << result["words_result"]["住址"]["words"].asString() << endl;
|
|
||||||
cout << "公民身份号码: " << result["words_result"]["公民身份号码"]["words"].asString() << endl;
|
|
||||||
// cout << "-------------------------" << endl;
|
|
||||||
// cout << result << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Before Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 260 KiB |
Before Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 166 KiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 1.2 MiB |