diff --git a/src/lib/integrations/deluge.service.ts b/src/lib/integrations/deluge.service.ts index 377467f..1ca4ea5 100644 --- a/src/lib/integrations/deluge.service.ts +++ b/src/lib/integrations/deluge.service.ts @@ -193,6 +193,7 @@ export class DelugeService implements IDownloadClient { torrentResponse = await axios.get(torrentUrl, { responseType: 'arraybuffer', maxRedirects: 0, validateStatus: (s) => s >= 200 && s < 300, timeout: DOWNLOAD_CLIENT_TIMEOUT, + headers: { 'User-Agent': RMAB_USER_AGENT }, }); if (torrentResponse.data.length > 0) { const magnetMatch = torrentResponse.data.toString().match(/^magnet:\?[^\s]+$/); @@ -205,7 +206,7 @@ export class DelugeService implements IDownloadClient { const loc = error.response.headers['location']; if (loc?.startsWith('magnet:')) return this.addMagnetLink(loc, category, options); if (loc?.startsWith('http://') || loc?.startsWith('https://')) { - try { torrentResponse = await axios.get(loc, { responseType: 'arraybuffer', timeout: DOWNLOAD_CLIENT_TIMEOUT, maxRedirects: 5 }); } + try { torrentResponse = await axios.get(loc, { responseType: 'arraybuffer', timeout: DOWNLOAD_CLIENT_TIMEOUT, maxRedirects: 5, headers: { 'User-Agent': RMAB_USER_AGENT } }); } catch { throw new Error('Failed to download torrent file after redirect'); } } else { throw new Error(`Invalid redirect location: ${loc}`); } } else { throw new Error(`Failed to download torrent: HTTP ${status}`); } diff --git a/src/lib/integrations/prowlarr.service.ts b/src/lib/integrations/prowlarr.service.ts index 90128ff..2e32865 100644 --- a/src/lib/integrations/prowlarr.service.ts +++ b/src/lib/integrations/prowlarr.service.ts @@ -318,7 +318,7 @@ export class ProwlarrService { extended: 1, }, headers: { - 'User-Agent': 'ReadMeABook', + 'User-Agent': RMAB_USER_AGENT, }, timeout: DOWNLOAD_CLIENT_TIMEOUT, responseType: 'text', // Get XML as text diff --git a/src/lib/integrations/transmission.service.ts b/src/lib/integrations/transmission.service.ts index 4cc7ce5..8705873 100644 --- a/src/lib/integrations/transmission.service.ts +++ b/src/lib/integrations/transmission.service.ts @@ -278,6 +278,7 @@ export class TransmissionService implements IDownloadClient { maxRedirects: 0, validateStatus: (status) => status >= 200 && status < 300, timeout: DOWNLOAD_CLIENT_TIMEOUT, + headers: { 'User-Agent': RMAB_USER_AGENT }, }); // Check if response body is a magnet link @@ -307,6 +308,7 @@ export class TransmissionService implements IDownloadClient { responseType: 'arraybuffer', timeout: DOWNLOAD_CLIENT_TIMEOUT, maxRedirects: 5, + headers: { 'User-Agent': RMAB_USER_AGENT }, }); } catch { throw new Error('Failed to download torrent file after redirect'); diff --git a/src/lib/services/ebook-scraper.ts b/src/lib/services/ebook-scraper.ts index d847e6d..a22f627 100644 --- a/src/lib/services/ebook-scraper.ts +++ b/src/lib/services/ebook-scraper.ts @@ -20,7 +20,6 @@ export interface EbookDownloadResult { error?: string; } -const USER_AGENT = RMAB_USER_AGENT; const REQUEST_DELAY_MS = 1500; // 1.5 second delay between requests const DOWNLOAD_TIMEOUT_MS = 60000; // 60 seconds per download attempt const MAX_SLOW_LINK_ATTEMPTS = 5; @@ -114,7 +113,7 @@ async function fetchHtml( moduleLogger.debug(`Using direct request for: ${url}`); const response = await retryRequest(() => axios.get(url, { - headers: { 'User-Agent': USER_AGENT }, + headers: { 'User-Agent': RMAB_USER_AGENT }, timeout: 30000, }) ); @@ -655,7 +654,7 @@ async function downloadFile( const response = await axios.get(url, { responseType: 'stream', timeout: DOWNLOAD_TIMEOUT_MS, - headers: { 'User-Agent': USER_AGENT }, + headers: { 'User-Agent': RMAB_USER_AGENT }, maxRedirects: 5, });