_ZN6YaHTTP6CookieC2Ev:
    5|  6.53k|     Cookie() {
    6|  6.53k|       secure = false;
    7|  6.53k|       httponly = false;
    8|  6.53k|       name = value = "";
    9|  6.53k|       expires = DateTime();
   10|  6.53k|     }; //!< Set the cookie to empty value
_ZN6YaHTTP9CookieJar12keyValuePairERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERS7_SA_:
   75|   279k|    void keyValuePair(const std::string &keyvalue, std::string &key, std::string &value) {
   76|   279k|      size_t pos;
   77|   279k|      pos = keyvalue.find("=");
   78|   279k|      if (pos == std::string::npos) throw ParseError("Not a Key-Value pair (cookie)");
  ------------------
  |  Branch (78:11): [True: 40, False: 279k]
  ------------------
   79|   279k|      key = std::string(keyvalue.begin(), keyvalue.begin()+pos);
   80|   279k|      value = std::string(keyvalue.begin()+pos+1, keyvalue.end());
   81|   279k|    } //<! key value pair parser
_ZN6YaHTTP9CookieJar17parseCookieHeaderERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   83|  2.04k|    void parseCookieHeader(const std::string &cookiestr) {
   84|  2.04k|      size_t pos, npos;
   85|  2.04k|      std::list<Cookie> lcookies;
   86|  2.04k|      Cookie c;
   87|  2.04k|      pos = 0;
   88|   281k|      while(pos < cookiestr.size()) {
  ------------------
  |  Branch (88:13): [True: 279k, False: 2.04k]
  ------------------
   89|   279k|        if ((npos = cookiestr.find("; ", pos)) == std::string::npos)
  ------------------
  |  Branch (89:13): [True: 1.84k, False: 277k]
  ------------------
   90|  1.84k|          npos = cookiestr.size();
   91|   279k|        keyValuePair(cookiestr.substr(pos, npos-pos), c.name, c.value);
   92|   279k|        c.name = YaHTTP::Utility::decodeURL(c.name);
   93|   279k|        c.value = YaHTTP::Utility::decodeURL(c.value);
   94|   279k|        lcookies.push_back(c);
   95|   279k|        pos = npos+2;
   96|   279k|      }
   97|   281k|      for(std::list<Cookie>::iterator i = lcookies.begin(); i != lcookies.end(); i++) {
  ------------------
  |  Branch (97:61): [True: 279k, False: 2.04k]
  ------------------
   98|   279k|        this->cookies[i->name] = *i;
   99|   279k|      }
  100|  2.04k|    }

_ZN6YaHTTP5ErrorC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
    9|    367|    Error(const std::string& reason_): reason(reason_) {};
_ZN6YaHTTP5ErrorD2Ev:
   10|    367|    virtual ~Error() throw() {};
_ZN6YaHTTP10ParseErrorC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   22|    367|    ParseError(const std::string& reason_): Error(reason_) {};

_ZN6YaHTTP7isspaceEc:
   10|  10.3M|  bool isspace(char c) {
   11|  10.3M|    return std::isspace(c) != 0;
   12|  10.3M|  }
_ZN6YaHTTP7isspaceEcRKNSt3__16localeE:
   14|  18.2k|  bool isspace(char c, const std::locale& loc) {
   15|  18.2k|    return std::isspace(c, loc);
   16|  18.2k|  }
