utiliza sirven que peticion para metodos los llamadas ejemplos ejemplo como http io go

http - sirven - peticion post



¿Lectura del cuerpo de http.Request sin modificar el estado de la solicitud? (2)

Tengo un tipo que implementa la interfaz http.Handler donde, en su método ServeHTTP , se inspeccionan las solicitudes HTTP entrantes, se toman algunas medidas y luego las solicitudes se reenvían a un controlador proxy inverso ( httputil.NewSingleHostReverseProxy ).

Esto funciona bien, siempre que solo esté inspeccionando las propiedades de solicitud básicas, como la URL o los encabezados.

Cuando quiero inspeccionar el cuerpo de una solicitud POST entrante, por ejemplo, llamando a req.ParseForm() y luego usando la propiedad req.Form , me encuentro con un error una vez que la solicitud se pasa al proxy inverso:

http: proxy error: http: Request.ContentLength=687 with Body length 0

Me imagino que esto sucede porque mirar el cuerpo de la solicitud HTTP hace que se req.Body.Reader secuencia req.Body.Reader , lo que significa que el manejador de proxy no puede volver a leerla.

He estado jugando con cosas como io.Copy() y bufio.Peek() , pero realmente no estoy llegando a ningún lado.

¿Hay alguna manera de echar un vistazo al cuerpo de la solicitud HTTP (y usar el análisis req.ParseForm de req.ParseForm etc.), mientras se deja el objeto de solicitud original en su estado original, de modo que se pueda pasar al proxy inverso?


Intente leer en un búfer y luego use el búfer para respaldar a dos nuevos lectores, uno para que lo use y otro para que lo usen los consumidores posteriores. Por ejemplo, imagina que queremos modificar el siguiente código:

doStuff(r.Body) // r is an http.Request

Podríamos hacer:

buf, _ := ioutil.ReadAll(r.Body) rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf)) rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf)) doStuff(rdr1) r.Body = rdr2 // OK since rdr2 implements the io.ReadCloser interface // Now the program can continue oblivious to the fact that // r.Body was ever touched.

Tenga en cuenta que *bytes.Buffer no tiene un método de Close() error , por lo que no implementa la interfaz io.ReadCloser . Por lo tanto, tenemos que ajustar nuestros valores *bytes.Buffer en las llamadas a ioutil.NopCloser .


Utilicé un enfoque diferente a esto más recientemente. Hay un método GetBody disponible, a través del cual puede obtener una nueva copia del cuerpo de la solicitud, en lugar de hacerlo:

doStuff(r.Body)

En su lugar, podría hacer:

body, _ := r.GetBody() doStuff(body) // r.Body is unmodified

Esto le permite inspeccionar el cuerpo de la solicitud mientras la tiene disponible para continuar el procesamiento posterior