2015-01-16 26 views
5

Probabilmente c'è qualcosa di ovvio che mi manca ma sto provando a eseguire il debug della risposta HTTP scritta dal mio server go.In go, come ispezionare la risposta http scritta su http.ResponseWriter?

vedo che c'è httputil.DumpResponse a disposizione, ma ci vuole un oggetto http.Response e quello che ho a disposizione è http.ResponseWriter

C'è un modo per estrarre il http.Response da http.ResponseWriter in modo da poter ispezionare il contenuto della risposta alla console o al log?

Contesto:

Sto scrivendo un'autenticazione del server-side semplice utilizzando https://github.com/RangelReale/osin ed è esempio di default, ma non riuscivo a capire perché il front-end (utilizzando http://ember-simple-auth.com) interpreta un'autenticazione fallita (password errata) come successo .

Ecco il frammento di codice:

r = mux.NewRouter() 
r.HandleFunc("/token", func (w http.ResponseWriter, r *http.Request) { 

    fmt.Printf("r.HandleFunc /token\n") 

    resp := server.NewResponse() 
    defer resp.Close() 

    r.ParseForm() 

    grantType := r.FormValue("grant_type") 
    username := r.FormValue("username") 
    password := r.FormValue("password") 
    fmt.Printf("/token : grantType=%s username=%s password=%s\n", grantType, username, password) 

    if ar := server.HandleAccessRequest(resp, r); ar != nil { 
     if username == "user" && password == "correct-password" { 
      ar.Authorized = true 
     } else { 
      ar.Authorized = false 
     } 
     server.FinishAccessRequest(resp, r, ar) 
    } 

    osin.OutputJSON(resp, w, r) 

    // Debug - doesn't work yet 
    dump, err := httputil.DumpResponse(w, true) 
    if err != nil { 
     fmt.Printf("%s\n", dump) 
    } 
}); 
http.Handle("/token", r) 

risposta

5

Scrivi un *httptest.ResponseRecorder (che implementa http.ResponseWriter) e controllarla.

Esempio dal pacchetto:

package main 

import (
    "fmt" 
    "log" 
    "net/http" 
    "net/http/httptest" 
) 

func main() { 
    handler := func(w http.ResponseWriter, r *http.Request) { 
     http.Error(w, "something failed", http.StatusInternalServerError) 
    } 

    req, err := http.NewRequest("GET", "http://example.com/foo", nil) 
    if err != nil { 
     log.Fatal(err) 
    } 

    w := httptest.NewRecorder() 
    handler(w, req) 

    fmt.Printf("%d - %s", w.Code, w.Body.String()) 
} 

Modifica di rispondere alla domanda nei commenti:

Se ho capito bene la tua domanda, allora sì, si può fare uso di chiusure per questo.

Si consideri il seguente per essere il vostro gestore:

func MyHandler(w http.ResponseWriter, r *http.Request) { 
    // do useful stuff... 
} 

si potrebbe quindi registrare il seguente chiusura con il servemux per raggiungere l'effetto desiderato:

http.HandleFunc("/my/url", func(w http.ResponseWriter, r *http.Request) { 
    // first call MyHandler 
    MyHandler(w, r) 

    // then log whatever you need 
    log.Printf("%#v\n", w) 
}) 

Se questo modello si rivela utile a voi allora è possibile scrivere un metodo di ordine superiore che avvolge qualsiasi func(http.ResponseWriter, *http.Request) in tale chiusura. Questo è un argomento per sé, però.

+0

Grazie per il frammento. Usando quell'esempio insieme al refactoring del mio codice, sono riuscito ad agganciare il mio gestore esistente a un httptest.Recorder. Tuttavia, è possibile semplicemente inserire un'istruzione di registro alla fine del func (w http.ResponseWriter, r * http.Request) stesso gestore? In questo modo posso tenere traccia delle risposte mentre interagisco con esso su un browser. –

+0

@zaichang Ho modificato la mia risposta per rispondere alla tua domanda. – thwd

+0

Grazie THWD, l'output che ottengo è qualcosa di simile a '& http.response {conn: (* http.conn) (0xc208048000), req: (* http.Request) (0xc2080268f0), wroteHeader: vero, wroteContinue: false, w: (* bufio.Writer) (0xc208044580), CW: http.chunkWriter {res: (*) (http.response 0xc20804ab40), .......... dateBuf: [29] uint8 {0x0, 0x0, 0x0 , 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 , 0x0}, clenBuf: [10] uint8 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}} 'che sembra una discarica oggetto e io non riesco a capire come ottenere a il corpo del messaggio json. –

Problemi correlati