_ZN6YaHTTP11AsyncLoaderINS_7RequestEE4feedERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
   43|  3.33k|  bool AsyncLoader<T>::feed(const std::string& somedata) {
   44|  3.33k|    buffer.append(somedata);
   45|  23.6k|    while(state < 2) {
  ------------------
  |  Branch (45:11): [True: 23.6k, False: 42]
  ------------------
   46|  23.6k|      int cr=0;
   47|  23.6k|      pos = buffer.find_first_of("\n");
   48|       |      // need to find CRLF in buffer
   49|  23.6k|      if (pos == std::string::npos) return false;
  ------------------
  |  Branch (49:11): [True: 2.05k, False: 21.5k]
  ------------------
   50|  21.5k|      if (pos>0 && buffer[pos-1]=='\r')
  ------------------
  |  Branch (50:11): [True: 18.4k, False: 3.09k]
  |  Branch (50:20): [True: 274, False: 18.2k]
  ------------------
   51|    274|        cr=1;
   52|  21.5k|      std::string line(buffer.begin(), buffer.begin()+pos-cr); // exclude CRLF
   53|  21.5k|      buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer including CRLF
   54|       |
   55|  21.5k|      if (state == 0) { // startup line
  ------------------
  |  Branch (55:11): [True: 3.31k, False: 18.2k]
  ------------------
   56|  3.31k|        if (target->kind == YAHTTP_TYPE_REQUEST) {
  ------------------
  |  |   31|  3.31k|#define YAHTTP_TYPE_REQUEST 1
  ------------------
  |  Branch (56:13): [True: 3.31k, False: 0]
  ------------------
   57|  3.31k|          std::string ver;
   58|  3.31k|          std::string tmpurl;
   59|  3.31k|          std::istringstream iss(line);
   60|  3.31k|          iss >> target->method >> tmpurl >> ver;
   61|  3.31k|          if (ver.size() == 0)
  ------------------
  |  Branch (61:15): [True: 3.12k, False: 189]
  ------------------
   62|  3.12k|            target->version = 9;
   63|    189|          else if (ver.find("HTTP/0.9") == 0)
  ------------------
  |  Branch (63:20): [True: 1, False: 188]
  ------------------
   64|      1|            target->version = 9;
   65|    188|          else if (ver.find("HTTP/1.0") == 0)
  ------------------
  |  Branch (65:20): [True: 3, False: 185]
  ------------------
   66|      3|            target->version = 10;
   67|    185|          else if (ver.find("HTTP/1.1") == 0)
  ------------------
  |  Branch (67:20): [True: 5, False: 180]
  ------------------
   68|      5|            target->version = 11;
   69|    180|          else
   70|    180|            throw ParseError("HTTP version not supported");
   71|       |          // uppercase the target method
   72|  3.13k|          std::transform(target->method.begin(), target->method.end(), target->method.begin(), ::toupper);
   73|  3.13k|          target->url.parse(tmpurl);
   74|  3.13k|          target->getvars = Utility::parseUrlParameters(target->url.parameters);
   75|  3.13k|          state = 1;
   76|  3.13k|        } else if(target->kind == YAHTTP_TYPE_RESPONSE) {
  ------------------
  |  |   32|      0|#define YAHTTP_TYPE_RESPONSE 2
  ------------------
  |  Branch (76:19): [True: 0, False: 0]
  ------------------
   77|      0|          std::string ver;
   78|      0|          std::istringstream iss(line);
   79|      0|          std::string::size_type pos1;
   80|      0|          iss >> ver >> target->status;
   81|      0|          std::getline(iss, target->statusText);
   82|      0|          pos1=0;
   83|      0|          while(pos1 < target->statusText.size() && YaHTTP::isspace(target->statusText.at(pos1))) pos1++;
  ------------------
  |  Branch (83:17): [True: 0, False: 0]
  |  Branch (83:53): [True: 0, False: 0]
  ------------------
   84|      0|          target->statusText = target->statusText.substr(pos1); 
   85|      0|          if ((pos1 = target->statusText.find("\r")) != std::string::npos) {
  ------------------
  |  Branch (85:15): [True: 0, False: 0]
  ------------------
   86|      0|            target->statusText = target->statusText.substr(0, pos1-1);
   87|      0|          }
   88|      0|          if (ver.size() == 0) {
  ------------------
  |  Branch (88:15): [True: 0, False: 0]
  ------------------
   89|      0|            target->version = 9;
   90|      0|          } else if (ver.find("HTTP/0.9") == 0)
  ------------------
  |  Branch (90:22): [True: 0, False: 0]
  ------------------
   91|      0|            target->version = 9;
   92|      0|          else if (ver.find("HTTP/1.0") == 0)
  ------------------
  |  Branch (92:20): [True: 0, False: 0]
  ------------------
   93|      0|            target->version = 10;
   94|      0|          else if (ver.find("HTTP/1.1") == 0)
  ------------------
  |  Branch (94:20): [True: 0, False: 0]
  ------------------
   95|      0|            target->version = 11;
   96|      0|          else
   97|      0|            throw ParseError("HTTP version not supported");
   98|      0|          state = 1;
   99|      0|        }
  100|  18.2k|      } else if (state == 1) {
  ------------------
  |  Branch (100:18): [True: 18.2k, False: 0]
  ------------------
  101|  18.2k|        std::string key,value;
  102|  18.2k|        size_t pos1;
  103|  18.2k|        if (line.empty()) {
  ------------------
  |  Branch (103:13): [True: 1.02k, False: 17.2k]
  ------------------
  104|  1.02k|          chunked = (target->headers.find("transfer-encoding") != target->headers.end() && target->headers["transfer-encoding"] == "chunked");
  ------------------
  |  Branch (104:22): [True: 364, False: 663]
  |  Branch (104:92): [True: 326, False: 38]
  ------------------
  105|  1.02k|          state = 2;
  106|  1.02k|          break;
  107|  1.02k|        }
  108|       |        // split headers
  109|  17.2k|        if ((pos1 = line.find(":")) == std::string::npos) {
  ------------------
  |  Branch (109:13): [True: 13, False: 17.2k]
  ------------------
  110|     13|          throw ParseError("Malformed header line");
  111|     13|        }
  112|  17.2k|        key = line.substr(0, pos1);
  113|  17.2k|        value = line.substr(pos1 + 1);
  114|  10.3M|        for(std::string::iterator it=key.begin(); it != key.end(); it++)
  ------------------
  |  Branch (114:51): [True: 10.3M, False: 17.2k]
  ------------------
  115|  10.3M|          if (YaHTTP::isspace(*it))
  ------------------
  |  Branch (115:15): [True: 12, False: 10.3M]
  ------------------
  116|     12|            throw ParseError("Header key contains whitespace which is not allowed by RFC");
  117|       |
  118|  17.2k|        Utility::trim(value);
  119|  17.2k|        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
  120|       |        // is it already defined
  121|       |
  122|  17.2k|        if (key == "set-cookie" && target->kind == YAHTTP_TYPE_RESPONSE) {
  ------------------
  |  |   32|    205|#define YAHTTP_TYPE_RESPONSE 2
  ------------------
  |  Branch (122:13): [True: 205, False: 17.0k]
  |  Branch (122:36): [True: 0, False: 205]
  ------------------
  123|      0|          target->jar.parseSetCookieHeader(value);
  124|  17.2k|        } else if (key == "cookie" && target->kind == YAHTTP_TYPE_REQUEST) {
  ------------------
  |  |   31|  2.04k|#define YAHTTP_TYPE_REQUEST 1
  ------------------
  |  Branch (124:20): [True: 2.04k, False: 15.1k]
  |  Branch (124:39): [True: 2.04k, False: 0]
  ------------------
  125|  2.04k|          target->jar.parseCookieHeader(value);
  126|  15.1k|        } else {
  127|  15.1k|          if (key == "host" && target->kind == YAHTTP_TYPE_REQUEST) {
  ------------------
  |  |   31|  1.19k|#define YAHTTP_TYPE_REQUEST 1
  ------------------
  |  Branch (127:15): [True: 1.19k, False: 13.9k]
  |  Branch (127:32): [True: 1.19k, False: 0]
  ------------------
  128|       |            // maybe it contains port?
  129|  1.19k|            if ((pos1 = value.find(":")) == std::string::npos) {
  ------------------
  |  Branch (129:17): [True: 528, False: 671]
  ------------------
  130|    528|              target->url.host = value;
  131|    671|            } else {
  132|    671|              target->url.host = value.substr(0, pos1);
  133|    671|              target->url.port = ::atoi(value.substr(pos1).c_str());
  134|    671|            }
  135|  1.19k|          }
  136|  15.1k|          if (target->headers.find(key) != target->headers.end()) {
  ------------------
  |  Branch (136:15): [True: 6.94k, False: 8.21k]
  ------------------
  137|  6.94k|            target->headers[key] = target->headers[key] + ";" + value;
  138|  8.21k|          } else {
  139|  8.21k|            target->headers[key] = std::move(value);
  140|  8.21k|          }
  141|  15.1k|        }
  142|  17.2k|      }
  143|  21.5k|    }
  144|       |
  145|  1.06k|    minbody = 0;
  146|       |    // check for expected body size
  147|  1.06k|    if (target->kind == YAHTTP_TYPE_REQUEST) maxbody = target->max_request_size;
  ------------------
  |  |   31|  1.06k|#define YAHTTP_TYPE_REQUEST 1
  ------------------
  |  Branch (147:9): [True: 1.02k, False: 42]
  ------------------
  148|     42|    else if (target->kind == YAHTTP_TYPE_RESPONSE) maxbody = target->max_response_size;
  ------------------
  |  |   32|     42|#define YAHTTP_TYPE_RESPONSE 2
  ------------------
  |  Branch (148:14): [True: 0, False: 42]
  ------------------
  149|     42|    else maxbody = 0;
  150|       |
  151|  1.06k|    if (!chunked) {
  ------------------
  |  Branch (151:9): [True: 701, False: 368]
  ------------------
  152|    701|      if (target->headers.find("content-length") != target->headers.end()) {
  ------------------
  |  Branch (152:11): [True: 483, False: 218]
  ------------------
  153|    483|        std::istringstream maxbodyS(target->headers["content-length"]);
  154|    483|        maxbodyS >> minbody;
  155|    483|        maxbody = minbody;
  156|    483|      }
  157|    701|      if (minbody < 1) return true; // guess there isn't anything left.
  ------------------
  |  Branch (157:11): [True: 238, False: 463]
  ------------------
  158|    463|      if (target->kind == YAHTTP_TYPE_REQUEST && static_cast<ssize_t>(minbody) > target->max_request_size) throw ParseError("Max request body size exceeded");
  ------------------
  |  |   31|    926|#define YAHTTP_TYPE_REQUEST 1
  ------------------
  |  Branch (158:11): [True: 463, False: 0]
  |  Branch (158:50): [True: 69, False: 394]
  ------------------
  159|    394|      else if (target->kind == YAHTTP_TYPE_RESPONSE && static_cast<ssize_t>(minbody) > target->max_response_size) throw ParseError("Max response body size exceeded");
  ------------------
  |  |   32|    788|#define YAHTTP_TYPE_RESPONSE 2
  ------------------
  |  Branch (159:16): [True: 0, False: 394]
  |  Branch (159:56): [True: 0, False: 0]
  ------------------
  160|    463|    }
  161|       |
  162|    762|    if (maxbody == 0) hasBody = false;
  ------------------
  |  Branch (162:9): [True: 0, False: 762]
  ------------------
  163|    762|    else hasBody = true;
  164|       |
  165|    762|    if (buffer.size() == 0) return ready();
  ------------------
  |  Branch (165:9): [True: 106, False: 656]
  ------------------
  166|       |
  167|  4.55k|    while(buffer.size() > 0) {
  ------------------
  |  Branch (167:11): [True: 4.11k, False: 445]
  ------------------
  168|  4.11k|      if (chunked) {
  ------------------
  |  Branch (168:11): [True: 3.82k, False: 289]
  ------------------
  169|  3.82k|        if (chunk_size == 0) {
  ------------------
  |  Branch (169:13): [True: 1.99k, False: 1.82k]
  ------------------
  170|  1.99k|          char buf[100];
  171|       |          // read chunk length
  172|  1.99k|          if ((pos = buffer.find('\n')) == std::string::npos) return false;
  ------------------
  |  Branch (172:15): [True: 4, False: 1.99k]
  ------------------
  173|  1.99k|          if (pos > 99)
  ------------------
  |  Branch (173:15): [True: 36, False: 1.95k]
  ------------------
  174|     36|            throw ParseError("Impossible chunk_size");
  175|  1.95k|          buffer.copy(buf, pos);
  176|  1.95k|          buf[pos]=0; // just in case...
  177|  1.95k|          buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer
  178|  1.95k|          if (sscanf(buf, "%x", &chunk_size) != 1) {
  ------------------
  |  Branch (178:15): [True: 14, False: 1.94k]
  ------------------
  179|     14|            throw ParseError("Unable to parse chunk size");
  180|     14|          }
  181|  1.94k|          if (chunk_size == 0) { state = 3; break; } // last chunk
  ------------------
  |  Branch (181:15): [True: 6, False: 1.93k]
  ------------------
  182|  1.93k|          if (chunk_size > (std::numeric_limits<decltype(chunk_size)>::max() - 2)) {
  ------------------
  |  Branch (182:15): [True: 3, False: 1.93k]
  ------------------
  183|      3|            throw ParseError("Chunk is too large");
  184|      3|          }
  185|  1.93k|        } else {
  186|  1.82k|          int crlf=1;
  187|  1.82k|          if (buffer.size() < static_cast<size_t>(chunk_size+1)) return false; // expect newline
  ------------------
  |  Branch (187:15): [True: 87, False: 1.73k]
  ------------------
  188|  1.73k|          if (buffer.at(chunk_size) == '\r') {
  ------------------
  |  Branch (188:15): [True: 311, False: 1.42k]
  ------------------
  189|    311|            if (buffer.size() < static_cast<size_t>(chunk_size+2) || buffer.at(chunk_size+1) != '\n') return false; // expect newline after carriage return
  ------------------
  |  Branch (189:17): [True: 7, False: 304]
  |  Branch (189:70): [True: 12, False: 292]
  ------------------
  190|    292|            crlf=2;
  191|  1.42k|          } else if (buffer.at(chunk_size) != '\n') return false;
  ------------------
  |  Branch (191:22): [True: 14, False: 1.41k]
  ------------------
  192|  1.70k|          std::string tmp = buffer.substr(0, chunk_size);
  193|  1.70k|          buffer.erase(buffer.begin(), buffer.begin()+chunk_size+crlf);
  194|  1.70k|          bodybuf << tmp;
  195|  1.70k|          chunk_size = 0;
  196|  1.70k|          if (buffer.size() == 0) break; // just in case
  ------------------
  |  Branch (196:15): [True: 28, False: 1.67k]
  ------------------
  197|  1.70k|        }
  198|  3.82k|      } else {
  199|    289|        if (bodybuf.str().length() + buffer.length() > maxbody)
  ------------------
  |  Branch (199:13): [True: 59, False: 230]
  ------------------
  200|     59|          bodybuf << buffer.substr(0, maxbody - bodybuf.str().length());
  201|    230|        else
  202|    230|          bodybuf << buffer;
  203|    289|        buffer = "";
  204|    289|      }
  205|  4.11k|    }
  206|       |
  207|    479|    if (chunk_size!=0) return false; // need more data
  ------------------
  |  Branch (207:9): [True: 112, False: 367]
  ------------------
  208|       |
  209|    367|    return ready();
  210|    479|  };

_ZN6YaHTTP7Utility8trimLeftERNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  425|  17.2k|    static void trimLeft(std::string &str) {
  426|  17.2k|       const std::locale &loc = std::locale::classic();
  427|  17.2k|       std::string::iterator iter = str.begin();
  428|  25.0k|       while(iter != str.end() && YaHTTP::isspace(*iter, loc)) iter++;
  ------------------
  |  Branch (428:14): [True: 12.3k, False: 12.6k]
  |  Branch (428:14): [True: 7.81k, False: 17.2k]
  |  Branch (428:35): [True: 7.81k, False: 4.53k]
  ------------------
  429|  17.2k|       str.erase(str.begin(), iter);
  430|  17.2k|    }; //<! removes whitespace from left
_ZN6YaHTTP7Utility9trimRightERNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  432|  17.2k|    static void trimRight(std::string &str) {
  433|  17.2k|       const std::locale &loc = std::locale::classic();
  434|  17.2k|       std::string::reverse_iterator iter = str.rbegin();
  435|  18.6k|       while(iter != str.rend() && YaHTTP::isspace(*iter, loc)) iter++;
  ------------------
  |  Branch (435:14): [True: 5.94k, False: 12.6k]
  |  Branch (435:14): [True: 1.40k, False: 17.2k]
  |  Branch (435:36): [True: 1.40k, False: 4.53k]
  ------------------
  436|  17.2k|       str.erase(iter.base(), str.end());
  437|  17.2k|    }; //<! removes whitespace from right
