PageRenderTime 23ms CodeModel.GetById 12ms app.highlight 8ms RepoModel.GetById 2ms app.codeStats 0ms

/http/triv.go

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