Source file src/net/http/example_test.go

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package http_test
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  	"io"
    11  	"log"
    12  	"net/http"
    13  	"os"
    14  	"os/signal"
    15  	"time"
    16  )
    17  
    18  func ExampleHijacker() {
    19  	http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
    20  		hj, ok := w.(http.Hijacker)
    21  		if !ok {
    22  			http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
    23  			return
    24  		}
    25  		conn, bufrw, err := hj.Hijack()
    26  		if err != nil {
    27  			http.Error(w, err.Error(), http.StatusInternalServerError)
    28  			return
    29  		}
    30  		// Don't forget to close the connection:
    31  		defer conn.Close()
    32  		bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
    33  		bufrw.Flush()
    34  		s, err := bufrw.ReadString('\n')
    35  		if err != nil {
    36  			log.Printf("error reading string: %v", err)
    37  			return
    38  		}
    39  		fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
    40  		bufrw.Flush()
    41  	})
    42  }
    43  
    44  func ExampleGet() {
    45  	res, err := http.Get("http://www.google.com/robots.txt")
    46  	if err != nil {
    47  		log.Fatal(err)
    48  	}
    49  	body, err := io.ReadAll(res.Body)
    50  	res.Body.Close()
    51  	if res.StatusCode > 299 {
    52  		log.Fatalf("Response failed with status code: %d and\nbody: %s\n", res.StatusCode, body)
    53  	}
    54  	if err != nil {
    55  		log.Fatal(err)
    56  	}
    57  	fmt.Printf("%s", body)
    58  }
    59  
    60  // Simple static webserver.
    61  func ExampleFileServerFS() {
    62  	// os.Root blocks following symlinks that lead outside of /usr/share/doc.
    63  	root, err := os.OpenRoot("/usr/share/doc")
    64  	if err != nil {
    65  		log.Fatal(err)
    66  	}
    67  	handler := http.FileServerFS(root.FS())
    68  	log.Fatal(http.ListenAndServe(":8080", handler))
    69  }
    70  
    71  // Serving a directory on disk (/usr/share/doc) under an alternate URL path (/docs/).
    72  func ExampleFileServerFS_stripPrefix() {
    73  	root, err := os.OpenRoot("/usr/share/doc")
    74  	if err != nil {
    75  		log.Fatal(err)
    76  	}
    77  	handler := http.FileServerFS(root.FS())
    78  
    79  	// Use StripPrefix to remove the /docs/ prefix from the path before
    80  	// FileServerFS sees it.
    81  	http.Handle("GET /docs/", http.StripPrefix("/docs/", handler))
    82  }
    83  
    84  func ExampleStripPrefix() {
    85  	root, err := os.OpenRoot("/usr/share/doc")
    86  	if err != nil {
    87  		log.Fatal(err)
    88  	}
    89  	handler := http.FileServerFS(root.FS())
    90  
    91  	// To serve a directory on disk (/usr/share/doc) under an alternate URL
    92  	// path (/docs/), use StripPrefix to modify the request
    93  	// before FileServerFS sees it.
    94  	http.Handle("GET /docs/", http.StripPrefix("/docs/", handler))
    95  }
    96  
    97  type apiHandler struct{}
    98  
    99  func (apiHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}
   100  
   101  func ExampleServeMux_Handle() {
   102  	mux := http.NewServeMux()
   103  	mux.Handle("/api/", apiHandler{})
   104  	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
   105  		// The "/" pattern matches everything, so we need to check
   106  		// that we're at the root here.
   107  		if req.URL.Path != "/" {
   108  			http.NotFound(w, req)
   109  			return
   110  		}
   111  		fmt.Fprintf(w, "Welcome to the home page!")
   112  	})
   113  }
   114  
   115  // HTTP Trailers are a set of key/value pairs like headers that come
   116  // after the HTTP response, instead of before.
   117  func ExampleResponseWriter_trailers() {
   118  	mux := http.NewServeMux()
   119  	mux.HandleFunc("/sendstrailers", func(w http.ResponseWriter, req *http.Request) {
   120  		// Before any call to WriteHeader or Write, declare
   121  		// the trailers you will set during the HTTP
   122  		// response. These three headers are actually sent in
   123  		// the trailer.
   124  		w.Header().Set("Trailer", "AtEnd1, AtEnd2")
   125  		w.Header().Add("Trailer", "AtEnd3")
   126  
   127  		w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
   128  		w.WriteHeader(http.StatusOK)
   129  
   130  		w.Header().Set("AtEnd1", "value 1")
   131  		io.WriteString(w, "This HTTP response has both headers before this text and trailers at the end.\n")
   132  		w.Header().Set("AtEnd2", "value 2")
   133  		w.Header().Set("AtEnd3", "value 3") // These will appear as trailers.
   134  	})
   135  }
   136  
   137  func ExampleServer_Shutdown() {
   138  	var srv http.Server
   139  
   140  	idleConnsClosed := make(chan struct{})
   141  	go func() {
   142  		sigint := make(chan os.Signal, 1)
   143  		signal.Notify(sigint, os.Interrupt)
   144  		<-sigint
   145  
   146  		// We received an interrupt signal, shut down.
   147  		if err := srv.Shutdown(context.Background()); err != nil {
   148  			// Error from closing listeners, or context timeout:
   149  			log.Printf("HTTP server Shutdown: %v", err)
   150  		}
   151  		close(idleConnsClosed)
   152  	}()
   153  
   154  	if err := srv.ListenAndServe(); err != http.ErrServerClosed {
   155  		// Error starting or closing listener:
   156  		log.Fatalf("HTTP server ListenAndServe: %v", err)
   157  	}
   158  
   159  	<-idleConnsClosed
   160  }
   161  
   162  func ExampleListenAndServeTLS() {
   163  	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
   164  		io.WriteString(w, "Hello, TLS!\n")
   165  	})
   166  
   167  	// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
   168  	log.Printf("About to listen on 8443. Go to https://127.0.0.1:8443/")
   169  	err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
   170  	log.Fatal(err)
   171  }
   172  
   173  func ExampleListenAndServe() {
   174  	// Hello world, the web server
   175  
   176  	helloHandler := func(w http.ResponseWriter, req *http.Request) {
   177  		io.WriteString(w, "Hello, world!\n")
   178  	}
   179  
   180  	http.HandleFunc("/hello", helloHandler)
   181  	log.Fatal(http.ListenAndServe(":8080", nil))
   182  }
   183  
   184  func ExampleHandleFunc() {
   185  	h1 := func(w http.ResponseWriter, _ *http.Request) {
   186  		io.WriteString(w, "Hello from a HandleFunc #1!\n")
   187  	}
   188  	h2 := func(w http.ResponseWriter, _ *http.Request) {
   189  		io.WriteString(w, "Hello from a HandleFunc #2!\n")
   190  	}
   191  
   192  	http.HandleFunc("/", h1)
   193  	http.HandleFunc("/endpoint", h2)
   194  
   195  	log.Fatal(http.ListenAndServe(":8080", nil))
   196  }
   197  
   198  func newPeopleHandler() http.Handler {
   199  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   200  		fmt.Fprintln(w, "This is the people handler.")
   201  	})
   202  }
   203  
   204  func ExampleNotFoundHandler() {
   205  	mux := http.NewServeMux()
   206  
   207  	// Create sample handler to returns 404
   208  	mux.Handle("/resources", http.NotFoundHandler())
   209  
   210  	// Create sample handler that returns 200
   211  	mux.Handle("/resources/people/", newPeopleHandler())
   212  
   213  	log.Fatal(http.ListenAndServe(":8080", mux))
   214  }
   215  
   216  func ExampleProtocols_http1() {
   217  	srv := http.Server{
   218  		Addr: ":8443",
   219  	}
   220  
   221  	// Serve only HTTP/1.
   222  	srv.Protocols = new(http.Protocols)
   223  	srv.Protocols.SetHTTP1(true)
   224  
   225  	log.Fatal(srv.ListenAndServeTLS("cert.pem", "key.pem"))
   226  }
   227  
   228  func ExampleProtocols_http1or2() {
   229  	t := http.DefaultTransport.(*http.Transport).Clone()
   230  
   231  	// Use either HTTP/1 or HTTP/2.
   232  	t.Protocols = new(http.Protocols)
   233  	t.Protocols.SetHTTP1(true)
   234  	t.Protocols.SetHTTP2(true)
   235  
   236  	cli := &http.Client{Transport: t}
   237  	res, err := cli.Get("http://www.google.com/robots.txt")
   238  	if err != nil {
   239  		log.Fatal(err)
   240  	}
   241  	res.Body.Close()
   242  }
   243  
   244  func ExampleCrossOriginProtection() {
   245  	mux := http.NewServeMux()
   246  
   247  	mux.HandleFunc("/hello", func(w http.ResponseWriter, req *http.Request) {
   248  		io.WriteString(w, "request allowed\n")
   249  	})
   250  
   251  	srv := http.Server{
   252  		Addr:         ":8080",
   253  		ReadTimeout:  15 * time.Second,
   254  		WriteTimeout: 15 * time.Second,
   255  		// Use CrossOriginProtection.Handler to block all non-safe cross-origin
   256  		// browser requests to mux.
   257  		Handler: http.NewCrossOriginProtection().Handler(mux),
   258  	}
   259  
   260  	log.Fatal(srv.ListenAndServe())
   261  }
   262  

View as plain text