_ZN6YaHTTP7Utility4trimERNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  439|  17.2k|    static void trim(std::string &str) {
  440|  17.2k|       trimLeft(str);
  441|  17.2k|       trimRight(str);
  442|  17.2k|    }; //<! removes whitespace from left and right

_ZN6YaHTTP9CookieJarC2Ev:
   65|  3.33k|    CookieJar() {}; //<! constructs empty cookie jar
_ZN6YaHTTP9CookieJar5clearEv:
   71|  9.99k|    void clear() {
   72|  9.99k|      this->cookies.clear();
   73|  9.99k|    }
_ZN6YaHTTP6CookieaSERKS0_:
   22|   279k|     Cookie& operator=(const Cookie &rhs) {
   23|   279k|       name = rhs.name;
   24|   279k|       value = rhs.value;
   25|   279k|       domain = rhs.domain;
   26|   279k|       path = rhs.path;
   27|   279k|       secure = rhs.secure;
   28|   279k|       httponly = rhs.httponly;
   29|   279k|       expires = rhs.expires;
   30|   279k|       return *this;
   31|   279k|     }
_ZN6YaHTTP6CookieC2ERKS0_:
   12|   279k|     Cookie(const Cookie &rhs) {
   13|   279k|       name = rhs.name;
   14|   279k|       value = rhs.value;
   15|   279k|       domain = rhs.domain;
   16|   279k|       path = rhs.path;
   17|   279k|       secure = rhs.secure;
   18|   279k|       httponly = rhs.httponly;
   19|   279k|       expires = rhs.expires;
   20|   279k|     }; //<! Copy cookie values

_ZN6YaHTTP7RequestC2Ev:
  228|  3.33k|    Request() { Request::initialize(); };
_ZN6YaHTTP8HTTPBaseC2Ev:
   98|  3.33k|    HTTPBase() {
   99|  3.33k|      HTTPBase::initialize();
  100|  3.33k|    };
_ZN6YaHTTP8HTTPBase10initializeEv:
  102|  9.99k|    virtual void initialize() {
  103|  9.99k|      kind = 0;
  104|  9.99k|      status = 0;
  105|  9.99k|#ifdef HAVE_CPP_FUNC_PTR
  106|  9.99k|      renderer = SendBodyRender();
  107|  9.99k|#endif
  108|  9.99k|      max_request_size = YAHTTP_MAX_REQUEST_SIZE;
  ------------------
  |  |   24|  9.99k|#define YAHTTP_MAX_REQUEST_SIZE 2097152
  ------------------
  109|  9.99k|      max_response_size = YAHTTP_MAX_RESPONSE_SIZE;
  ------------------
  |  |   28|  9.99k|#define YAHTTP_MAX_RESPONSE_SIZE 2097152
  ------------------
  110|  9.99k|      url = "";
  111|  9.99k|      method = "";
  112|  9.99k|      statusText = "";
  113|  9.99k|      jar.clear();
  114|  9.99k|      headers.clear();
  115|  9.99k|      parameters.clear();
  116|  9.99k|      getvars.clear();
  117|  9.99k|      postvars.clear();
  118|  9.99k|      body = "";
  119|  9.99k|      routeName = "";
  120|  9.99k|      version = 11; // default to version 1.1
  121|  9.99k|      is_multipart = false;
  122|  9.99k|    }
_ZN6YaHTTP8HTTPBase14SendBodyRenderC2Ev:
   48|  9.99k|      SendBodyRender() {};
_ZN6YaHTTP7Request10initializeEv:
  237|  6.66k|    void initialize() override {
  238|  6.66k|      HTTPBase::initialize();
  239|  6.66k|      this->kind = YAHTTP_TYPE_REQUEST;
  ------------------
  |  |   31|  6.66k|#define YAHTTP_TYPE_REQUEST 1
  ------------------
  240|  6.66k|    }
_ZN6YaHTTP11AsyncLoaderINS_7RequestEE10initializeEPS1_:
  311|  3.33k|    void initialize(T* target_) {
  312|  3.33k|      chunked = false; chunk_size = 0;
  313|  3.33k|      bodybuf.str(""); minbody = 0; maxbody = 0;
  314|  3.33k|      pos = 0; state = 0; this->target = target_;
  315|  3.33k|      hasBody = false;
  316|  3.33k|      buffer = "";
  317|  3.33k|      this->target->initialize();
  318|  3.33k|    }; //<! Initialize the parser for target and clear state
_ZN6YaHTTP11AsyncLoaderINS_7RequestEE8finalizeEv:
  329|    358|    void finalize() {
  330|    358|      bodybuf.flush();
  331|    358|      if (ready()) {
  ------------------
  |  Branch (331:11): [True: 358, False: 0]
  ------------------
  332|    358|        strstr_map_t::iterator cpos = target->headers.find("content-type");
  333|    358|        if (cpos != target->headers.end() && Utility::iequals(cpos->second, "application/x-www-form-urlencoded", 32)) {
  ------------------
  |  Branch (333:13): [True: 130, False: 228]
  |  Branch (333:13): [True: 93, False: 265]
  |  Branch (333:46): [True: 93, False: 37]
  ------------------
  334|     93|          target->postvars = Utility::parseUrlParameters(bodybuf.str());
  335|     93|        }
  336|    358|        target->body = bodybuf.str();
  337|    358|      }
  338|    358|      bodybuf.str("");
  339|    358|      this->target = NULL;
  340|    358|    }; //<! finalize and release target
_ZN6YaHTTP11AsyncLoaderINS_7RequestEE5readyEv:
  320|    787|    bool ready() {
  321|    787|     return (chunked == true && state == 3) || // if it's chunked we get end of data indication
  ------------------
  |  Branch (321:14): [True: 41, False: 746]
  |  Branch (321:33): [True: 12, False: 29]
  ------------------
  322|    787|             (chunked == false && state > 1 &&  
  ------------------
  |  Branch (322:15): [True: 746, False: 29]
  |  Branch (322:35): [True: 746, False: 0]
  ------------------
  323|    775|               (!hasBody || 
  ------------------
  |  Branch (323:17): [True: 238, False: 508]
  ------------------
  324|    746|                 (bodybuf.str().size() <= maxbody && 
  ------------------
  |  Branch (324:19): [True: 508, False: 0]
  ------------------
  325|    508|                  bodybuf.str().size() >= minbody)
  ------------------
  |  Branch (325:19): [True: 228, False: 280]
  ------------------
  326|    746|               )
  327|    775|             ); 
  328|    787|    }; //<! whether we have received enough data

_ZN6YaHTTP3URLC2Ev:
  166|  3.33k|      URL() { initialize(); }; //<! construct empty url
_ZN6YaHTTP3URL10initializeEv:
  116|  16.4k|      void initialize() {
  117|  16.4k|        protocol = ""; host = ""; port = 0; username = ""; password = ""; path = ""; parameters = ""; anchor =""; pathless = true;
  118|  16.4k|      }; //<! initialize to empty URL
_ZN6YaHTTP3URLC2EPKc:
  171|  9.99k|      URL(const char *url) {
  172|  9.99k|        parse(std::string(url));
  173|  9.99k|      }; //<! calls parse with url
_ZN6YaHTTP3URL5parseERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  175|  13.1k|      bool parse(const std::string& url) {
  176|       |        // setup
  177|  13.1k|        initialize();
  178|       |
  179|  13.1k|        if (url.size() > YAHTTP_MAX_URL_LENGTH) return false;
  ------------------
  |  |    8|  13.1k|#define YAHTTP_MAX_URL_LENGTH 2048
  ------------------
  |  Branch (179:13): [True: 11, False: 13.1k]
  ------------------
  180|  13.1k|        size_t pos = 0;
  181|  13.1k|        if (*(url.begin()) != '/') { // full url?
  ------------------
  |  Branch (181:13): [True: 13.0k, False: 111]
  ------------------
  182|  13.0k|          if (parseSchema(url, pos) == false) return false;
  ------------------
  |  Branch (182:15): [True: 12.2k, False: 782]
  ------------------
  183|    782|          if (pathless) {
  ------------------
  |  Branch (183:15): [True: 536, False: 246]
  ------------------
  184|    536|            parameters = url.substr(pos);
  185|    536|            return true;
  186|    536|          }
  187|    246|          if (parseUserPass(url, pos) == false) return false;
  ------------------
  |  Branch (187:15): [True: 0, False: 246]
  ------------------
  188|    246|          if (parseHost(url, pos) == false) return false;
  ------------------
  |  Branch (188:15): [True: 28, False: 218]
  ------------------
  189|    246|        }
  190|    329|        if (parsePath(url, pos) == false) return false;
  ------------------
  |  Branch (190:13): [True: 0, False: 329]
  ------------------
  191|    329|        if (parseParameters(url, pos) == false) return false;
  ------------------
  |  Branch (191:13): [True: 0, False: 329]
  ------------------
  192|    329|        return parseAnchor(url, pos);
  193|    329|    }; //<! parse various formats of urls ranging from http://example.com/foo?bar=baz into data:base64:d089swt64wt... 
_ZN6YaHTTP3URL11parseSchemaERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   15|  13.0k|      bool parseSchema(const std::string& url, size_t &pos) {
   16|  13.0k|          size_t pos1;
   17|  13.0k|          if (pos >= url.size()) return false; // no data
  ------------------
  |  Branch (17:15): [True: 12.1k, False: 815]
  ------------------
   18|    815|          if ( (pos1 = url.find_first_of(":",pos)) == std::string::npos ) return false; // schema is mandatory
  ------------------
  |  Branch (18:16): [True: 33, False: 782]
  ------------------
   19|    782|          protocol = url.substr(pos, pos1-pos);
   20|    782|          if (protocol == "http") port = 80;
  ------------------
  |  Branch (20:15): [True: 1, False: 781]
  ------------------
   21|    782|          if (protocol == "https") port = 443;
  ------------------
  |  Branch (21:15): [True: 1, False: 781]
  ------------------
   22|    782|          pos = pos1+1; // after :
   23|    782|          if (url.compare(pos, 2, "//") == 0) {
  ------------------
  |  Branch (23:15): [True: 246, False: 536]
  ------------------
   24|    246|             pathless = false; // if this is true we put rest into parameters
   25|    246|             pos += 2;
   26|    246|          }
   27|    782|          return true;
   28|    815|      }; //<! parse schema/protocol part 
_ZN6YaHTTP3URL13parseUserPassERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   60|    246|      bool parseUserPass(const std::string& url, size_t &pos) {
   61|    246|          size_t pos1,pos2;
   62|    246|          if (pos >= url.size()) return true; // no data
  ------------------
  |  Branch (62:15): [True: 1, False: 245]
  ------------------
   63|       |
   64|    245|          if ( (pos1 = url.find_first_of("@",pos)) == std::string::npos ) return true; // no userinfo
  ------------------
  |  Branch (64:16): [True: 183, False: 62]
  ------------------
   65|     62|          pos2 = url.find_first_of(":",pos);
   66|       |
   67|     62|          if (pos2 != std::string::npos) { // comes with password
  ------------------
  |  Branch (67:15): [True: 24, False: 38]
  ------------------
   68|     24|             username = url.substr(pos, pos2 - pos);
   69|     24|             password = url.substr(pos2+1, pos1 - pos2 - 1);
   70|     24|             password = Utility::decodeURL(password);
   71|     38|          } else {
   72|     38|             username = url.substr(pos, pos1 - pos);
   73|     38|          }
   74|     62|          pos = pos1+1;
   75|     62|          username = Utility::decodeURL(username);
   76|     62|          return true;
   77|    245|      }; //<! parse possible username and password
_ZN6YaHTTP3URL9parseHostERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   30|    246|      bool parseHost(const std::string& url, size_t &pos) {
   31|    246|          size_t pos1;
   32|    246|          if (pos >= url.size()) return true; // no data
  ------------------
  |  Branch (32:15): [True: 17, False: 229]
  ------------------
   33|    229|          if ( (pos1 = url.find_first_of("/", pos)) == std::string::npos ) {
  ------------------
  |  Branch (33:16): [True: 189, False: 40]
  ------------------
   34|    189|             host = url.substr(pos);
   35|    189|             path = "/";
   36|    189|             pos = url.size();
   37|    189|          } else {
   38|     40|             host = url.substr(pos, pos1-pos);
   39|     40|             pos = pos1;
   40|     40|          }
   41|    229|          if (host.at(0) == '[') { // IPv6
  ------------------
  |  Branch (41:15): [True: 88, False: 141]
  ------------------
   42|     88|            if ((pos1 = host.find_first_of("]")) == std::string::npos) {
  ------------------
  |  Branch (42:17): [True: 28, False: 60]
  ------------------
   43|       |              // incomplete address
   44|     28|              return false;
   45|     28|            }
   46|     60|            size_t pos2;
   47|     60|            if ((pos2 = host.find_first_of(":", pos1)) != std::string::npos) {
  ------------------
  |  Branch (47:17): [True: 27, False: 33]
  ------------------
   48|     27|              std::istringstream tmp(host.substr(pos2 + 1));
   49|     27|              tmp >> port;
   50|     27|            }
   51|     60|            host = host.substr(1, pos1 - 1);
   52|    141|          } else if ( (pos1 = host.find_first_of(":")) != std::string::npos ) {
  ------------------
  |  Branch (52:23): [True: 43, False: 98]
  ------------------
   53|     43|             std::istringstream tmp(host.substr(pos1+1));
   54|     43|             tmp >> port;
   55|     43|             host = host.substr(0, pos1);
   56|     43|          }
   57|    201|          return true;
   58|    229|      }; //<! parse host and port
_ZN6YaHTTP3URL9parsePathERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   79|    327|      bool parsePath(const std::string& url, size_t &pos) {
   80|    327|          size_t pos1;
   81|    327|          if (pos >= url.size()) return true; // no data
  ------------------
  |  Branch (81:15): [True: 182, False: 145]
  ------------------
   82|    145|          if (url[pos] != '/') return false; // not an url
  ------------------
  |  Branch (82:15): [True: 0, False: 145]
  ------------------
   83|    145|          if ( (pos1 = url.find_first_of("?", pos)) == std::string::npos ) {
  ------------------
  |  Branch (83:16): [True: 38, False: 107]
  ------------------
   84|     38|             path = url.substr(pos);
   85|     38|             pos = url.size();
   86|    107|          } else {
   87|    107|             path = url.substr(pos, pos1-pos);
   88|    107|             pos = pos1;
   89|    107|          }
   90|    145|          return true;
   91|    145|      }; //<! parse path component
