Coverage Report

Created: 2026-04-06 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pdns/ext/yahttp/yahttp/cookie.hpp
Line
Count
Source
1
namespace YaHTTP {
2
  /*! Implements a single cookie */
3
  class Cookie {
4
  public:
5
7.15k
     Cookie() {
6
7.15k
       secure = false;
7
7.15k
       httponly = false;
8
7.15k
       name = value = "";
9
7.15k
       expires = DateTime();
10
7.15k
     }; //!< Set the cookie to empty value
11
12
1.24M
     Cookie(const Cookie &rhs) {
13
1.24M
       name = rhs.name;
14
1.24M
       value = rhs.value;
15
1.24M
       domain = rhs.domain;
16
1.24M
       path = rhs.path;
17
1.24M
       secure = rhs.secure;
18
1.24M
       httponly = rhs.httponly;
19
1.24M
       expires = rhs.expires;
20
1.24M
     }; //<! Copy cookie values
21
22
625k
     Cookie& operator=(const Cookie &rhs) {
23
625k
       name = rhs.name;
24
625k
       value = rhs.value;
25
625k
       domain = rhs.domain;
26
625k
       path = rhs.path;
27
625k
       secure = rhs.secure;
28
625k
       httponly = rhs.httponly;
29
625k
       expires = rhs.expires;
30
625k
       return *this;
31
625k
     }
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
3.68k
    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
11.0k
    void clear() {
72
11.0k
      this->cookies.clear();
73
11.0k
    }
74
75
1.24M
    void keyValuePair(const std::string &keyvalue, std::string &key, std::string &value) {
76
1.24M
      size_t pos;
77
1.24M
      pos = keyvalue.find("=");
78
1.24M
      if (pos == std::string::npos) throw ParseError("Not a Key-Value pair (cookie)");
79
1.24M
      key = std::string(keyvalue.begin(), keyvalue.begin()+pos);
80
1.24M
      value = std::string(keyvalue.begin()+pos+1, keyvalue.end());
81
1.24M
    } //<! key value pair parser
82
  
83
2.22k
    void parseCookieHeader(const std::string &cookiestr) {
84
2.22k
      size_t pos, npos;
85
2.22k
      std::list<Cookie> lcookies;
86
2.22k
      Cookie c;
87
2.22k
      pos = 0;
88
1.25M
      while(pos < cookiestr.size()) {
89
1.24M
        if ((npos = cookiestr.find("; ", pos)) == std::string::npos)
90
1.99k
          npos = cookiestr.size();
91
1.24M
        keyValuePair(cookiestr.substr(pos, npos-pos), c.name, c.value);
92
1.24M
        c.name = YaHTTP::Utility::decodeURL(c.name);
93
1.24M
        c.value = YaHTTP::Utility::decodeURL(c.value);
94
1.24M
        lcookies.push_back(c);
95
1.24M
        pos = npos+2;
96
1.24M
      }
97
627k
      for(std::list<Cookie>::iterator i = lcookies.begin(); i != lcookies.end(); i++) {
98
625k
        this->cookies[i->name] = *i;
99
625k
      }
100
2.22k
    }
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
};