Last active
April 30, 2025 12:28
-
-
Save spraints/42b3ec473655ce665f8c215bf6dcfe5e to your computer and use it in GitHub Desktop.
play with go http and sockets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module gist.github.com/spraints/42b3ec473655ce665f8c215bf6dcfe5e | |
go 1.22.2 | |
require ( | |
github.com/vishvananda/netlink v1.3.0 // indirect | |
github.com/vishvananda/netns v0.0.4 // indirect | |
golang.org/x/sys v0.10.0 // indirect | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk= | |
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= | |
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= | |
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= | |
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= | |
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"log" | |
) | |
func measureLink(ctx context.Context) { | |
log.Println("measureLink: disabled on darwin") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"log" | |
"syscall" | |
"time" | |
"github.com/vishvananda/netlink" | |
) | |
func measureLink(ctx context.Context) { | |
ticker := time.NewTicker(time.Second / 5) | |
defer ticker.Stop() | |
for { | |
select { | |
case <-ticker.C: | |
// yay! | |
case <-ctx.Done(): | |
log.Println("measureLink: done") | |
return | |
} | |
socks, err := netlink.SocketDiagTCP(syscall.AF_INET) | |
if err != nil { | |
log.Printf("measureLink: error getting sock diag: %v", err) | |
return | |
} | |
for _, sock := range socks { | |
saddr := fmt.Sprintf("%v:%v", sock.ID.Source, sock.ID.SourcePort) | |
daddr := fmt.Sprintf("%v:%v", sock.ID.Destination, sock.ID.DestinationPort) | |
log.Printf("%v -> %v", saddr, daddr) | |
return | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"io" | |
"log" | |
"net/http" | |
"os" | |
"sync" | |
"time" | |
) | |
const addr = "127.0.0.1:7373" | |
func main() { | |
defer log.Println("main: done") | |
var wg sync.WaitGroup | |
defer wg.Wait() | |
ctx, cancel := context.WithCancel(context.Background()) | |
defer cancel() | |
wg.Add(1) | |
go func() { defer wg.Done(); measureLink(ctx) }() | |
// Demonstrate that response isn't sent to client until the server's | |
// handler returns. | |
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) | |
srv := &http.Server{ | |
Addr: addr, | |
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
wg.Add(1) | |
defer wg.Done() | |
log.Println("server: request received") | |
// set CHUNKED=1 this to make the client receive the | |
// response headers before the sleep finishes. | |
// | |
// note the response still won't be completely finished | |
// until this func returns. | |
if os.Getenv("CHUNKED") == "1" { | |
if f, ok := w.(http.Flusher); ok { | |
f.Flush() | |
} | |
} | |
w.Write([]byte("Hello, world!")) | |
log.Println("server: response written") | |
time.Sleep(time.Second) | |
log.Println("server: response finished") | |
}), | |
} | |
go srv.ListenAndServe() | |
log.Println("client: sending request") | |
resp, err := http.Get("http://" + addr + "/") | |
if err != nil { | |
log.Println(err) | |
return | |
} | |
log.Printf("client: response received %v", resp.StatusCode) | |
io.Copy(os.Stdout, resp.Body) | |
log.Println("client: done!") | |
time.Sleep(time.Second) | |
cancel() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment