Ruby http request 사용시 404 에러 삽질

모든 삽질이 그렇지만 알면 간단하지만 몇시간 허비한 삽질기입니다.

Ruby, 엄밀히 말해서 Rails는 많은 것을 알아서 해주는 경우가 많습니다. 예를 들어 문자 날짜 변환도 다음과 같이 자동으로 해줍니다.

"2017.02.02".to_date "2017/04/05".to_date "Feb. 13 2016".to_date

이번 삽질도 이런 편리함에 깊게 생각하지 않아서 발생한 삽질이었습니다.

문제정의

HTTP 기반으로 다른 API 서버를 호출하기 위해 다음과 같은 코드를 작성했습니다.

1
2
3
4
5
6
7
8
9
10
send_request('http://api-server:8080/api/v1/test')
def send_request(url, data)
  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  header = {'Content-Type' => 'application/json'} 
  request = Net::HTTP::Post.new(url, header)
  request.body = data.to_json
  response = http.request(request)
  response
end

이 코드로 여러 서비스에 접속해서 처리하는 것은 잘 되었습니다. 심지어 외부 OAuth 인증하는 코드도 잘 호출 되었습니다. 문제는 새로운 API 서버 호출하려고 하는데 계속 404 Not Found 에러를 받고 있었습니다.

삽질 내용

  1. 기존에 잘 동작하는 코드라 의심을 하지 않고 API 서버쪽 문제라 생각하고 Postman 으로 호출 시도 -> 정상 동작
  2.  다른 프로그램 언어(자바)로 동일하게 동작하는 코드 작성 및 동일 서버에 호출 -> 정상 동작
  3. 위 코드로 다른 API 서버에 호출 -> 정상 동작

해결 절차

  1. 이렇게 계속 반복해서 몇시간을 허비한 뒤 해당 API 서버 담당자에게 호출 시 서버 로그에 어떻게 나오는지 확인을 해달라고 요청했습니다.  서버 로그를 확인해보니 다음과 같이 path 부분이 없이 호출하고 있었습니다.

    POST, http://api-server:8080

  2.  로그 확인 후 소스 코드 문제를 의심하고 다음 부분을 수정

    request = Net::HTTP::Post.new(url, header) -> request = Net::HTTP::Post.new(uri.request_uri, header)

  3. 정상 동작 확인
  4. ruby 의 구현 코드를 보면 url 처리하는 부분이 다음과 같이 구현되어 있는 것 확인

    1
    2
    3
    4
    5
    6
    7
    def initialize(m, reqbody, resbody, uri_or_path, initheader = nil)
      if URI === uri_or_path then
        ...
        @path = uri_or_path.request_uri
      else
        @path = uri_or_path.dup
      end

어떤 서버에는 정상 동작하고 어떤 서버에는 비정상 동작하는 것을 보면 request 정보의 path에 host, port 정보가 포함되어 있어도 이를 유연하게 처리하는 서버가 있는 반면에 이를 엄격하게 처리하는 서버가 있는 것으로 파악됩니다. 물론 확인을 해보면 알겠지만 이것까지 확인해보기에는 시간이 없어 패스 했습니다. 정상동작했던 서버들의 대부분은 IIS 이고, 비정상 동작했던 서버는 Nginx를 사용하는 서버 였습니다.

교훈

원래 문제가 발생하면 로그를 먼저 확인하는 것이 일반적이지만 여러 API 서버를 호출하는 시스템에서 다른 서비스의 로그를 확인하기 위해서는 약간 불편함(서버 인증, 담당자 확인 등등)이 있습니다.  이것 때문에 서버 로그를 확인하면 쉽게 해결할 수 있었던 것을 몇시간 소비한 다음에 해결하게 되었습니다.

  1. 문제가 발생하면 로그 부터 확인한다.
  2. 자신의 코드를 신뢰하지 마라.
  3. rails도 다 알아서 해주지는 않는다.


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.