/* **************************************************************************** * * socketHttpConnect - */ int socketHttpConnect(const std::string& host, unsigned short port) { int fd; struct addrinfo hints; struct addrinfo* peer; char port_str[10]; LM_VVV(("Generic Connect to: '%s' port: '%d'", host.c_str(), port)); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; if (ipVersionUsed == IPV4) { hints.ai_family = AF_INET; LM_VVV(("Allow IPv4 only")); } else if (ipVersionUsed == IPV6) { hints.ai_family = AF_INET6; LM_VVV(("Allow IPv6 only")); } else { hints.ai_family = AF_UNSPEC; LM_VVV(("Allow IPv4 or IPv6")); } snprintf(port_str, sizeof(port_str), "%d" , (int) port); if (getaddrinfo(host.c_str(), port_str, &hints, &peer) != 0) { LM_RE(-1, ("getaddrinfo('%s'): %s", host.c_str(), strerror(errno))); } if ((fd = socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol)) == -1) { LM_RE(-1, ("socket: %s", strerror(errno))); } if (connect(fd, peer->ai_addr, peer->ai_addrlen) == -1) { freeaddrinfo(peer); close(fd); LM_E(("connect(%s, %d): %s", host.c_str(), port, strerror(errno))); return -1; } freeaddrinfo(peer); return fd; }
/* **************************************************************************** * * parseUrl - * * Breaks an URL into pieces. It returns false if the string passed as first * argument is not a valid URL. Otherwise, it returns true. * */ bool parseUrl(std::string url, std::string& host, int& port, std::string& path) { /* Sanity check */ if (url == "") { return false; } /* First: split by the first '/' to get host:ip and path */ std::vector<std::string> urlTokens; int components = stringSplit(url, '/', urlTokens); /* http://some.host.com/my/path * ^^ ^ ^ * || | | * ----- ------------- -- ---- * 0 2 3 4 position in urlTokens vector * 1 23 4 5 coponentes */ if ((components < 3) || (components == 3 && urlTokens[2].length() == 0)) { return false; } path = ""; /* Note that components could be 3, in which case we don't enter in the for. This is * the case of URL without '/' like eg. "http://www.google.com" */ for (int ix = 3; ix < components; ++ix ) { path += "/" + urlTokens[ix]; } if (path == "") { /* Minimum path is always "/" */ path = "/"; } /* Second: split third token for host and port */ std::string auxIp; std::string auxPort; // First we check if it is IPv6 if (getIPv6Port(urlTokens[2], auxIp, auxPort)) { // IPv6 host = auxIp; port = atoi(auxPort.c_str()); LM_VVV(("Parsed IPv6: '%s' and port: '%d'", host.c_str(), port)); } else { // IPv4 std::vector<std::string> hostTokens; components = stringSplit(urlTokens[2], ':', hostTokens); /* some.host.com:8080 * ^ * | * ------------- ---- * 0 1 position in urlTokens vector * 1 2 components */ /* Sanity check */ if (components > 2) { return false; } host = hostTokens[0]; if (components == 2) { port = atoi(hostTokens[1].c_str()); } else { port = DEFAULT_HTTP_PORT; } } return true; }