|  | // Copyright 2009 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | // +build ignore | 
|  |  | 
|  | package main | 
|  |  | 
|  | import ( | 
|  | "bytes" | 
|  | "expvar" | 
|  | "flag" | 
|  | "fmt" | 
|  | "io" | 
|  | "log" | 
|  | "net/http" | 
|  | "os" | 
|  | "os/exec" | 
|  | "strconv" | 
|  | "sync" | 
|  | ) | 
|  |  | 
|  | // hello world, the web server | 
|  | var helloRequests = expvar.NewInt("hello-requests") | 
|  |  | 
|  | func HelloServer(w http.ResponseWriter, req *http.Request) { | 
|  | helloRequests.Add(1) | 
|  | io.WriteString(w, "hello, world!\n") | 
|  | } | 
|  |  | 
|  | // Simple counter server. POSTing to it will set the value. | 
|  | type Counter struct { | 
|  | mu sync.Mutex // protects n | 
|  | n  int | 
|  | } | 
|  |  | 
|  | // This makes Counter satisfy the expvar.Var interface, so we can export | 
|  | // it directly. | 
|  | func (ctr *Counter) String() string { | 
|  | ctr.mu.Lock() | 
|  | defer ctr.mu.Unlock() | 
|  | return fmt.Sprintf("%d", ctr.n) | 
|  | } | 
|  |  | 
|  | func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) { | 
|  | ctr.mu.Lock() | 
|  | defer ctr.mu.Unlock() | 
|  | switch req.Method { | 
|  | case "GET": | 
|  | ctr.n++ | 
|  | case "POST": | 
|  | buf := new(bytes.Buffer) | 
|  | io.Copy(buf, req.Body) | 
|  | body := buf.String() | 
|  | if n, err := strconv.Atoi(body); err != nil { | 
|  | fmt.Fprintf(w, "bad POST: %v\nbody: [%v]\n", err, body) | 
|  | } else { | 
|  | ctr.n = n | 
|  | fmt.Fprint(w, "counter reset\n") | 
|  | } | 
|  | } | 
|  | fmt.Fprintf(w, "counter = %d\n", ctr.n) | 
|  | } | 
|  |  | 
|  | // simple flag server | 
|  | var booleanflag = flag.Bool("boolean", true, "another flag for testing") | 
|  |  | 
|  | func FlagServer(w http.ResponseWriter, req *http.Request) { | 
|  | w.Header().Set("Content-Type", "text/plain; charset=utf-8") | 
|  | fmt.Fprint(w, "Flags:\n") | 
|  | flag.VisitAll(func(f *flag.Flag) { | 
|  | if f.Value.String() != f.DefValue { | 
|  | fmt.Fprintf(w, "%s = %s [default = %s]\n", f.Name, f.Value.String(), f.DefValue) | 
|  | } else { | 
|  | fmt.Fprintf(w, "%s = %s\n", f.Name, f.Value.String()) | 
|  | } | 
|  | }) | 
|  | } | 
|  |  | 
|  | // simple argument server | 
|  | func ArgServer(w http.ResponseWriter, req *http.Request) { | 
|  | for _, s := range os.Args { | 
|  | fmt.Fprint(w, s, " ") | 
|  | } | 
|  | } | 
|  |  | 
|  | // a channel (just for the fun of it) | 
|  | type Chan chan int | 
|  |  | 
|  | func ChanCreate() Chan { | 
|  | c := make(Chan) | 
|  | go func(c Chan) { | 
|  | for x := 0; ; x++ { | 
|  | c <- x | 
|  | } | 
|  | }(c) | 
|  | return c | 
|  | } | 
|  |  | 
|  | func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) { | 
|  | io.WriteString(w, fmt.Sprintf("channel send #%d\n", <-ch)) | 
|  | } | 
|  |  | 
|  | // exec a program, redirecting output | 
|  | func DateServer(rw http.ResponseWriter, req *http.Request) { | 
|  | rw.Header().Set("Content-Type", "text/plain; charset=utf-8") | 
|  |  | 
|  | date, err := exec.Command("/bin/date").Output() | 
|  | if err != nil { | 
|  | http.Error(rw, err.Error(), http.StatusInternalServerError) | 
|  | return | 
|  | } | 
|  | rw.Write(date) | 
|  | } | 
|  |  | 
|  | func Logger(w http.ResponseWriter, req *http.Request) { | 
|  | log.Print(req.URL) | 
|  | http.Error(w, "oops", http.StatusNotFound) | 
|  | } | 
|  |  | 
|  | var webroot = flag.String("root", os.Getenv("HOME"), "web root directory") | 
|  |  | 
|  | func main() { | 
|  | flag.Parse() | 
|  |  | 
|  | // The counter is published as a variable directly. | 
|  | ctr := new(Counter) | 
|  | expvar.Publish("counter", ctr) | 
|  | http.Handle("/counter", ctr) | 
|  | http.Handle("/", http.HandlerFunc(Logger)) | 
|  | http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot)))) | 
|  | http.Handle("/chan", ChanCreate()) | 
|  | http.HandleFunc("/flags", FlagServer) | 
|  | http.HandleFunc("/args", ArgServer) | 
|  | http.HandleFunc("/go/hello", HelloServer) | 
|  | http.HandleFunc("/date", DateServer) | 
|  | log.Fatal(http.ListenAndServe(":12345", nil)) | 
|  | } |