Backend with Golang

Building HTTP Services - Middleware(Network programming with Go)

아직개구리 2023. 7. 30. 17:08

Middleware는 http.Handler를 인풋으로 받아서 http.Handler를 return 하는 reusable function들이다. 

다음 handler에게 passing하기 전에 content에 기반하여 몇가지를 결정하는데 쓰이곤 한다. 아니면 request content에 따라서 response의 header를 작성하기도 한다. 그리고 아래 리스트와 같은 일들을 처리하기도 한다. 하나의 middleware에서 여러개의 테스크를 담당하지 않도록 하는 게 좋다. 대신에 minimalist middleware 를 작성하는 것이 중요하다. 

  • authentication
  • collect metrics 
  • log requests 
  • control access to resources 

middleware에서는  parameter로 들어온 Handler를 실행시키는데, 어떤 케이스에서는 그다음껄 실행시키지 않아야 할 때는 block하고 client에게 직접 respond를 하기도 한다.

 

Timing Out Slow Clients

client가 request-response life cycle의 duration을 명령할 수 있도록 하게 하면 악의적인 client들이 server 의 resource를 고갈시킬 수 있다는 문제점이 있다. 하지만 동시에 read & write time-outs를 서버단에서 시간을 정하게 되면  stream data하거나 각 handler마다 different time-out duration 을 가지도록 조정하는 것이 어려워지게 된다. 

 

대신에 tiemout을 middleward에서 다루거나 individual handler에서 다뤄야한다. 

http.TimeoutHandler 는 http.Handler, duration, 그리고 response body에 담아야 할 string을 parameter로 받는 함수인데, 이렇게 하면 internal timer를 설정할 수 있게 된다. 인풋으로 들어간 handler가 timer가 expired되기 전에 return되지 않는다면, timeouthandler는 handler 를 블락하고, 503 에러를 내보내게 된다. 

 

Protecting Sensitive Files 

server의 파일을 내려줄 때, . 으로 시작하는 파일들은 보통 보호되어야하는데, http.FileServer 함수는 . 에 상관없이 검색하여 내려주게 된다. 그래서 StripPrefix, RestrictPrefix와 같은 middleware를 거쳐야한다. RestrictPrefix middleware의 경우 request's resource path를 분석해서 client가 restricted path로 request를 보냈는지 확인한다. 

만약에 제한된 path로 보냈다면, middleware내부에서 error 를 respond하고, fileserver함수로 전달하지 않는다. 

사실 resource를 제한하는 더 좋은 접근 방법은 모든 resources를 block하고, 선택된 몇개에 대해서만 allow하는 것이다.