Skip to content

Instantly share code, notes, and snippets.

@erikdubbelboer
Created November 9, 2019 12:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erikdubbelboer/81a1f23be935e5b764506f728f021423 to your computer and use it in GitHub Desktop.
Save erikdubbelboer/81a1f23be935e5b764506f728f021423 to your computer and use it in GitHub Desktop.
Example of how fasthttp might get corrupted with fasthttp
package main
import (
"bytes"
"math/rand"
"net"
"time"
"github.com/valyala/fasthttp"
)
func main() {
var b []byte
s := &fasthttp.Server{
Handler: func(ctx *fasthttp.RequestCtx) {
if b == nil {
// Keeping a reference to a header after the request ended is a bad idea!
// If you need to do this copy() the value.
b = ctx.Request.Header.Peek("X-Test")
} else if s := string(ctx.Request.Header.Peek("X-Test")); s != "foobar" {
println(s)
}
},
}
rw := &readWriter{}
rw.r.Grow(1024)
rw.w.Grow(1024)
rw.r.WriteString("GET / HTTP/1.1\r\nHost: google.com\r\nX-Test: foobar\r\n\r\n")
if err := s.ServeConn(rw); err != nil {
panic(err)
}
// Reset the write buffer to make space for the next response.
rw.w.Reset()
go func() {
for {
// We are always writing "foobar"
rw.r.WriteString("GET / HTTP/1.1\r\nHost: google.com\r\nX-Test: foobar\r\n\r\n")
if err := s.ServeConn(rw); err != nil {
panic(err)
}
// Reset the write buffer to make space for the next response.
rw.w.Reset()
time.Sleep(time.Millisecond)
}
}()
for {
// Change the first byte of the header that we kept to a random character between a and z.
b[0] = 'a' + byte(rand.Intn('z'-'a'))
time.Sleep(time.Microsecond)
}
}
var zeroTCPAddr = &net.TCPAddr{
IP: net.IPv4zero,
}
type readWriter struct {
net.Conn
r bytes.Buffer
w bytes.Buffer
}
func (rw *readWriter) Close() error {
return nil
}
func (rw *readWriter) Read(b []byte) (int, error) {
return rw.r.Read(b)
}
func (rw *readWriter) Write(b []byte) (int, error) {
return rw.w.Write(b)
}
func (rw *readWriter) RemoteAddr() net.Addr {
return zeroTCPAddr
}
func (rw *readWriter) LocalAddr() net.Addr {
return zeroTCPAddr
}
func (rw *readWriter) SetReadDeadline(t time.Time) error {
return nil
}
func (rw *readWriter) SetWriteDeadline(t time.Time) error {
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment