trace.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package http3
  2. import (
  3. "net"
  4. "net/http/httptrace"
  5. "net/textproto"
  6. "time"
  7. tls "github.com/Psiphon-Labs/psiphon-tls"
  8. "github.com/Psiphon-Labs/quic-go"
  9. )
  10. func traceGetConn(trace *httptrace.ClientTrace, hostPort string) {
  11. if trace != nil && trace.GetConn != nil {
  12. trace.GetConn(hostPort)
  13. }
  14. }
  15. // fakeConn is a wrapper for quic.EarlyConnection
  16. // because the quic connection does not implement net.Conn.
  17. type fakeConn struct {
  18. conn quic.EarlyConnection
  19. }
  20. func (c *fakeConn) Close() error { panic("connection operation prohibited") }
  21. func (c *fakeConn) Read(p []byte) (int, error) { panic("connection operation prohibited") }
  22. func (c *fakeConn) Write(p []byte) (int, error) { panic("connection operation prohibited") }
  23. func (c *fakeConn) SetDeadline(t time.Time) error { panic("connection operation prohibited") }
  24. func (c *fakeConn) SetReadDeadline(t time.Time) error { panic("connection operation prohibited") }
  25. func (c *fakeConn) SetWriteDeadline(t time.Time) error { panic("connection operation prohibited") }
  26. func (c *fakeConn) RemoteAddr() net.Addr { return c.conn.RemoteAddr() }
  27. func (c *fakeConn) LocalAddr() net.Addr { return c.conn.LocalAddr() }
  28. func traceGotConn(trace *httptrace.ClientTrace, conn quic.EarlyConnection, reused bool) {
  29. if trace != nil && trace.GotConn != nil {
  30. trace.GotConn(httptrace.GotConnInfo{
  31. Conn: &fakeConn{conn: conn},
  32. Reused: reused,
  33. })
  34. }
  35. }
  36. func traceGotFirstResponseByte(trace *httptrace.ClientTrace) {
  37. if trace != nil && trace.GotFirstResponseByte != nil {
  38. trace.GotFirstResponseByte()
  39. }
  40. }
  41. func traceGot1xxResponse(trace *httptrace.ClientTrace, code int, header textproto.MIMEHeader) {
  42. if trace != nil && trace.Got1xxResponse != nil {
  43. trace.Got1xxResponse(code, header)
  44. }
  45. }
  46. func traceGot100Continue(trace *httptrace.ClientTrace) {
  47. if trace != nil && trace.Got100Continue != nil {
  48. trace.Got100Continue()
  49. }
  50. }
  51. func traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool {
  52. return trace != nil && trace.WroteHeaderField != nil
  53. }
  54. func traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {
  55. if trace != nil && trace.WroteHeaderField != nil {
  56. trace.WroteHeaderField(k, []string{v})
  57. }
  58. }
  59. func traceWroteHeaders(trace *httptrace.ClientTrace) {
  60. if trace != nil && trace.WroteHeaders != nil {
  61. trace.WroteHeaders()
  62. }
  63. }
  64. func traceWroteRequest(trace *httptrace.ClientTrace, err error) {
  65. if trace != nil && trace.WroteRequest != nil {
  66. trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
  67. }
  68. }
  69. func traceConnectStart(trace *httptrace.ClientTrace, network, addr string) {
  70. if trace != nil && trace.ConnectStart != nil {
  71. trace.ConnectStart(network, addr)
  72. }
  73. }
  74. func traceConnectDone(trace *httptrace.ClientTrace, network, addr string, err error) {
  75. if trace != nil && trace.ConnectDone != nil {
  76. trace.ConnectDone(network, addr, err)
  77. }
  78. }
  79. func traceTLSHandshakeStart(trace *httptrace.ClientTrace) {
  80. if trace != nil && trace.TLSHandshakeStart != nil {
  81. trace.TLSHandshakeStart()
  82. }
  83. }
  84. func traceTLSHandshakeDone(trace *httptrace.ClientTrace, state tls.ConnectionState, err error) {
  85. if trace != nil && trace.TLSHandshakeDone != nil {
  86. // [Psiphon]
  87. state := *tls.UnsafeFromConnectionState(&state)
  88. trace.TLSHandshakeDone(state, err)
  89. }
  90. }