Home [삽질] 자꾸 예상치 못한 301 redirect가 일어날 때...
Post
Cancel

[삽질] 자꾸 예상치 못한 301 redirect가 일어날 때...

자꾸 예상치 못한 301 redirect가 일어날 때…

아니 분명 맞는데 왜 내 생각대로 코드가 안돌아가 - - ;;;;;

오늘 아래 코드를 돌리는데 "/bar"로 갈 때 bar.gohtml가 보여지도록 해주었는데 자꾸 index페이지로 돌아가는 것이었다…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func main() {
	http.HandleFunc("/", index)
	http.HandleFunc("/bar", bar)
	http.HandleFunc("/hello", hello)
	http.Handle("/favicon.ico", http.NotFoundHandler())
	http.ListenAndServe(":8080", nil)
}


func bar(w http.ResponseWriter, req *http.Request) {
	// get cookie
	c, err := req.Cookie("session")
	if err != nil {
		http.Redirect(w, req, "/", http.StatusSeeOther)
		return
	}
	un, ok := dbSessions[c.Value]
	if !ok {
		http.Redirect(w, req, "/", http.StatusSeeOther)
		return
	}
	u := dbUsers[un]
	tpl.ExecuteTemplate(w, "bar.gohtml", u)
}

아무리 봐도 코드는 잘못된게 없어보이는데 index로 redirect되는 이유를 찾지못하여 한참을 삽질하던 찰나에..
브라우저 개발자 도구에서 network탭을 살펴보니…!!!
/bar에서 301(moved permanently / from disk cache) 코드를 반환해주면서 /로 돌아가는 것을 확인했다.
그리고 뒤에 보이는 from disk cache…. 캐시라는 단어를 보자마자 “아 내가 혹시 이전에 설정해놓은 것이 캐시에 남아서 이렇게 되었나?” 라는 생각이 뇌리를 스쳤고, 이전에 redirect를 공부하며 짰던 코드를 보니 아니나 다를까… /bar/로 moved permanently redirect를 해주었던 것이 발견되었다..

1
2
3
4
func bar(w http.ResponseWriter, r *http.Request) {
	fmt.Println("Your request method at bar: ", r.Method)
	http.Redirect(w, r, "/", http.StatusMovedPermanently)
}

ㅂㄷㅂㄷ….

HTTP 캐시들은 보통 GET에 대한 응답만을 캐싱한다고 한다. 그래서 /bar에서 301을 반환해주는 get메소드를 캐싱하여 캐시에 남았고 그 후에 /bar에 접근할 때 캐시 리소스를 재사용하여 /로 redirect 되었던 것이었다.

해서 브라우저 설정에 들어가서 캐시를 삭제하고 나니 제대로 실행이 되었다!
하지만 매번 이렇게 캐시를 삭제할 수 는 없지 않을까? 예를들어 웹 서비스를 사용하는 유저들에게 “제대로 동작하지 않으면 캐시를 삭제하고 다시 시도해보세요.” 라는 메세지를 남길수도 없는 노릇이다.. 그래서 찾아보니 이럴 때는 HTTP 헤더Cache-control을 설정해주면 된다는 걸 알게되었다.

no-store => 캐시는 클라이언트 요청 혹은 서버 응답에 관해 아무것도 저장하지 않는다.
no-cache => 캐시된 복사본을 사용자에게 릴리즈 하기 전에 휴효성 확인을 위해 원 서버로 요청을 보낸다.

이 외에도 여러 값이 있는데 no-cache로 헤더를 지정해주면 오늘과 같은 상황을 해결해 줄 수 있다.
Golang에서는 아래 함수의 첫째줄과 같이 헤더를 설정해줄 수 있다.

1
2
3
4
5
func bar(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Cache-Control", "no-cache, private, max-age=0")
	fmt.Println("Your request method at bar: ", r.Method)
	http.Redirect(w, r, "/", http.StatusMovedPermanently)
}
This post is licensed under CC BY 4.0 by the author.

[Go] Golang에서의 쿠키

[Devlog] Go로 만드는 웹 (2): 회원가입, 로그인&아웃 기능 구현..!