Commit 23d793c9 by xiongziliang

http客户端支持多cookie

parent 4662c1fe
...@@ -263,42 +263,39 @@ void HttpClient::onResponseCompleted_l() { ...@@ -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,";","=");
int index = 0;
HttpCookie::Ptr cookie = std::make_shared<HttpCookie>(); auto arg_vec = split(it_set_cookie->second, ";");
cookie->setHost(_lastHost); for (string &key_val : arg_vec) {
auto key = FindField(key_val.data(),NULL,"=");
int index = 0; auto val = FindField(key_val.data(),"=", NULL);
auto arg_vec = split(it_set_cookie->second, ";");
for (string &key_val : arg_vec) { if(index++ == 0){
auto key = FindField(key_val.data(),NULL,"="); cookie->setKeyVal(key,val);
auto val = FindField(key_val.data(),"=", NULL); continue;
}
if(index++ == 0){ if(key == "path") {
cookie->setKeyVal(key,val); cookie->setPath(val);
continue; continue;
} }
if(key == "path") { if(key == "expires"){
cookie->setPath(val); cookie->setExpires(val,headers["Date"]);
continue; continue;
}
} }
if(key == "expires"){ if(!(*cookie)){
cookie->setExpires(val,headers["Date"]); //无效的cookie
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) { ...@@ -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 ...@@ -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); //遍历该path下的各个cookie
}else{ for(auto it_cookie = pr.second.begin() ; it_cookie != pr.second.end() ; ){
path_cookie.erase(it_cookie); if(!*(it_cookie->second)){
//该cookie已经过期,移除之
it_cookie = pr.second.erase(it_cookie);
continue;
} }
//保存有效cookie
ret.emplace_back(it_cookie->second);
++it_cookie;
} }
}; }
int pos = 0;
do{
auto sub_path = path.substr(0,pos + 1);
lam(sub_path);
pos = path.find('/',1 + pos);
}while (pos != string::npos);
lam(path);
return ret; return ret;
} }
......
...@@ -30,12 +30,16 @@ ...@@ -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: ...@@ -60,6 +64,9 @@ private:
}; };
/**
* http客户端cookie全局保存器
*/
class HttpCookieStorage{ class HttpCookieStorage{
public: public:
~HttpCookieStorage(){} ~HttpCookieStorage(){}
...@@ -69,7 +76,7 @@ public: ...@@ -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 { ...@@ -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: ...@@ -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: ...@@ -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;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论