1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
package fasthttp_test
import (
"fmt"
"log"
"math/rand"
"net"
"time"
"github.com/valyala/fasthttp"
)
func ExampleListenAndServe() {
// The server will listen for incoming requests on this address.
listenAddr := "127.0.0.1:80"
// This function will be called by the server for each incoming request.
//
// RequestCtx provides a lot of functionality related to http request
// processing. See RequestCtx docs for details.
requestHandler := func(ctx *fasthttp.RequestCtx) {
fmt.Fprintf(ctx, "Hello, world! Requested path is %q", ctx.Path())
}
// Start the server with default settings.
// Create Server instance for adjusting server settings.
//
// ListenAndServe returns only on error, so usually it blocks forever.
if err := fasthttp.ListenAndServe(listenAddr, requestHandler); err != nil {
log.Fatalf("error in ListenAndServe: %v", err)
}
}
func ExampleServe() {
// Create network listener for accepting incoming requests.
//
// Note that you are not limited by TCP listener - arbitrary
// net.Listener may be used by the server.
// For example, unix socket listener or TLS listener.
ln, err := net.Listen("tcp4", "127.0.0.1:8080")
if err != nil {
log.Fatalf("error in net.Listen: %v", err)
}
// This function will be called by the server for each incoming request.
//
// RequestCtx provides a lot of functionality related to http request
// processing. See RequestCtx docs for details.
requestHandler := func(ctx *fasthttp.RequestCtx) {
fmt.Fprintf(ctx, "Hello, world! Requested path is %q", ctx.Path())
}
// Start the server with default settings.
// Create Server instance for adjusting server settings.
//
// Serve returns on ln.Close() or error, so usually it blocks forever.
if err := fasthttp.Serve(ln, requestHandler); err != nil {
log.Fatalf("error in Serve: %v", err)
}
}
func ExampleServer() {
// This function will be called by the server for each incoming request.
//
// RequestCtx provides a lot of functionality related to http request
// processing. See RequestCtx docs for details.
requestHandler := func(ctx *fasthttp.RequestCtx) {
fmt.Fprintf(ctx, "Hello, world! Requested path is %q", ctx.Path())
}
// Create custom server.
s := &fasthttp.Server{
Handler: requestHandler,
// Every response will contain 'Server: My super server' header.
Name: "My super server",
// Other Server settings may be set here.
}
// Start the server listening for incoming requests on the given address.
//
// ListenAndServe returns only on error, so usually it blocks forever.
if err := s.ListenAndServe("127.0.0.1:80"); err != nil {
log.Fatalf("error in ListenAndServe: %v", err)
}
}
func ExampleRequestCtx_Hijack() {
// hijackHandler is called on hijacked connection.
hijackHandler := func(c net.Conn) {
fmt.Fprintf(c, "This message is sent over a hijacked connection to the client %s\n", c.RemoteAddr())
fmt.Fprintf(c, "Send me something and I'll echo it to you\n")
var buf [1]byte
for {
if _, err := c.Read(buf[:]); err != nil {
log.Printf("error when reading from hijacked connection: %v", err)
return
}
fmt.Fprintf(c, "You sent me %q. Waiting for new data\n", buf[:])
}
}
// requestHandler is called for each incoming request.
requestHandler := func(ctx *fasthttp.RequestCtx) {
path := ctx.Path()
switch {
case string(path) == "/hijack":
// Note that the connection is hijacked only after
// returning from requestHandler and sending http response.
ctx.Hijack(hijackHandler)
// The connection will be hijacked after sending this response.
fmt.Fprintf(ctx, "Hijacked the connection!")
case string(path) == "/":
fmt.Fprintf(ctx, "Root directory requested")
default:
fmt.Fprintf(ctx, "Requested path is %q", path)
}
}
if err := fasthttp.ListenAndServe(":80", requestHandler); err != nil {
log.Fatalf("error in ListenAndServe: %v", err)
}
}
func ExampleRequestCtx_TimeoutError() {
requestHandler := func(ctx *fasthttp.RequestCtx) {
// Emulate long-running task, which touches ctx.
doneCh := make(chan struct{})
go func() {
workDuration := time.Millisecond * time.Duration(rand.Intn(2000))
time.Sleep(workDuration)
fmt.Fprintf(ctx, "ctx has been accessed by long-running task\n")
fmt.Fprintf(ctx, "The requestHandler may be finished by this time.\n")
close(doneCh)
}()
select {
case <-doneCh:
fmt.Fprintf(ctx, "The task has been finished in less than a second")
case <-time.After(time.Second):
// Since the long-running task is still running and may access ctx,
// we must call TimeoutError before returning from requestHandler.
//
// Otherwise the program will suffer from data races.
ctx.TimeoutError("Timeout!")
}
}
if err := fasthttp.ListenAndServe(":80", requestHandler); err != nil {
log.Fatalf("error in ListenAndServe: %v", err)
}
}
func ExampleRequestCtx_Logger() {
requestHandler := func(ctx *fasthttp.RequestCtx) {
if string(ctx.Path()) == "/top-secret" {
ctx.Logger().Printf("Alarm! Alien intrusion detected!")
ctx.Error("Access denied!", fasthttp.StatusForbidden)
return
}
// Logger may be cached in local variables.
logger := ctx.Logger()
logger.Printf("Good request from User-Agent %q", ctx.Request.Header.UserAgent())
fmt.Fprintf(ctx, "Good request to %q", ctx.Path())
logger.Printf("Multiple log messages may be written during a single request")
}
if err := fasthttp.ListenAndServe(":80", requestHandler); err != nil {
log.Fatalf("error in ListenAndServe: %v", err)
}
}
|