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  )
    16  
    17  func ExampleHijacker() {
    18  	http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
    19  		hj, ok := w.(http.Hijacker)
    20  		if !ok {
    21  			http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
    22  			return
    23  		}
    24  		conn, bufrw, err := hj.Hijack()
    25  		if err != nil {
    26  			http.Error(w, err.Error(), http.StatusInternalServerError)
    27  			return
    28  		}
    29  		// Don't forget to close the connection:
    30  		defer conn.Close()
    31  		bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
    32  		bufrw.Flush()
    33  		s, err := bufrw.ReadString('\n')
    34  		if err != nil {
    35  			log.Printf("error reading string: %v", err)
    36  			return
    37  		}
    38  		fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
    39  		bufrw.Flush()
    40  	})
    41  }
    42  
    43  func ExampleGet() {
    44  	res, err := http.Get("http://www.google.com/robots.txt")
    45  	if err != nil {
    46  		log.Fatal(err)
    47  	}
    48  	body, err := io.ReadAll(res.Body)
    49  	res.Body.Close()
    50  	if res.StatusCode > 299 {
    51  		log.Fatalf("Response failed with status code: %d and\nbody: %s\n", res.StatusCode, body)
    52  	}
    53  	if err != nil {
    54  		log.Fatal(err)
    55  	}
    56  	fmt.Printf("%s", body)
    57  }
    58  
    59  func ExampleFileServer() {
    60  	// Simple static webserver:
    61  	log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))
    62  }
    63  
    64  func ExampleFileServer_stripPrefix() {
    65  	// To serve a directory on disk (/tmp) under an alternate URL
    66  	// path (/tmpfiles/), use StripPrefix to modify the request
    67  	// URL's path before the FileServer sees it:
    68  	http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
    69  }
    70  
    71  func ExampleStripPrefix() {
    72  	// To serve a directory on disk (/tmp) under an alternate URL
    73  	// path (/tmpfiles/), use StripPrefix to modify the request
    74  	// URL's path before the FileServer sees it:
    75  	http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
    76  }
    77  
    78  type apiHandler struct{}
    79  
    80  func (apiHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}
    81  
    82  func ExampleServeMux_Handle() {
    83  	mux := http.NewServeMux()
    84  	mux.Handle("/api/", apiHandler{})
    85  	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    86  		// The "/" pattern matches everything, so we need to check
    87  		// that we're at the root here.
    88  		if req.URL.Path != "/" {
    89  			http.NotFound(w, req)
    90  			return
    91  		}
    92  		fmt.Fprintf(w, "Welcome to the home page!")
    93  	})
    94  }
    95  
    96  // HTTP Trailers are a set of key/value pairs like headers that come
    97  // after the HTTP response, instead of before.
    98  func ExampleResponseWriter_trailers() {
    99  	mux := http.NewServeMux()
   100  	mux.HandleFunc("/sendstrailers", func(w http.ResponseWriter, req *http.Request) {
   101  		// Before any call to WriteHeader or Write, declare
   102  		// the trailers you will set during the HTTP
   103  		// response. These three headers are actually sent in
   104  		// the trailer.
   105  		w.Header().Set("Trailer", "AtEnd1, AtEnd2")
   106  		w.Header().Add("Trailer", "AtEnd3")
   107  
   108  		w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
   109  		w.WriteHeader(http.StatusOK)
   110  
   111  		w.Header().Set("AtEnd1", "value 1")
   112  		io.WriteString(w, "This HTTP response has both headers before this text and trailers at the end.\n")
   113  		w.Header().Set("AtEnd2", "value 2")
   114  		w.Header().Set("AtEnd3", "value 3") // These will appear as trailers.
   115  	})
   116  }
   117  
   118  func ExampleServer_Shutdown() {
   119  	var srv http.Server
   120  
   121  	idleConnsClosed := make(chan struct{})
   122  	go func() {
   123  		sigint := make(chan os.Signal, 1)
   124  		signal.Notify(sigint, os.Interrupt)
   125  		<-sigint
   126  
   127  		// We received an interrupt signal, shut down.
   128  		if err := srv.Shutdown(context.Background()); err != nil {
   129  			// Error from closing listeners, or context timeout:
   130  			log.Printf("HTTP server Shutdown: %v", err)
   131  		}
   132  		close(idleConnsClosed)
   133  	}()
   134  
   135  	if err := srv.ListenAndServe(); err != http.ErrServerClosed {
   136  		// Error starting or closing listener:
   137  		log.Fatalf("HTTP server ListenAndServe: %v", err)
   138  	}
   139  
   140  	<-idleConnsClosed
   141  }
   142  
   143  func ExampleListenAndServeTLS() {
   144  	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
   145  		io.WriteString(w, "Hello, TLS!\n")
   146  	})
   147  
   148  	// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
   149  	log.Printf("About to listen on 8443. Go to https://127.0.0.1:8443/")
   150  	err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
   151  	log.Fatal(err)
   152  }
   153  
   154  func ExampleListenAndServe() {
   155  	// Hello world, the web server
   156  
   157  	helloHandler := func(w http.ResponseWriter, req *http.Request) {
   158  		io.WriteString(w, "Hello, world!\n")
   159  	}
   160  
   161  	http.HandleFunc("/hello", helloHandler)
   162  	log.Fatal(http.ListenAndServe(":8080", nil))
   163  }
   164  
   165  func ExampleHandleFunc() {
   166  	h1 := func(w http.ResponseWriter, _ *http.Request) {
   167  		io.WriteString(w, "Hello from a HandleFunc #1!\n")
   168  	}
   169  	h2 := func(w http.ResponseWriter, _ *http.Request) {
   170  		io.WriteString(w, "Hello from a HandleFunc #2!\n")
   171  	}
   172  
   173  	http.HandleFunc("/", h1)
   174  	http.HandleFunc("/endpoint", h2)
   175  
   176  	log.Fatal(http.ListenAndServe(":8080", nil))
   177  }
   178  
   179  func newPeopleHandler() http.Handler {
   180  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   181  		fmt.Fprintln(w, "This is the people handler.")
   182  	})
   183  }
   184  
   185  func ExampleNotFoundHandler() {
   186  	mux := http.NewServeMux()
   187  
   188  	// Create sample handler to returns 404
   189  	mux.Handle("/resources", http.NotFoundHandler())
   190  
   191  	// Create sample handler that returns 200
   192  	mux.Handle("/resources/people/", newPeopleHandler())
   193  
   194  	log.Fatal(http.ListenAndServe(":8080", mux))
   195  }
   196  

View as plain text