Как обрабатывать и сохранять тело HTTP как есть в Haskell?

Я попробовал следующий код для загрузки HTML, но он фактически преобразует не-ASCII-символы в последовательности декодированных символов, таких как и 0033200400\0031\0031.

openURL x = getResponseBody =<< simpleHTTP (getRequest x)

download url path = do src <- openURL url
 writeFile path src

Как изменить следующий код для написания ответа HTTP точно так же, как получено? Как следует искать и манипулировать строками в таком контенте?

1 ответ

Строковый вывод типа "\ 1234\5678" на самом деле имеет только два символа - данные сохраняются, но вам нужно правильно его интерпретировать. Вероятно, лучший способ сделать это - использовать Text который вместо списка Char s фактически представляет собой байтовый массив, представляющий кодовые точки UTF-8.

Для этого вам нужно использовать несколько более общий интерфейс в HTTP mkRequest :: BufferType ty => RequestMethod → URI → Request ty. Text напрямую не создает экземпляр BufferType, поэтому мы пройдем через ByteString, который представляет двоичные фрагменты данных - он не имеет никакой конкретной интерпретации кодировки этих данных.

Затем мы можем использовать decodeUtf8 для преобразования необработанных байтов в Text UTF-8

import Data.Text
import Data.Text.Encoding
import Data.ByteString

\ uri -> do
 rawData <- getResponseBody =<< simpleHTTP (mkRequest GET uri) :: IO Text
 return (decodeUtf8 rawData)

Обратите внимание, что decodeUtf8 является частичным - он может потерпеть неудачу способом, который не может быть пойман в чистом коде, требующем перезапуска или обработчика полностью в вашем стеке IO. Если это нежелательно, если есть хорошая вероятность, что вы загружаете текст, который недопустим, UTF-8, то вы можете использовать decodeUtf8' который возвращает Either.

licensed under cc by-sa 3.0 with attribution.