http.go 903 B

1234567891011121314151617181920212223242526272829303132333435363738
  1. package rcli
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/url"
  6. "path"
  7. )
  8. // Use this key to encode an RPC call into an URL,
  9. // eg. domain.tld/path/to/method?q=get_user&q=gordon
  10. const ARG_URL_KEY = "q"
  11. func URLToCall(u *url.URL) (method string, args []string) {
  12. return path.Base(u.Path), u.Query()[ARG_URL_KEY]
  13. }
  14. func ListenAndServeHTTP(addr string, service Service) error {
  15. return http.ListenAndServe(addr, http.HandlerFunc(
  16. func(w http.ResponseWriter, r *http.Request) {
  17. cmd, args := URLToCall(r.URL)
  18. if err := call(service, r.Body, &AutoFlush{w}, append([]string{cmd}, args...)...); err != nil {
  19. fmt.Fprintf(w, "Error: "+err.Error()+"\n")
  20. }
  21. }))
  22. }
  23. type AutoFlush struct {
  24. http.ResponseWriter
  25. }
  26. func (w *AutoFlush) Write(data []byte) (int, error) {
  27. ret, err := w.ResponseWriter.Write(data)
  28. if flusher, ok := w.ResponseWriter.(http.Flusher); ok {
  29. flusher.Flush()
  30. }
  31. return ret, err
  32. }