| 1524 | } |
| 1525 | |
| 1526 | ParseResult |
| 1527 | url_parse_http_regex(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings) |
| 1528 | { |
| 1529 | const char *cur = *start; |
| 1530 | const char *host_end; |
| 1531 | |
| 1532 | // Do a quick check for "://" - our only format check. |
| 1533 | if (end - cur > 3 && (((':' ^ *cur) | ('/' ^ cur[1]) | ('/' ^ cur[2])) == 0)) { |
| 1534 | cur += 3; |
| 1535 | } else if (':' == *cur && (++cur >= end || ('/' == *cur && (++cur >= end || ('/' == *cur && ++cur >= end))))) { |
| 1536 | return PARSE_RESULT_ERROR; |
| 1537 | } |
| 1538 | |
| 1539 | // Grab everything until EOS or slash. |
| 1540 | const char *base = cur; |
| 1541 | cur = static_cast<const char *>(memchr(cur, '/', end - cur)); |
| 1542 | if (cur) { |
| 1543 | host_end = cur; |
| 1544 | // Remove all preceding slashes |
| 1545 | while (cur < end && *cur == '/') { |
| 1546 | cur++; |
| 1547 | } |
| 1548 | } else { |
| 1549 | host_end = cur = end; |
| 1550 | } |
| 1551 | |
| 1552 | // Did we find something for the host? |
| 1553 | if (base != host_end) { |
| 1554 | const char *port = nullptr; |
| 1555 | int port_len = 0; |
| 1556 | |
| 1557 | // Check for port. Search from the end stopping on the first non-digit |
| 1558 | // or more than 5 digits and a delimiter. |
| 1559 | port = host_end - 1; |
| 1560 | const char *port_limit = host_end - 6; |
| 1561 | if (port_limit < base) { |
| 1562 | port_limit = base; // don't go past start. |
| 1563 | } |
| 1564 | |
| 1565 | while (port >= port_limit && isdigit(*port)) { |
| 1566 | --port; |
| 1567 | } |
| 1568 | |
| 1569 | // A port if we're still in the host area and we found a ':' as |
| 1570 | // the immediately preceeding character. |
| 1571 | if (port >= base && ':' == *port) { |
| 1572 | port_len = host_end - port - 1; // must compute this first. |
| 1573 | host_end = port; // then point at colon. |
| 1574 | ++port; // drop colon from port. |
| 1575 | url->set_port(heap, port, port_len, copy_strings); |
| 1576 | } |
| 1577 | |
| 1578 | // Now we can set the host. |
| 1579 | url->set_host(heap, base, host_end - base, copy_strings); |
| 1580 | } |
| 1581 | |
| 1582 | // path is anything that's left. |
| 1583 | if (cur < end) { |
no test coverage detected