title: HTTP PUT request handler using go
body: <p>Please consider this sample Go code snippet, </p>
  
  <pre><code>package main
  
  import (
          "fmt"
          "log"
          "net/http"
          "time"
  )
  
  func main() {
          listen_at := ":3114"
          go http.Handle("/", http.FileServer(http.Dir(".")))
          //go http.Handle("/max", http.FileServer(http.Dir("."))) &lt;-- Fails
          go http.HandleFunc("/ping", ping_handler)
          log.Fatal(http.ListenAndServe(listen_at, nil))
  
  }
  
  func ping_handler(w http.ResponseWriter, r *http.Request) {
          a := time.Now()
          layout := "2006-01-02-03-04-05-000"
  
          fmt.Println("Got root!")
          fmt.Println("r is", r)
          fmt.Println("RemoteAddr is", r.RemoteAddr)
          send_this := "OK GOT ping! " + a.Format(layout)
          w.Write([]byte(send_this))
  }
  </code></pre>
  
  <p>I've two questions: </p>
  
  <p>(1) How can I change the FileServer to serve <code>/max</code> instead of <code>/</code> - my attempts failed, I get 404 for <code>http://localhost:3114/max/</code> and <code>http://localhost:3114/max</code>.</p>
  
  <p>(2) I wish to accept <code>PUT</code> requests to <code>/max</code> - how can I achieve this?</p>
  
  <p>Please point me the right direction, thanks! </p>
  
  <p><strong>Edit 1</strong></p>
  
  <pre><code>package main
  
  import (
          "fmt"
          "log"
          "net/http"
  )
  
  func main() {
          go http.HandleFunc("/ping", hello)
          log.Fatal(http.ListenAndServe(":3114", nil))
  }
  
  func hello(w http.ResponseWriter, r *http.Request) {
          fmt.Println("STarting hello!")
  
          log.Println("Got connection")
          if r.URL.Path != "/ping" {
                  http.Error(w, "404 not found", http.StatusNotFound)
                  return
          }
          log.Println("Method:", r.Method)
          switch r.Method {
          case "GET":
                  send_this := "OK GOT ping! "
                  w.Write([]byte(send_this))
          case "PUT":
                  fmt.Println("We got put!")
                  err := r.ParseForm()
                  checkErr(err)
                  fmt.Println("r now", r)
                  fmt.Println("r.Form", r.Form)
                  fmt.Println("r.PostForm", r.PostForm)
          default:
                  send_this := "Please dont!"
                  w.Write([]byte(send_this))
                  fmt.Fprintf(w, "Unknown request!")
          }
  
  }
  
  func checkErr(err error) {
          if err != nil {
                  fmt.Println("Error", err)
          }
  }
  </code></pre>
  
  <p>I send a PUT request as <code>curl -k http://localhost:3114/ping -T /tmp/a.go  -v</code>, it shows:</p>
  
  <pre><code>STarting hello!
  2019/06/07 15:05:10 Got connection
  2019/06/07 15:05:10 Method: PUT
  We got put!
  r now &amp;{PUT /ping HTTP/1.1 1 1 map[Content-Length:[10115] Expect:[100-continue] User-Agent:[curl/7.47.0] Accept:[*/*]] 0xc4200ec2e0 &lt;nil&gt; 10115 [] false localhost:3114 map[] map[] &lt;nil&gt; map[] 127.0.0.1:64612 /ping &lt;nil&gt; &lt;nil&gt; &lt;nil&gt; 0xc42005e340}
  r.Form map[]
  r.PostForm map[]
  </code></pre>
  
  <p>How can I find the actual data, and the filename that came in from PUT? </p>