안녕하세요... 정말 오랜만의 포스트군요. 원래 게으른데다 WCF 도서 집필, 회사 일도 많아서 정신이 없었답니다. 사이트에 너무 신경을 안 쓰는 거 아니냐 라고 생각하실지 모르지만... 맞습니다. T_T
그래도 매일 들어와 포스트에 대한 피드백 답변과 가끔 올라오는 질문들에 대해 "여긴 Q/A 게시판이 아닙니다"라는 싸가지 없는 글들을 남기곤 했답니다. 항상 좋은 내용을 독자 분들께 남기려고 고민하고 아이디어를 생각하지만 절대적인 시간 부족으로 "생각"으로만 끝나는 경우가 많네요.
Fiddler Tip in Capturing Web Service Message
"오호라... 간만에 글을 쓴다 이거지? 이젠 시간이 좀 되나 보지? "
이렇게 생각하는 독자가 있을지 모르겠다. 미안하게도 여전히 필자는 시간이 없다. 하지만 이렇게 사이트를 방치하다가는 손님 다 떨어질 것 같은 위기감에 봉착한 필자, 가벼운 팁 하나로 글 하나 날로 먹어보고자 글을 써 본다.
Fiddler는 웹 개발자들에게 필수적인 디버깅 도구이다. 간편하고 손쉬운 설치와 사용방법도 매력적이지만 누구(?)나 무료로 다운로드 받아 사용할 수 있기 때문이다. 이런걸 만들어 나눠 주는 사람은 어떤 사람인지 정말 궁금하지 않은가?
http://www.fiddlertool.com
Fiddler에 대해 아직 모른다면 숏 잡고 2-30초 정도 반성의 시간을 가진 다음에 즉시 이 도구를 다운로드 받아 사용해 보길 권하는 바이다. 웹 어플리케이션과 HTTP 그리고 웹 서비스에 또 다른 눈을 뜨게 될 것이다. 아는 사람은 다 아는 유명하고 유용한 도구이기 때문에 구차하게 여기서 Fiddler를 어떻게 사용하는 지에 대해서는 언급하지 않겠다. 현재 Fiddler의 최신 버전은 2.x 이며 다양한 Add-in을 사용하여 더욱 더 편리하고 강력하게 HTTP 메시지들을 캡처 할 수 있다(화면2).

화면1. Syntax Highlight 애드온을 사용한 Fiddler 2.x 버전
Fiddler를 활용하는 방법은 대단히 다양하지만 오늘 관심을 가질 부분은 웹 서비스 호출을 캡처 하여 SOAP(Simple Object Access Protocol) 메시지를 살펴본다던가 웹 서비스 디버깅을 하는 경우이다. 쉽게 말하면 ASP.NET Web Service 혹은 WCF(Windows Communication Foundation) 호출에 문제가 있는 경우 이것을 살펴볼 때 유용하다는 말이 되겠다. 그런데... Fiddler를 통해 웹 서비스 호출을 캡처 할 때 가끔 클라이언트 프로그램이 다음과 같은 예외를 작렬하는 경우가 생기곤 한다.
System.Net.WebException: 기본 연결이 닫혔습니다. 보내기에서 예기치 않은 오류가 발생했습니다. ---> System.IO.IOException: 전송 연결 현재 연결은 사용자의 호스트 시스템의 소프트웨어의 의해 중단되었습니다 ---> System.Net.Sockets.SocketException: 현재 연결은 사용자의 호스트 시스템의 소프트웨어의 의해 중단되었습니다.
이 예외가 발생하는 이유는 이렇다. HTTP는 TCP를 하부 트랜스포트(transport) 프로토콜로 사용함에도 불구하고 그 특성 상 Connection-less 프로토콜이기 때문이다. 즉, 매 HTTP Request/Response 마다 TCP 연결을 맺고 끊거나(HTTP 1.0), TCP 연결을 유지하는 것을 서버와 클라이언트가 협상할 수도 있지만 언제든지 TCP 연결은 끊길 수 있다(HTTP 1.1)는 것이다. 서버에 의해 TCP 연결이 강제로 끊기는 경우 닷넷 HttpWebRequest 클래스(웹 서비스와 WCF가 내부적으로 사용한다)가 이와 같은 예외를 유발하곤 한다. 특히, Fiddler로 웹 서비스 호출을 캡처 할 때 이런 예외가 자주 발생하는데, Fiddler가 클라이언트와 Fiddler 와의 TCP 연결을 끊어버리기 때문이다.
기본적으로 HTTP 클라이언트는 이렇게 TCP 연결이 서버에 의해 끊기는 상황에 대처하는 것이 가장 좋지만 Fiddler를 사용하지 않으면 전혀 문제가 없는 경우가 대부분이므로 굳이 복잡한 코드를 추가적으로 구사하지 않는 것이 일반적이라 할 수 있겠다.
Fiddler는 매우 유연한 도구이다. 다양한 애드인을 개발할 수 있을 뿐만 아니라 HTTP 메시지를 캡처 하거나 필터링 하는 작업에 자신만의 규칙을 자바 스크립트를 통해 구현할 수도 있다. 앞서 언급한 웹 서비스 캡처 시에 발생하는 연결 끊김 문제를 해결하는 방법은 Fiddler의 커스텀 규칙을 약간 수정하면 해결이 가능하다. 이 방법은 Fiddler의 홈페이지(http://www.fiddlertool.com)에서 Known Issue 페이지를 살펴보면 된다.
뭐 링크 알려줬으니 여기서 블로그를 끝내는 것도 나쁘지 않겠지만... 잉글리쉬 프러블럼이 있거나 필자보다 더 심한 귀차니즘에 쩔어 사는 독자들을 위해 여기서 다시 설명하도록 하겠다. 먼저 화면2와 같이 Fiddler의 규칙 에디터 메뉴를 선택하자.

화면2. Fiddler의 Customize Rules 메뉴
그러면 Notepad 혹은 Fiddler Rule Editor가 구동될 것이다. 이 Rule은 Fiddler가 HTTP 메시지를 캡처 할 때 사용하는 다양한 규칙으로써 JScript.NET 코드이다. 이 코드에서 OnBeforeResponse 메쏘드를 눈에 불을 켜고 찾자. 쉽게 찾을 수 있을 것이다. 이 메쏘드의 맨 끝을 보면 몇 줄의 코드가 주석(comment)에 의해 막혀 있을 것이다. 이 코드의 주석을 살포시 풀어주자. 다음과 같이 말이다.
// Uncomment to reduce incidence of "unexpected socket closure" exceptions in .NET code.
// Note that you really should also fix your .NET code to gracefully handle unexpected connection closure.
//
if ((oSession.responseCode != 401) && (oSession.responseCode != 407)){
oSession.oResponse["Connection"] = "close";
}
리스트1. 수정해야 할 Fiddler의 Rule 코드
수정을 했으면 저장을 하고 에디터를 닫는다. 좀 허무하지만 이게 전부이다. 이렇게 수정하고 나면 이제 웹 서비스 호출을 Fiddler가 캡처 하는 상황에서도 "기본 연결이 닫혔습니다(The underline connection was closed)" 라는 예외가 발생하지 않을 것이다.
필자도 이 방법을 최근에 알게 되어 매우 유용하게 써먹고 있다. Fiddler를 사용하는 독자들도 이 방법을 통해 웹 서비스 호출을 캡처 할 때 발생할 수 있는 문제들을 해결하기 바란다.