http客户端支持多cookie
This commit is contained in:
parent
4662c1feb0
commit
23d793c9c2
|
|
@ -263,42 +263,39 @@ void HttpClient::onResponseCompleted_l() {
|
||||||
|
|
||||||
void HttpClient::checkCookie(HttpClient::HttpHeader &headers) {
|
void HttpClient::checkCookie(HttpClient::HttpHeader &headers) {
|
||||||
//Set-Cookie: IPTV_SERVER=8E03927B-CC8C-4389-BC00-31DBA7EC7B49;expires=Sun, Sep 23 2018 15:07:31 GMT;path=/index/api/
|
//Set-Cookie: IPTV_SERVER=8E03927B-CC8C-4389-BC00-31DBA7EC7B49;expires=Sun, Sep 23 2018 15:07:31 GMT;path=/index/api/
|
||||||
auto it_set_cookie = headers.find("Set-Cookie");
|
for(auto it_set_cookie = headers.find("Set-Cookie") ; it_set_cookie != headers.end() ; ++it_set_cookie ){
|
||||||
if(it_set_cookie == headers.end()){
|
auto key_val = Parser::parseArgs(it_set_cookie->second,";","=");
|
||||||
return;
|
HttpCookie::Ptr cookie = std::make_shared<HttpCookie>();
|
||||||
}
|
cookie->setHost(_lastHost);
|
||||||
auto key_val = Parser::parseArgs(it_set_cookie->second,";","=");
|
|
||||||
|
|
||||||
HttpCookie::Ptr cookie = std::make_shared<HttpCookie>();
|
int index = 0;
|
||||||
cookie->setHost(_lastHost);
|
auto arg_vec = split(it_set_cookie->second, ";");
|
||||||
|
for (string &key_val : arg_vec) {
|
||||||
|
auto key = FindField(key_val.data(),NULL,"=");
|
||||||
|
auto val = FindField(key_val.data(),"=", NULL);
|
||||||
|
|
||||||
int index = 0;
|
if(index++ == 0){
|
||||||
auto arg_vec = split(it_set_cookie->second, ";");
|
cookie->setKeyVal(key,val);
|
||||||
for (string &key_val : arg_vec) {
|
continue;
|
||||||
auto key = FindField(key_val.data(),NULL,"=");
|
}
|
||||||
auto val = FindField(key_val.data(),"=", NULL);
|
|
||||||
|
|
||||||
if(index++ == 0){
|
if(key == "path") {
|
||||||
cookie->setKeyVal(key,val);
|
cookie->setPath(val);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key == "expires"){
|
||||||
|
cookie->setExpires(val,headers["Date"]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key == "path") {
|
if(!(*cookie)){
|
||||||
cookie->setPath(val);
|
//无效的cookie
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(key == "expires"){
|
|
||||||
cookie->setExpires(val,headers["Date"]);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
HttpCookieStorage::Instance().set(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(*cookie)){
|
|
||||||
//无效的cookie
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HttpCookieStorage::Instance().set(cookie);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ void HttpCookieStorage::set(const HttpCookie::Ptr &cookie) {
|
||||||
if(!cookie || !(*cookie)){
|
if(!cookie || !(*cookie)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_all_cookie[cookie->_host][cookie->_path] = cookie;
|
_all_cookie[cookie->_host][cookie->_path][cookie->_key] = cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<HttpCookie::Ptr> HttpCookieStorage::get(const string &host, const string &path) {
|
vector<HttpCookie::Ptr> HttpCookieStorage::get(const string &host, const string &path) {
|
||||||
|
|
@ -88,29 +88,27 @@ vector<HttpCookie::Ptr> HttpCookieStorage::get(const string &host, const string
|
||||||
lock_guard<mutex> lck(_mtx_cookie);
|
lock_guard<mutex> lck(_mtx_cookie);
|
||||||
auto it = _all_cookie.find(host);
|
auto it = _all_cookie.find(host);
|
||||||
if(it == _all_cookie.end()){
|
if(it == _all_cookie.end()){
|
||||||
|
//未找到该host相关记录
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
auto &path_cookie = it->second;
|
//遍历该host下所有path
|
||||||
|
for(auto &pr : it->second){
|
||||||
auto lam = [&](const string &sub_path){
|
if(path.find(pr.first) != 0){
|
||||||
auto it_cookie = path_cookie.find(sub_path);
|
//这个path不匹配
|
||||||
if(it_cookie != path_cookie.end()){
|
continue;
|
||||||
if(*(it_cookie->second)){
|
|
||||||
ret.emplace_back(it_cookie->second);
|
|
||||||
}else{
|
|
||||||
path_cookie.erase(it_cookie);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
//遍历该path下的各个cookie
|
||||||
|
for(auto it_cookie = pr.second.begin() ; it_cookie != pr.second.end() ; ){
|
||||||
|
if(!*(it_cookie->second)){
|
||||||
int pos = 0;
|
//该cookie已经过期,移除之
|
||||||
do{
|
it_cookie = pr.second.erase(it_cookie);
|
||||||
auto sub_path = path.substr(0,pos + 1);
|
continue;
|
||||||
lam(sub_path);
|
}
|
||||||
pos = path.find('/',1 + pos);
|
//保存有效cookie
|
||||||
}while (pos != string::npos);
|
ret.emplace_back(it_cookie->second);
|
||||||
lam(path);
|
++it_cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,16 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http客户端cookie对象
|
||||||
|
*/
|
||||||
class HttpCookie {
|
class HttpCookie {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<HttpCookie> Ptr;
|
typedef std::shared_ptr<HttpCookie> Ptr;
|
||||||
|
|
@ -60,6 +64,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http客户端cookie全局保存器
|
||||||
|
*/
|
||||||
class HttpCookieStorage{
|
class HttpCookieStorage{
|
||||||
public:
|
public:
|
||||||
~HttpCookieStorage(){}
|
~HttpCookieStorage(){}
|
||||||
|
|
@ -69,7 +76,7 @@ public:
|
||||||
private:
|
private:
|
||||||
HttpCookieStorage(){};
|
HttpCookieStorage(){};
|
||||||
private:
|
private:
|
||||||
unordered_map<string,unordered_map<string,HttpCookie::Ptr> > _all_cookie;
|
unordered_map<string/*host*/,map<string/*cookie path*/,map<string/*cookie_key*/,HttpCookie::Ptr> > > _all_cookie;
|
||||||
mutex _mtx_cookie;
|
mutex _mtx_cookie;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,19 @@ struct StrCaseCompare {
|
||||||
bool operator()(const string &__x, const string &__y) const { return strcasecmp(__x.data(), __y.data()) < 0; }
|
bool operator()(const string &__x, const string &__y) const { return strcasecmp(__x.data(), __y.data()) < 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef map<string, string, StrCaseCompare> StrCaseMap;
|
|
||||||
|
class StrCaseMap : public multimap<string, string, StrCaseCompare>{
|
||||||
|
public:
|
||||||
|
StrCaseMap() = default;
|
||||||
|
~StrCaseMap() = default;
|
||||||
|
string &operator[](const string &key){
|
||||||
|
auto it = find(key);
|
||||||
|
if(it == end()){
|
||||||
|
it = emplace(key,"");
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
public:
|
public:
|
||||||
|
|
@ -155,7 +167,7 @@ public:
|
||||||
auto field = FindField(line.data(), NULL, ": ");
|
auto field = FindField(line.data(), NULL, ": ");
|
||||||
auto value = FindField(line.data(), ": ", NULL);
|
auto value = FindField(line.data(), ": ", NULL);
|
||||||
if (field.size() != 0) {
|
if (field.size() != 0) {
|
||||||
_mapHeaders[field] = value;
|
_mapHeaders.emplace(field,value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start = start + line.size() + 2;
|
start = start + line.size() + 2;
|
||||||
|
|
@ -235,7 +247,7 @@ public:
|
||||||
for (string &key_val : arg_vec) {
|
for (string &key_val : arg_vec) {
|
||||||
auto key = FindField(key_val.data(), NULL, key_delim);
|
auto key = FindField(key_val.data(), NULL, key_delim);
|
||||||
auto val = FindField(key_val.data(), key_delim, NULL);
|
auto val = FindField(key_val.data(), key_delim, NULL);
|
||||||
ret[key] = val;
|
ret.emplace(key,val);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue