/* find Host for Metric */ static Host * findHost(Task *t, Metric *m) { Host *h; h = t->hosts; while (h) { /* look for existing host */ if (h->name == m->hname) return h; h = h->next; } h = newHost(t, m->hname); /* add new host */ if (t->hosts) { h->next = t->hosts; t->hosts->prev = h; } t->hosts = h; return h; }
void ServerInfo::parseURL(const char *theURL, std::size_t len) { std::size_t offset = 0; bool urlUsesSSL; // Check that the length of the infoString is at least as long as the // shortest permissible URL. This check allows us to safely execute // all of the checks in the following if statement without worrying // about running off the end of the buffer. The comparison string // is only significant for being a minimally valid URL. if (len - offset < MIN_URL_LEN) { invalidURL("URL too short", theURL, len); } if ((theURL[offset] == 'h' || theURL[offset] == 'H') && (theURL[++offset] == 't' || theURL[offset] == 'T') && (theURL[++offset] == 't' || theURL[offset] == 'T') && (theURL[++offset] == 'p' || theURL[offset] == 'P')) { if (theURL[offset + 1] == 's' || theURL[offset + 1] == 'S') { urlUsesSSL = true; offset += 2; } else { urlUsesSSL = false; offset += 1; } if (theURL[offset] == ':' && theURL[offset + 1] == '/' && theURL[offset + 2] == '/') { offset += 3; std::size_t startOfHost = offset; while (offset < len && ':' != theURL[offset] && '/' != theURL[offset]) { offset += 1; } std::size_t hostLen = offset - startOfHost; if (hostLen > 0) { std::string newHost(&theURL[startOfHost], hostLen); unsigned short newPort = urlUsesSSL ? HTTPS_PORT : HTTP_PORT; std::string newURI("/"); if (offset < len) { if (':' == theURL[offset]) { offset += 1; std::size_t startOfPort = offset; while (offset < len && '0' <= theURL[offset] && '9' >= theURL[offset]) { offset += 1; } // NOTE: RFC NNNN allows a URL to have the following // form: http://host:/, i.e. port separator present // but no port number specified. if (offset - startOfPort > 0) { unsigned int value = 0; for (std::size_t i = startOfPort; i < offset; ++i){ value = (value * 10) + (theURL[i] - '0'); } if (value <= USHRT_MAX) { newPort = static_cast<unsigned short>(value); } else { invalidURL("invalid port number", theURL, len); } } } if (offset < len) { if ('/' == theURL[offset++]) { newURI.append(&theURL[offset], len - offset); } else { invalidURL("invalid character in port number", theURL, len); } } } // We have successfully parsed the URL, so now we can // assign the bits and pieces to the member fields, without // worrying about corrupting the object, since none of // these operations will generate an exception. host.swap(newHost); port = newPort; use_ssl = urlUsesSSL; uri.swap(newURI); this->url.append(theURL, len); } else { invalidURL("missing host name", theURL, len); } } else { invalidURL("unable to parse protocol terminator", theURL, len); } } else { invalidURL("unable to parse protocol", theURL, len); } }