41 lines
911 B
Go
41 lines
911 B
Go
package rcli
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"path"
|
|
"fmt"
|
|
)
|
|
|
|
|
|
// Use this key to encode an RPC call into an URL,
|
|
// eg. domain.tld/path/to/method?q=get_user&q=gordon
|
|
const ARG_URL_KEY = "q"
|
|
|
|
func URLToCall(u *url.URL) (method string, args []string) {
|
|
return path.Base(u.Path), u.Query()[ARG_URL_KEY]
|
|
}
|
|
|
|
|
|
func ListenAndServeHTTP(addr string, service Service) error {
|
|
return http.ListenAndServe(addr, http.HandlerFunc(
|
|
func (w http.ResponseWriter, r *http.Request) {
|
|
cmd, args := URLToCall(r.URL)
|
|
if err := call(service, r.Body, &AutoFlush{w}, append([]string{cmd}, args...)...); err != nil {
|
|
fmt.Fprintf(w, "Error: " + err.Error() + "\n")
|
|
}
|
|
}))
|
|
}
|
|
|
|
|
|
type AutoFlush struct {
|
|
http.ResponseWriter
|
|
}
|
|
|
|
func (w *AutoFlush) Write(data []byte) (int, error) {
|
|
ret, err := w.ResponseWriter.Write(data)
|
|
if flusher, ok := w.ResponseWriter.(http.Flusher); ok {
|
|
flusher.Flush()
|
|
}
|
|
return ret, err
|
|
}
|