...

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	// +build ignore
     6	
     7	package main
     8	
     9	import (
    10		"bytes"
    11		"expvar"
    12		"flag"
    13		"fmt"
    14		"io"
    15		"log"
    16		"net/http"
    17		"os"
    18		"os/exec"
    19		"strconv"
    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 fmt.Sprintf("%d", 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			buf := new(bytes.Buffer)
    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", os.Getenv("HOME"), "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		http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot))))
   132		http.Handle("/chan", ChanCreate())
   133		http.HandleFunc("/flags", FlagServer)
   134		http.HandleFunc("/args", ArgServer)
   135		http.HandleFunc("/go/hello", HelloServer)
   136		http.HandleFunc("/date", DateServer)
   137		log.Fatal(http.ListenAndServe(":12345", nil))
   138	}
   139	

View as plain text