2017-11-24 10 views
0

http 경로 처리에 golang의 기본값 인 http.ServeMux을 사용하고 있습니다. 요청 경로에 추가 슬래시가 포함 된 경우 Golang "301 Moved Permanently"

wrap := func(h func(t *MyStruct, w http.ResponseWriter, r *http.Request)) func(http.ResponseWriter, *http.Request) { 
    return func(w http.ResponseWriter, r *http.Request) { 
     h(t, w, r) 
    } 
} 

// Register handlers with default mux 
httpMux := http.NewServeMux() 
httpMux.HandleFunc("/", wrap(payloadHandler)) 

이 서버 내 클라이언트의 요청 http://example.com/

거의가 301 Moved Permanently로 리디렉션 경로 http://example.com/api//module (여분의 슬래시주의)로 있었다를 통해 액세스 할 수있는 가정합니다. golang의 http ServeMux.Handler(r *Request) 기능을 탐색하는 것은 의도 된 것 같습니다.

path := cleanPath(r.URL.Path) 
// if there is any change between actual and cleaned path, the request is 301 ed 
if path != r.URL.Path { 
    _, pattern = mux.handler(host, path) 
    url := *r.URL 
    url.Path = path 
    return RedirectHandler(url.String(), StatusMovedPermanently), pattern 
} 

다른 유사한 문제가 있습니다. QN 위

go-web-server-is-automatically-redirecting-post-requests

레지스터 패턴 자체 중복 /에 문제가있다,하지만 내 사용 사례가 있기 때문에,

문제가 (패턴을 등록 할 의미도 없습니다 일부 중첩 된 경로에) 레지스터 패턴으로하지 않습니다 제 의뢰인의 요청은 POST이고, 브라우저는 정확하게 GET 요청과 정확한 검색어 매개 변수 및 POST 본문이 포함 된 301을 처리합니다. 그러나 HTTP 메소드를 변경하면 요청이 실패하게됩니다.

URL에 중복 /을 수정하도록 고객에게 이미 지시했지만 수정 사항을 모든 클라이언트 위치에 배포하는 데 몇 주가 걸릴 수 있습니다.

/Apache Tomcat에서 정상적으로 처리되지만 golang 서버에서만 오류가 발생합니다. 그렇다면 golang 또는 가능한 버그가있는 사용 사례 (중복 된 / 중첩 경로)의 의도 된 동작입니까?

ServeMuxHandler 기능을 무시하는 방법을 생각하고 있지만 Handler 호출이 내부적으로 이루어 지므로 유용하지 않습니다. 이 301 행동을 사용하지 않으려면 도움을 받으실 수 있습니다.

관련 링크

http-post-method-is-actally-sending-a-get

답변

1

깨끗하고 리디렉션이 동작을위한 것입니다.

랩 이중 슬래시 제거하는 핸들러와 MUX :

type slashFix struct { 
    mux http.Handler 
} 

func (h *slashFix) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    r.URL.Path = strings.Replace(r.URL.Path, "//", "/", -1) 
    h.mux.ServeHTTP(w, r) 
} 

이처럼 사용

httpMux := http.NewServeMux() 
httpMux.HandleFunc("/", wrap(payloadHandler)) 
http.ListenAndServe(addr, &fixSlash{httpMux}) 
+0

처음에 나는 Gorilla Mux와 함께 spiked. 그러나 이것을보고 난 후에.. 나의 날을 만들었다. ..! –

0

Accepeted의 대답은 문제를 해결을

또 하나의 방법입니다 Gorilla mux을 사용하고 SkipClean(true)으로 설정하십시오. 그러나 그 부작용에 대해 반드시 알아야합니다.

SkipClean은 새 경로에 대한 경로 정리 동작을 정의합니다. 초기 값은 false입니다. 사용자는 어떤 경로가 정리되지 않았는지주의해야합니다. 참이면 경로 경로가 "/ path // to"이면 이중 슬래시로 남습니다.당신이 경로 같은 경우에 유용합니다 :/가져 오기// http://xkcd.com/534/

때 잘못된 경로를 청소해야합니다 가져 오기, 정도/http://xkcd.com/534/이 될 것입니다 /fetch/http/xkcd.com/534

func (r *Router) SkipClean(value bool) *Router { 
    r.skipClean = value 
    return r 
}