/http/triv.go

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