_ZN6YaHTTP3URL15parseParametersERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   93|    327|      bool parseParameters(const std::string& url, size_t &pos) {
   94|    327|          size_t pos1;
   95|    327|          if (pos >= url.size()) return true; // no data
  ------------------
  |  Branch (95:15): [True: 220, False: 107]
  ------------------
   96|    107|          if (url[pos] == '#') return true; // anchor starts here
  ------------------
  |  Branch (96:15): [True: 0, False: 107]
  ------------------
   97|    107|          if (url[pos] != '?') return false; // not a parameter
  ------------------
  |  Branch (97:15): [True: 0, False: 107]
  ------------------
   98|    107|          if ( (pos1 = url.find_first_of("#", pos)) == std::string::npos ) {
  ------------------
  |  Branch (98:16): [True: 88, False: 19]
  ------------------
   99|     88|             parameters = url.substr(pos+1);;
  100|     88|             pos = url.size();
  101|     88|          } else {
  102|     19|             parameters = url.substr(pos+1, pos1-pos-1);
  103|     19|             pos = pos1;
  104|     19|          }
  105|    107|          if (parameters.size()>0 && *(parameters.end()-1) == '&') parameters.resize(parameters.size()-1);
  ------------------
  |  Branch (105:15): [True: 92, False: 15]
  |  Branch (105:15): [True: 7, False: 100]
  |  Branch (105:38): [True: 7, False: 85]
  ------------------
  106|    107|          return true;
  107|    107|      }; //<! parse url parameters
_ZN6YaHTTP3URL11parseAnchorERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
  109|    327|      bool parseAnchor(const std::string& url, size_t &pos) {
  110|    327|          if (pos >= url.size()) return true; // no data
  ------------------
  |  Branch (110:15): [True: 308, False: 19]
  ------------------
  111|     19|          if (url[pos] != '#') return false; // not anchor
  ------------------
  |  Branch (111:15): [True: 0, False: 19]
  ------------------
  112|     19|          anchor = url.substr(pos+1);
  113|     19|          return true;
  114|     19|      }; //<! parse anchor

_ZN6YaHTTP7Utility9decodeURLERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  220|   660k|    static std::string decodeURL(const std::string& component) {
  221|   660k|        std::string result = component;
  222|   660k|        size_t pos1,pos2;
  223|   660k|        pos2 = 0;
  224|  8.88M|        while((pos1 = result.find_first_of("%", pos2))!=std::string::npos) {
  ------------------
  |  Branch (224:15): [True: 8.23M, False: 649k]
  ------------------
  225|  8.23M|           std::string code;
  226|  8.23M|           char a,b,c;
  227|  8.23M|           if (pos1 + 2 > result.length()) return result; // end of result
  ------------------
  |  Branch (227:16): [True: 10.7k, False: 8.22M]
  ------------------
  228|  8.22M|           code = result.substr(pos1+1, 2);
  229|  8.22M|           a = std::tolower(code[0]); b = std::tolower(code[1]);
  230|       |
  231|  8.22M|           if ((( '0' > a || a > '9') && ('a' > a || a > 'f')) ||
  ------------------
  |  Branch (231:19): [True: 5.97M, False: 2.25M]
  |  Branch (231:30): [True: 1.64M, False: 607k]
  |  Branch (231:43): [True: 6.16M, False: 1.45M]
  |  Branch (231:54): [True: 906k, False: 548k]
  ------------------
  232|  8.22M|              (( '0' > b || b > '9') && ('a' > b || b > 'f'))) {
  ------------------
  |  Branch (232:18): [True: 417k, False: 737k]
  |  Branch (232:29): [True: 545k, False: 192k]
  |  Branch (232:42): [True: 424k, False: 538k]
  |  Branch (232:53): [True: 504k, False: 33.3k]
  ------------------
  233|  8.00M|              pos2 = pos1+3;
  234|  8.00M|              continue;
  235|  8.00M|           }
  236|       |
  237|   225k|           if ('0' <= a && a <= '9') a = a - '0';
  ------------------
  |  Branch (237:16): [True: 225k, False: 0]
  |  Branch (237:28): [True: 21.2k, False: 204k]
  ------------------
  238|   204k|           else if ('a' <= a && a <= 'f') a = a - 'a' + 0x0a;
  ------------------
  |  Branch (238:21): [True: 204k, False: 0]
  |  Branch (238:33): [True: 204k, False: 0]
  ------------------
  239|   225k|           if ('0' <= b && b <= '9') b = b - '0';
  ------------------
  |  Branch (239:16): [True: 225k, False: 0]
  |  Branch (239:28): [True: 192k, False: 33.3k]
  ------------------
  240|  33.3k|           else if ('a' <= b && b <= 'f') b = b - 'a' + 0x0a;
  ------------------
  |  Branch (240:21): [True: 33.3k, False: 0]
  |  Branch (240:33): [True: 33.3k, False: 0]
  ------------------
  241|       |
  242|   225k|           c = (a<<4)+b;
  243|   225k|           result = result.replace(pos1,3,1,c);
  244|   225k|           pos2=pos1;
  245|   225k|        }
  246|   649k|        return result;
  247|   660k|    }; //<! Decodes %xx from string into bytes
_ZNK6YaHTTP25ASCIICINullSafeComparatorclERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
   17|  2.89M|    bool operator() (const std::string& lhs, const std::string& rhs) const {
   18|  2.89M|      int v;
   19|  2.89M|      std::string::const_iterator lhi = lhs.begin();
   20|  2.89M|      std::string::const_iterator rhi = rhs.begin();
   21|  10.1M|      for(;lhi != lhs.end() && rhi != rhs.end(); lhi++, rhi++)
  ------------------
  |  Branch (21:12): [True: 9.18M, False: 914k]
  |  Branch (21:12): [True: 9.15M, False: 945k]
  |  Branch (21:32): [True: 9.15M, False: 30.3k]
  ------------------
   22|  9.15M|        if ((v = ::tolower(*lhi) - ::tolower(*rhi)) != 0) return v<0; 
  ------------------
  |  Branch (22:13): [True: 1.95M, False: 7.20M]
  ------------------
   23|   945k|      if (lhi == lhs.end() && rhi != rhs.end()) return true;
  ------------------
  |  Branch (23:11): [True: 914k, False: 30.3k]
  |  Branch (23:11): [True: 263k, False: 682k]
  |  Branch (23:31): [True: 263k, False: 651k]
  ------------------
   24|   682k|      if (lhi != lhs.end() && rhi == rhs.end()) return false;
  ------------------
  |  Branch (24:11): [True: 30.3k, False: 651k]
  |  Branch (24:11): [True: 30.3k, False: 651k]
  |  Branch (24:31): [True: 30.3k, False: 0]
  ------------------
   25|   651k|      return false; // they are equal
   26|   682k|    }
