Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion src/squid-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,46 @@ describe('generateSquidConfig', () => {
});
});

describe('Bare Hostname Handling', () => {
it('should handle bare hostnames without adding leading dot', () => {
// Bare hostnames (no dots) like Docker container names should not get a leading dot
// because they have no subdomains to match
const config: SquidConfig = {
domains: ['api-proxy', 'localhost'],
port: defaultPort,
};
const result = generateSquidConfig(config);
expect(result).toContain('acl allowed_domains dstdomain api-proxy');
expect(result).toContain('acl allowed_domains dstdomain localhost');
expect(result).not.toContain('.api-proxy');
expect(result).not.toContain('.localhost');
});

it('should handle mixed bare hostnames and FQDNs', () => {
const config: SquidConfig = {
domains: ['api-proxy', 'github.com', 'localhost', 'example.org'],
port: defaultPort,
};
const result = generateSquidConfig(config);
// Bare hostnames without leading dot
expect(result).toContain('acl allowed_domains dstdomain api-proxy');
expect(result).toContain('acl allowed_domains dstdomain localhost');
// FQDNs with leading dot
expect(result).toContain('acl allowed_domains dstdomain .github.com');
expect(result).toContain('acl allowed_domains dstdomain .example.org');
});

it('should handle bare hostnames with protocol prefixes', () => {
const config: SquidConfig = {
domains: ['http://api-proxy'],
port: defaultPort,
};
const result = generateSquidConfig(config);
expect(result).toContain('acl allowed_http_only dstdomain api-proxy');
expect(result).not.toContain('.api-proxy');
});
});

describe('Redundant Subdomain Removal', () => {
it('should remove subdomain when parent domain is present', () => {
const config: SquidConfig = {
Expand Down Expand Up @@ -293,12 +333,14 @@ describe('generateSquidConfig', () => {
});

it('should handle TLD-only domain (edge case)', () => {
// TLD-only (e.g., 'com') is a bare hostname with no dots, so no leading dot
const config: SquidConfig = {
domains: ['com'],
port: defaultPort,
};
const result = generateSquidConfig(config);
expect(result).toContain('acl allowed_domains dstdomain .com');
expect(result).toContain('acl allowed_domains dstdomain com');
expect(result).not.toContain('.com');
});
});

Expand Down
25 changes: 23 additions & 2 deletions src/squid-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,31 @@ interface PatternsByProtocol {
}

/**
* Helper to add leading dot to domain for Squid subdomain matching
* Helper to format domain for Squid ACL matching
*
* For fully qualified domains (containing dots), adds a leading dot to enable
* subdomain matching (e.g., .github.com matches both github.com and api.github.com).
*
* For bare hostnames (no dots, like Docker container names), returns as-is without
* a leading dot since bare hostnames have no subdomains to match.
*
* @param domain - Domain or hostname to format
* @returns Formatted string for Squid dstdomain ACL
*/
function formatDomainForSquid(domain: string): string {
return domain.startsWith('.') ? domain : `.${domain}`;
// Already has leading dot - return as-is
if (domain.startsWith('.')) {
return domain;
}

// Bare hostname (no dots) - return as-is (e.g., 'api-proxy', 'localhost')
// These are typically Docker container names or single-word hostnames
if (!domain.includes('.')) {
return domain;
}

// Fully qualified domain - add leading dot for subdomain matching
return `.${domain}`;
}

/**
Expand Down
Loading