Test HTTP/HTTPS connectivity to a specific IP:port
(ip, port, timeout=5)
| 1544 | return connectivity_results |
| 1545 | |
| 1546 | def test_http_connectivity(ip, port, timeout=5): |
| 1547 | """Test HTTP/HTTPS connectivity to a specific IP:port""" |
| 1548 | results = { |
| 1549 | 'http': {'status': False, 'code': None, 'title': None, 'error': None}, |
| 1550 | 'https': {'status': False, 'code': None, 'title': None, 'error': None, 'is_self_signed': False} |
| 1551 | } |
| 1552 | |
| 1553 | # Test HTTP |
| 1554 | try: |
| 1555 | url = f"http://{ip}:{port}" |
| 1556 | response = requests.get(url, timeout=timeout, allow_redirects=True, verify=False) |
| 1557 | results['http']['status'] = True |
| 1558 | results['http']['code'] = response.status_code |
| 1559 | |
| 1560 | # Try to extract title from HTML and save body |
| 1561 | if 'text/html' in response.headers.get('content-type', '').lower(): |
| 1562 | import re |
| 1563 | title_match = re.search(r'<title[^>]*>([^<]+)</title>', response.text, re.IGNORECASE) |
| 1564 | if title_match: |
| 1565 | results['http']['title'] = title_match.group(1).strip()[:100] # Limit title length |
| 1566 | |
| 1567 | # Save response body (safely for JSON) |
| 1568 | body_text = response.text[:1048576] if response.text else "" # Limit to 1MB |
| 1569 | results['http']['body'] = body_text # Let JSON encoder handle escaping |
| 1570 | |
| 1571 | except Exception as e: |
| 1572 | results['http']['error'] = str(e)[:100] # Limit error length |
| 1573 | |
| 1574 | # Test HTTPS |
| 1575 | try: |
| 1576 | url = f"https://{ip}:{port}" |
| 1577 | |
| 1578 | # First try with verification to check if certificate is valid |
| 1579 | try: |
| 1580 | response = requests.get(url, timeout=timeout, allow_redirects=True, verify=True) |
| 1581 | results['https']['is_self_signed'] = False # Valid certificate |
| 1582 | except requests.exceptions.SSLError: |
| 1583 | # SSL error - likely self-signed or invalid certificate |
| 1584 | response = requests.get(url, timeout=timeout, allow_redirects=True, verify=False) |
| 1585 | results['https']['is_self_signed'] = True # Self-signed or invalid |
| 1586 | |
| 1587 | results['https']['status'] = True |
| 1588 | results['https']['code'] = response.status_code |
| 1589 | |
| 1590 | # Try to extract title from HTML and save body |
| 1591 | if 'text/html' in response.headers.get('content-type', '').lower(): |
| 1592 | import re |
| 1593 | title_match = re.search(r'<title[^>]*>([^<]+)</title>', response.text, re.IGNORECASE) |
| 1594 | if title_match: |
| 1595 | results['https']['title'] = title_match.group(1).strip()[:100] # Limit title length |
| 1596 | |
| 1597 | # Save response body (safely for JSON) |
| 1598 | body_text = response.text[:1048576] if response.text else "" # Limit to 1MB |
| 1599 | results['https']['body'] = body_text # Let JSON encoder handle escaping |
| 1600 | |
| 1601 | except Exception as e: |
| 1602 | results['https']['error'] = str(e)[:100] # Limit error length |
| 1603 |