Я создал маршрутизатор с расширенными возможностями ведения журнала, используя Go.Это работает правильно для большинства случаев использования.Однако возникают проблемы, когда клиенты отправляют нестандартные HTTP-сообщения через порт 80.
На сегодняшний день я решил эту проблему, внедрив собственную версию ServeHTTP ():
func (myproxy *MyProxy) ServeHTTP(w http.ResponseWtier, r *http.Request) {
// Inspect headers
// Determine if it is a custom protocol (ie: websockets, CONNECT requests)
// Implement handlers for each time
}
Всобытие, в котором я определяю запрос, является нестандартным протоколом HTTP, запрос воспроизводится в исходное место назначения (через http.Request.Write ()), и все довольны.
По крайней мере, большинство извремя.Проблема возникает с крайними случаями.Клиенты Tivo не отправляют заголовки «Host» и, похоже, не любят все другие стандартные вещи, которые делает Go (например, использование заглавных букв в заголовках).Количество возможных вариантов этого бесконечно, поэтому я бы очень хотел сделать буферизацию исходного запроса - в точности так, как он был отправлен мне без каких-либо изменений, - и воспроизвести его обратно на исходный целевой сервер.
Я мог бы взломать это, повторно внедрив net.Http.Server, но это кажется чрезвычайно сложным и хрупким подходом.Я бы предпочел сделать это, как-то подключиться к net / http / http / server.go прямо вокруг точки, где он получает соединение, а затем обернуть это в шпионскую оболочку, которая записывает запрос в буфер.
func (srv *Server) Serve(l net.Listener) error {
// Lots of listener code...
c := srv.newConn(rw)
c.setState(c.rwc, StateNew) // before Serve can return
// I'd like to wrap c here and save the request for possible reply later.
go c.serve(ctx)
}
https://golang.org/src/net/http/server.go?s=93229:93284#L2805
Редактировать: Я смотрел на httpUtil: DumpRequest, но это немного изменяет исходный запрос (изменяет регистр и порядок заголовков).Если бы это не было сделано, это было бы идеальным решением.
https://godoc.org/net/http/httputil#DumpRequest
Есть ли способ перехватить соединения вокруг этой точки, прежде чем они будут проанализированы http.Request?