Source file src/net/http/triv.go

     1  // Copyright 2009 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  //go:build ignore
     6  
     7  package main
     8  
     9  import (
    10  	"expvar"
    11  	"flag"
    12  	"fmt"
    13  	"io"
    14  	"log"
    15  	"net/http"
    16  	"os"
    17  	"os/exec"
    18  	"strconv"
    19  	"strings"
    20  	"sync"
    21  )
    22  
    23  // hello world, the web server
    24  var helloRequests = expvar.NewInt("hello-requests")
    25  
    26  func HelloServer(w http.ResponseWriter, req *http.Request) {
    27  	helloRequests.Add(1)
    28  	io.WriteString(w, "hello, world!\n")
    29  }
    30  
    31  // Simple counter server. POSTing to it will set the value.
    32  type Counter struct {
    33  	mu sync.Mutex // protects n
    34  	n  int
    35  }
    36  
    37  // This makes Counter satisfy the [expvar.Var] interface, so we can export
    38  // it directly.
    39  func (ctr *Counter) String() string {
    40  	ctr.mu.Lock()
    41  	defer ctr.mu.Unlock()
    42  	return strconv.Itoa(ctr.n)
    43  }
    44  
    45  func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    46  	ctr.mu.Lock()
    47  	defer ctr.mu.Unlock()
    48  	switch req.Method {
    49  	case "GET":
    50  		ctr.n++
    51  	case "POST":
    52  		var buf strings.Builder
    53  		io.Copy(&buf, req.Body)
    54  		body := buf.String()
    55  		if n, err := strconv.Atoi(body); err != nil {
    56  			fmt.Fprintf(w, "bad POST: %v\nbody: [%v]\n", err, body)
    57  		} else {
    58  			ctr.n = n
    59  			fmt.Fprint(w, "counter reset\n")
    60  		}
    61  	}
    62  	fmt.Fprintf(w, "counter = %d\n", ctr.n)
    63  }
    64  
    65  // simple flag server
    66  var booleanflag = flag.Bool("boolean", true, "another flag for testing")
    67  
    68  func FlagServer(w http.ResponseWriter, req *http.Request) {
    69  	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    70  	fmt.Fprint(w, "Flags:\n")
    71  	flag.VisitAll(func(f *flag.Flag) {
    72  		if f.Value.String() != f.DefValue {
    73  			fmt.Fprintf(w, "%s = %s [default = %s]\n", f.Name, f.Value.String(), f.DefValue)
    74  		} else {
    75  			fmt.Fprintf(w, "%s = %s\n", f.Name, f.Value.String())
    76  		}
    77  	})
    78  }
    79  
    80  // simple argument server
    81  func ArgServer(w http.ResponseWriter, req *http.Request) {
    82  	for _, s := range os.Args {
    83  		fmt.Fprint(w, s, " ")
    84  	}
    85  }
    86  
    87  // a channel (just for the fun of it)
    88  type Chan chan int
    89  
    90  func ChanCreate() Chan {
    91  	c := make(Chan)
    92  	go func(c Chan) {
    93  		for x := 0; ; x++ {
    94  			c <- x
    95  		}
    96  	}(c)
    97  	return c
    98  }
    99  
   100  func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) {
   101  	io.WriteString(w, fmt.Sprintf("channel send #%d\n", <-ch))
   102  }
   103  
   104  // exec a program, redirecting output.
   105  func DateServer(rw http.ResponseWriter, req *http.Request) {
   106  	rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
   107  
   108  	date, err := exec.Command("/bin/date").Output()
   109  	if err != nil {
   110  		http.Error(rw, err.Error(), http.StatusInternalServerError)
   111  		return
   112  	}
   113  	rw.Write(date)
   114  }
   115  
   116  func Logger(w http.ResponseWriter, req *http.Request) {
   117  	log.Print(req.URL)
   118  	http.Error(w, "oops", http.StatusNotFound)
   119  }
   120  
   121  var webroot = flag.String("root", "", "web root directory")
   122  
   123  func main() {
   124  	flag.Parse()
   125  
   126  	// The counter is published as a variable directly.
   127  	ctr := new(Counter)
   128  	expvar.Publish("counter", ctr)
   129  	http.Handle("/counter", ctr)
   130  	http.Handle("/", http.HandlerFunc(Logger))
   131  	if *webroot != "" {
   132  		http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot))))
   133  	}
   134  	http.Handle("/chan", ChanCreate())
   135  	http.HandleFunc("/flags", FlagServer)
   136  	http.HandleFunc("/args", ArgServer)
   137  	http.HandleFunc("/go/hello", HelloServer)
   138  	http.HandleFunc("/date", DateServer)
   139  	log.Fatal(http.ListenAndServe("localhost:12345", nil))
   140  }
   141  

View as plain text