@@ -4,6 +4,7 @@ import { Readable } from 'node:stream';
44
55import { HttpCrawler , SessionPool } from '@crawlee/http' ;
66import { ResponseWithUrl } from '@crawlee/http-client' ;
7+ import iconv from 'iconv-lite' ;
78import { MemoryStorageEmulator } from '../../shared/MemoryStorageEmulator.js' ;
89
910const router = new Map < string , http . RequestListener > ( ) ;
@@ -60,6 +61,20 @@ router.set('/403-with-octet-stream', (req, res) => {
6061 res . end ( ) ;
6162} ) ;
6263
64+ router . set ( '/meta-charset' , ( req , res ) => {
65+ const text = 'Žluťoučký kůň' ;
66+ const html = `<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1250"></head><body>${ text } </body></html>` ;
67+ res . setHeader ( 'content-type' , 'text/html' ) ; // no charset in HTTP header
68+ res . end ( iconv . encode ( html , 'windows-1250' ) ) ;
69+ } ) ;
70+
71+ router . set ( '/meta-charset-html5' , ( req , res ) => {
72+ const text = 'Žluťoučký kůň' ;
73+ const html = `<html><head><meta charset="windows-1250"></head><body>${ text } </body></html>` ;
74+ res . setHeader ( 'content-type' , 'text/html' ) ; // no charset in HTTP header
75+ res . end ( iconv . encode ( html , 'windows-1250' ) ) ;
76+ } ) ;
77+
6378let server : http . Server ;
6479let url : string ;
6580
@@ -208,6 +223,36 @@ test('invalid content type defaults to octet-stream', async () => {
208223 ] ) ;
209224} ) ;
210225
226+ test ( 'decodes charset from http-equiv meta tag when absent in HTTP header' , async ( ) => {
227+ const results : string [ ] = [ ] ;
228+
229+ const crawler = new HttpCrawler ( {
230+ maxRequestRetries : 0 ,
231+ requestHandler : ( { body } ) => {
232+ results . push ( body as string ) ;
233+ } ,
234+ } ) ;
235+
236+ await crawler . run ( [ `${ url } /meta-charset` ] ) ;
237+
238+ expect ( results [ 0 ] ) . toContain ( 'Žluťoučký kůň' ) ;
239+ } ) ;
240+
241+ test ( 'decodes charset from HTML5 meta charset attribute when absent in HTTP header' , async ( ) => {
242+ const results : string [ ] = [ ] ;
243+
244+ const crawler = new HttpCrawler ( {
245+ maxRequestRetries : 0 ,
246+ requestHandler : ( { body } ) => {
247+ results . push ( body as string ) ;
248+ } ,
249+ } ) ;
250+
251+ await crawler . run ( [ `${ url } /meta-charset-html5` ] ) ;
252+
253+ expect ( results [ 0 ] ) . toContain ( 'Žluťoučký kůň' ) ;
254+ } ) ;
255+
211256test ( 'handles cookies from redirects' , async ( ) => {
212257 const results : string [ ] = [ ] ;
213258
0 commit comments