2014-11-01 3 views
3

매우 간단한 세션 관리자를 작성하여 미들웨어를 이해하려고합니다.하스켈 WAI에서 헤더를 미들웨어로 추가하려면 어떻게해야합니까?

응답에 SetCookie 헤더를 추가해야합니다. wai-extra 패키지를 살펴본 결과 wai-session이 발견되었습니다.

wai-3.0.2를 사용하고 있는데, Response에 대한 유형 생성자에 대한 직접 액세스 권한이없는 것 같습니다. 그리고 패턴을 찾은 모든 예는 Response(..)에서 헤더를 추가합니다.

올바른 방향으로 나를 가리킬 수 있습니까?

+1

'Network.Wai.Internal'을 가져 와서'Response'의 생성자에 패턴 일치를시킬 수 있습니다. – ibotty

+0

@ibotty 오케이, 나는 어리 석다. 나는 그것을 시도했지만 실패했다. 형식 생성자 중 하나의 이름이 변경 되었기 때문에 실패했음을 알았습니다. – rob

+0

다음 번에 ghci에서 탐색 해보십시오. ': i'를 사용하면 모든 생성자와 정의 된 곳을 알 수 있습니다. – ibotty

답변

5

편집 : Wai의 버전 3.0.3.0은 아래 예제에서 mapHeader과 동일한 도우미 함수 mapResponseHeaders을 소개합니다. 즉, 예제에서는 더 이상 Response에서 패턴 일치를 수행 할 필요가 없습니다.

import Network.HTTP.Types (ResponseHeaders, Header) 
import Network.Wai (Middleware, Response, mapResponseHeaders) 

withHeader :: Header -> Middleware 
withHeader h app req respond = app req $ respond . addHeader h 

addHeader :: Header -> Response -> Response 
addHeader h = mapResponseHeaders (\hs -> h:hs) 

나는 뭔가 작업을하고, 내가 알고 있다고 생각하지만, 의견과 제안 하시겠습니까 정말. 저는 하스켈을 처음 접했고 이것이 와이의 첫 번째 사용법입니다. 가장 큰 걸림돌은 응용 프로그램 유형이 Wai 3.0.0에서 연속 통과 스타일로 변경되었음을 깨닫지 못했습니다. (문서의 상태를 명확하게 매우, 난 그냥 그것을 처음 15 시간을 놓친 나는 그것을 읽어 보시기 바랍니다.)

import Network.HTTP.Types (ResponseHeaders, Header) 
import Network.Wai (Middleware) 
import Network.Wai.Internal (Response(..)) 

withHeader :: Header -> Middleware 
withHeader h app req respond = app req $ respond . addHeader h 

mapHeader :: (ResponseHeaders -> ResponseHeaders) -> Response -> Response 
mapHeader f (ResponseFile s h b1 b2) = ResponseFile s (f h) b1 b2 
mapHeader f (ResponseBuilder s h b) = ResponseBuilder s (f h) b 
mapHeader f (ResponseStream s h b) = ResponseStream s (f h) b 
mapHeader _ [email protected](ResponseRaw _ _) = r 

addHeader :: Header -> Response -> Response 
addHeader h = mapHeader (\hs -> h:hs) 

내가 방법을 알아낼 수 없었기 때문에 내가하는 ResponseRaw 헤더를 수정하려는 시도를하지 않았다.

addHeader이 부분적으로 적용되고 내부 응용 프로그램에 전달 된 연속 함수인지는 분명하지 않습니다. 이 양식은 명확하게 (또는 이보다) 수도 :

withHeader h app req respond = app req $ \resp -> respond $ addHeader h resp 

나는 wai-session에서 mapHeader을 복사하지만 ResponseRaw의 경우를 추가했다.

+0

Network.Wai.Internal에서 Response 생성자를 가져와야하는 것은 불행한 일입니다. 그러나 내가 볼 수있는 한이를 수행 할 수있는 유일한 방법입니다. – hdgarrood

+0

또한 부분적으로 적용되는'addHeader'는 나에게 분명합니다; 에타 확장 버전보다 차라리. 마침내 mapHeader의 마지막 패턴에서'f'가 사용되지 않으므로'f'에'_'를 사용하는 것을 선호합니다. (당신이 -Wall을 사용했다면 경고 메시지가 나타납니다.) – hdgarrood

+0

@hdgarrood 사용하지 않은'f'를'_'으로 변경했습니다. 그게 나아. 하스켈에 익숙해지면서 부분적으로 적용된 버전을 선호합니다. 의견에 감사드립니다! – rob