Home | History | Annotate | Download | only in http
      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 	"io/ioutil"
     12 	"log"
     13 	"net/http"
     14 	"os"
     15 	"os/signal"
     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 	robots, err := ioutil.ReadAll(res.Body)
     50 	res.Body.Close()
     51 	if err != nil {
     52 		log.Fatal(err)
     53 	}
     54 	fmt.Printf("%s", robots)
     55 }
     56 
     57 func ExampleFileServer() {
     58 	// Simple static webserver:
     59 	log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))
     60 }
     61 
     62 func ExampleFileServer_stripPrefix() {
     63 	// To serve a directory on disk (/tmp) under an alternate URL
     64 	// path (/tmpfiles/), use StripPrefix to modify the request
     65 	// URL's path before the FileServer sees it:
     66 	http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
     67 }
     68 
     69 func ExampleStripPrefix() {
     70 	// To serve a directory on disk (/tmp) under an alternate URL
     71 	// path (/tmpfiles/), use StripPrefix to modify the request
     72 	// URL's path before the FileServer sees it:
     73 	http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
     74 }
     75 
     76 type apiHandler struct{}
     77 
     78 func (apiHandler) ServeHTTP(http.ResponseWriter, *http.Request) {}
     79 
     80 func ExampleServeMux_Handle() {
     81 	mux := http.NewServeMux()
     82 	mux.Handle("/api/", apiHandler{})
     83 	mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
     84 		// The "/" pattern matches everything, so we need to check
     85 		// that we're at the root here.
     86 		if req.URL.Path != "/" {
     87 			http.NotFound(w, req)
     88 			return
     89 		}
     90 		fmt.Fprintf(w, "Welcome to the home page!")
     91 	})
     92 }
     93 
     94 // HTTP Trailers are a set of key/value pairs like headers that come
     95 // after the HTTP response, instead of before.
     96 func ExampleResponseWriter_trailers() {
     97 	mux := http.NewServeMux()
     98 	mux.HandleFunc("/sendstrailers", func(w http.ResponseWriter, req *http.Request) {
     99 		// Before any call to WriteHeader or Write, declare
    100 		// the trailers you will set during the HTTP
    101 		// response. These three headers are actually sent in
    102 		// the trailer.
    103 		w.Header().Set("Trailer", "AtEnd1, AtEnd2")
    104 		w.Header().Add("Trailer", "AtEnd3")
    105 
    106 		w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
    107 		w.WriteHeader(http.StatusOK)
    108 
    109 		w.Header().Set("AtEnd1", "value 1")
    110 		io.WriteString(w, "This HTTP response has both headers before this text and trailers at the end.\n")
    111 		w.Header().Set("AtEnd2", "value 2")
    112 		w.Header().Set("AtEnd3", "value 3") // These will appear as trailers.
    113 	})
    114 }
    115 
    116 func ExampleServer_Shutdown() {
    117 	var srv http.Server
    118 
    119 	idleConnsClosed := make(chan struct{})
    120 	go func() {
    121 		sigint := make(chan os.Signal, 1)
    122 		signal.Notify(sigint, os.Interrupt)
    123 		<-sigint
    124 
    125 		// We received an interrupt signal, shut down.
    126 		if err := srv.Shutdown(context.Background()); err != nil {
    127 			// Error from closing listeners, or context timeout:
    128 			log.Printf("HTTP server Shutdown: %v", err)
    129 		}
    130 		close(idleConnsClosed)
    131 	}()
    132 
    133 	if err := srv.ListenAndServe(); err != http.ErrServerClosed {
    134 		// Error starting or closing listener:
    135 		log.Printf("HTTP server ListenAndServe: %v", err)
    136 	}
    137 
    138 	<-idleConnsClosed
    139 }
    140