Coverage Report

Created: 2025-09-05 06:36

/src/pdns/ext/yahttp/yahttp/cookie.hpp
Line
Count
Source (jump to first uncovered line)
1
namespace YaHTTP {
2
  /*! Implements a single cookie */
3
  class Cookie {
4
  public:
5
6.84k
     Cookie() {
6
6.84k
       secure = false;
7
6.84k
       httponly = false;
8
6.84k
       name = value = "";
9
6.84k
       expires = DateTime();
10
6.84k
     }; //!< Set the cookie to empty value
11
12
798k
     Cookie(const Cookie &rhs) {
13
798k
       name = rhs.name;
14
798k
       value = rhs.value;
15
798k
       domain = rhs.domain;
16
798k
       path = rhs.path;
17
798k
       secure = rhs.secure;
18
798k
       httponly = rhs.httponly;
19
798k
       expires = rhs.expires;
20
798k
     }; //<! Copy cookie values
21
22
263k
     Cookie& operator=(const Cookie &rhs) {
23
263k
       name = rhs.name;
24
263k
       value = rhs.value;
25
263k
       domain = rhs.domain;
26
263k
       path = rhs.path;
27
263k
       secure = rhs.secure;
28
263k
       httponly = rhs.httponly;
29
263k
       expires = rhs.expires;
30
263k
       return *this;
31
263k
     }
32
33
     DateTime expires; /*!< Expiration date */
34
     std::string domain; /*!< Domain where cookie is valid */
35
     std::string path; /*!< Path where the cookie is valid */
36
     bool httponly; /*!< Whether the cookie is for server use only */
37
     bool secure; /*!< Whether the cookie is for HTTPS only */
38
 
39
     std::string name; /*!< Cookie name */
40
     std::string value; /*!< Cookie value */
41
42
0
     std::string str() const {
43
0
       std::ostringstream oss;
44
0
       oss << YaHTTP::Utility::encodeURL(name) << "=" << YaHTTP::Utility::encodeURL(value);
45
46
0
       if (expires.isSet) 
47
0
         oss << "; expires=" << expires.cookie_str();
48
0
       if (domain.size()>0)
49
0
         oss << "; domain=" << domain;
50
0
       if (path.size()>0)
51
0
         oss << "; path=" << path;
52
0
       if (secure)
53
0
         oss << "; secure";
54
0
       if (httponly)
55
0
         oss << "; httpOnly";
56
0
       return oss.str();
57
0
     }; //!< Stringify the cookie
58
  };
59
60
  /*! Implements a Cookie jar for storing multiple cookies */
61
  class CookieJar {
62
    public:
63
    std::map<std::string, Cookie, ASCIICINullSafeComparator> cookies;  //<! cookie container
64
  
65
4.15k
    CookieJar() {}; //<! constructs empty cookie jar
66
0
    CookieJar(const CookieJar & rhs) {
67
0
      this->cookies = rhs.cookies;
68
0
    } //<! copy cookies from another cookie jar
69
0
    CookieJar& operator=(const CookieJar & rhs) = default;
70
  
71
12.4k
    void clear() {
72
12.4k
      this->cookies.clear();
73
12.4k
    }
74
75
798k
    void keyValuePair(const std::string &keyvalue, std::string &key, std::string &value) {
76
798k
      size_t pos;
77
798k
      pos = keyvalue.find("=");
78
798k
      if (pos == std::string::npos) throw ParseError("Not a Key-Value pair (cookie)");
79
798k
      key = std::string(keyvalue.begin(), keyvalue.begin()+pos);
80
798k
      value = std::string(keyvalue.begin()+pos+1, keyvalue.end());
81
798k
    } //<! key value pair parser
82
  
83
2.08k
    void parseCookieHeader(const std::string &cookiestr) {
84
2.08k
      size_t pos, npos;
85
2.08k
      std::list<Cookie> lcookies;
86
2.08k
      Cookie c;
87
2.08k
      pos = 0;
88
800k
      while(pos < cookiestr.size()) {
89
798k
        if ((npos = cookiestr.find("; ", pos)) == std::string::npos)
90
1.85k
          npos = cookiestr.size();
91
798k
        keyValuePair(cookiestr.substr(pos, npos-pos), c.name, c.value);
92
798k
        c.name = YaHTTP::Utility::decodeURL(c.name);
93
798k
        c.value = YaHTTP::Utility::decodeURL(c.value);
94
798k
        lcookies.push_back(c);
95
798k
        pos = npos+2;
96
798k
      }
97
265k
      for(std::list<Cookie>::iterator i = lcookies.begin(); i != lcookies.end(); i++) {
98
263k
        this->cookies[i->name] = *i;
99
263k
      }
100
2.08k
    }
101
102
0
    void parseSetCookieHeader(const std::string &cookiestr) {
103
0
      Cookie c;
104
0
      size_t pos,npos;
105
0
      std::string k, v;
106
107
0
      if ((pos = cookiestr.find("; ", 0)) == std::string::npos)
108
0
        pos = cookiestr.size();
109
0
      keyValuePair(cookiestr.substr(0, pos), c.name, c.value);
110
0
      c.name = YaHTTP::Utility::decodeURL(c.name);
111
0
      c.value = YaHTTP::Utility::decodeURL(c.value);
112
0
      if (pos < cookiestr.size()) pos+=2;
113
114
0
      while(pos < cookiestr.size()) {
115
0
        if ((npos = cookiestr.find("; ", pos)) == std::string::npos)
116
0
          npos = cookiestr.size();
117
0
        std::string s = cookiestr.substr(pos, npos-pos);
118
0
        if (s.find("=") != std::string::npos)
119
0
          keyValuePair(s, k, v);
120
0
        else
121
0
          k = std::move(s);
122
0
        if (k == "expires") {
123
0
          DateTime dt;
124
0
          dt.parseCookie(v);
125
0
          c.expires = dt;
126
0
        } else if (k == "domain") {
127
0
          c.domain = v;
128
0
        } else if (k == "path") {
129
0
          c.path = v;
130
0
        } else if (k == "httpOnly") {
131
0
          c.httponly = true;
132
0
        } else if (k == "secure") {
133
0
          c.secure = true;
134
0
        } else {
135
          // ignore crap
136
0
          break;
137
0
        }
138
0
        pos = npos+2;
139
0
      }
140
  
141
0
      this->cookies[c.name] = c;
142
0
    }; //<! Parse multiple cookies from header 
143
  };
144
};