| 167 | } |
| 168 | |
| 169 | static void ExtractHostPort(const struct HttpUrl* url, cc_string* host, cc_string* port) { |
| 170 | /* address can have the form of either "host" or "host:port" */ |
| 171 | /* Slightly more complicated because IPv6 hosts can be e.g. [::1] */ |
| 172 | cc_string addr = url->address; |
| 173 | int idx = String_IndexOf(&addr, ':'); |
| 174 | int endIdx; |
| 175 | |
| 176 | /* Special handling for raw IPv6 hosts, e.g. "[::1]:80" */ |
| 177 | if (addr.length && addr.buffer[0] == '[' && (endIdx = String_IndexOf(&addr, ']')) >= 0) { |
| 178 | *host = String_UNSAFE_Substring(&addr, 1, endIdx - 1); |
| 179 | addr = String_UNSAFE_SubstringAt(&addr, endIdx + 1); |
| 180 | |
| 181 | idx = String_IndexOf(&addr, ':'); |
| 182 | } else if (idx == -1) { |
| 183 | /* Hostname/IP only */ |
| 184 | *host = addr; |
| 185 | } else { |
| 186 | /* Hostname/IP:port */ |
| 187 | *host = String_UNSAFE_Substring(&addr, 0, idx); |
| 188 | } |
| 189 | |
| 190 | if (idx == -1) { |
| 191 | *port = String_Empty; |
| 192 | } else { |
| 193 | *port = String_UNSAFE_SubstringAt(&addr, idx + 1); |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct HttpUrl* url) { |
| 198 | cc_string host, port; |
no test coverage detected