...
Run Format

Source file src/net/http/triv.go

Documentation: net/http

  // 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(), 500)
  		return
  	}
  	rw.Write(date)
  }
  
  func Logger(w http.ResponseWriter, req *http.Request) {
  	log.Print(req.URL)
  	http.Error(w, "oops", 404)
  }
  
  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))
  }
  

View as plain text