_ZN6YaHTTP8DateTimeC2Ev:
   48|   292k|     DateTime() { 
   49|   292k|       initialize();
   50|   292k|     }; //<! Construct and initialize
_ZN6YaHTTP8DateTime10initializeEv:
   52|   292k|     void initialize() {
   53|   292k|       isSet = false; 
   54|   292k|       year = month = day = wday = hours = minutes = seconds = utc_offset = 0;
   55|   292k|       month = 1; // it's invalid otherwise
   56|   292k|     }; //<! Creates year 0 date
_ZN6YaHTTP7Utility7iequalsERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_m:
  406|    130|    static bool iequals(const std::string& a, const std::string& b, size_t length) {
  407|    130|      std::string::const_iterator ai, bi;
  408|    130|      size_t i;
  409|  3.64k|      for(ai = a.begin(), bi = b.begin(), i = 0; ai != a.end() && bi != b.end() && i < length; ai++,bi++,i++) {
  ------------------
  |  Branch (409:50): [True: 3.62k, False: 17]
  |  Branch (409:50): [True: 3.51k, False: 122]
  |  Branch (409:67): [True: 3.62k, False: 0]
  |  Branch (409:84): [True: 3.51k, False: 105]
  ------------------
  410|  3.51k|        if (::toupper(*ai) != ::toupper(*bi)) return false;
  ------------------
  |  Branch (410:13): [True: 8, False: 3.51k]
  ------------------
  411|  3.51k|      }
  412|       |
  413|    122|      if (ai == a.end() && bi == b.end()) return true;
  ------------------
  |  Branch (413:11): [True: 17, False: 105]
  |  Branch (413:11): [True: 0, False: 122]
  |  Branch (413:28): [True: 0, False: 17]
  ------------------
  414|    122|      if ((ai == a.end() && bi != b.end()) ||
  ------------------
  |  Branch (414:11): [True: 17, False: 105]
  |  Branch (414:12): [True: 17, False: 105]
  |  Branch (414:29): [True: 17, False: 0]
  ------------------
  415|    122|          (ai != a.end() && bi == b.end())) return false;
  ------------------
  |  Branch (415:12): [True: 105, False: 0]
  |  Branch (415:29): [True: 0, False: 105]
  ------------------
  416|       |      
  417|    105|      return ::toupper(*ai) == ::toupper(*bi);
  418|    122|    }; //<! case-insensitive comparison with length
_ZN6YaHTTP7Utility18parseUrlParametersENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  367|  3.22k|    static strstr_map_t parseUrlParameters(std::string parameters) {
  368|  3.22k|      std::string::size_type pos = 0;
  369|  3.22k|      strstr_map_t parameter_map;
  370|  53.5k|      while (pos != std::string::npos) {
  ------------------
  |  Branch (370:14): [True: 53.5k, False: 0]
  ------------------
  371|       |        // find next parameter start
  372|  53.5k|        std::string::size_type nextpos = parameters.find("&", pos);
  373|  53.5k|        std::string::size_type delim = parameters.find("=", pos);
  374|  53.5k|        if (delim > nextpos) {
  ------------------
  |  Branch (374:13): [True: 43.2k, False: 10.3k]
  ------------------
  375|  43.2k|          delim = nextpos;
  376|  43.2k|        }
  377|  53.5k|        std::string key;
  378|  53.5k|        std::string value;
  379|  53.5k|        if (delim == std::string::npos) {
  ------------------
  |  Branch (379:13): [True: 3.13k, False: 50.4k]
  ------------------
  380|  3.13k|          key = parameters.substr(pos);
  381|  50.4k|        } else {
  382|  50.4k|          key = parameters.substr(pos, delim-pos);
  383|  50.4k|          if (nextpos == std::string::npos) {
  ------------------
  |  Branch (383:15): [True: 41, False: 50.4k]
  ------------------
  384|     41|            value = parameters.substr(delim+1);
  385|  50.4k|          } else {
  386|  50.4k|            value = parameters.substr(delim+1, nextpos-delim-1);
  387|  50.4k|          }
  388|  50.4k|        }
  389|  53.5k|        if (key.empty()) {
  ------------------
  |  Branch (389:13): [True: 2.65k, False: 50.9k]
  ------------------
  390|       |          // no parameters at all
  391|  2.65k|          break;
  392|  2.65k|        }
  393|  50.9k|        key = decodeURL(key);
  394|  50.9k|        value = decodeURL(value);
  395|  50.9k|        parameter_map[key] = std::move(value);
  396|  50.9k|        if (nextpos == std::string::npos) {
  ------------------
  |  Branch (396:13): [True: 564, False: 50.3k]
  ------------------
  397|       |          // no more parameters left
  398|    564|          break;
  399|    564|        }
  400|       |
  401|  50.3k|        pos = nextpos+1;
  402|  50.3k|      }
  403|  3.22k|      return parameter_map;
  404|  3.22k|    }; //<! parses URL parameters into string map 

LLVMFuzzerTestOneInput:
   28|  3.33k|{
   29|  3.33k|  try {
   30|  3.33k|    YaHTTP::AsyncRequestLoader yarl;
   31|  3.33k|    YaHTTP::Request req;
   32|       |
   33|  3.33k|    yarl.initialize(&req);
   34|  3.33k|    bool finished = yarl.feed(std::string(reinterpret_cast<const char*>(data), size));
   35|  3.33k|    if (finished) {
  ------------------
  |  Branch (35:9): [True: 358, False: 2.97k]
  ------------------
   36|    358|      yarl.finalize();
   37|    358|    }
   38|  3.33k|  }
   39|  3.33k|  catch (const YaHTTP::ParseError& e) {
   40|    367|  }
   41|  3.33k|  catch (const std::exception& e) {
   42|      4|  }
   43|  3.33k|  catch (...) {
   44|      0|  }
   45|       |
   46|  3.33k|  return 0;
   47|  3.33k|}

