rc: add support for OPTIONS and basic CORS - #2575

This commit is contained in:
frenos 2018-09-14 16:02:09 +02:00 committed by Nick Craig-Wood
parent 7b975bc1ff
commit 382a6863b5
2 changed files with 46 additions and 14 deletions

View File

@ -229,6 +229,9 @@ If an error occurs then there will be an HTTP error status (usually
400) and the body of the response will contain a JSON encoded error
object.
The sever implements basic CORS support and allows all origins for that.
The response to a preflight OPTIONS request will echo the requested "Access-Control-Request-Headers" back.
### Using POST with URL parameters only
```

View File

@ -94,19 +94,7 @@ func (s *server) handler(w http.ResponseWriter, r *http.Request) {
}
}
if r.Method != "POST" {
writeError(errors.Errorf("method %q not allowed - POST required", r.Method), http.StatusMethodNotAllowed)
return
}
// Find the call
call := registry.get(path)
if call == nil {
writeError(errors.Errorf("couldn't find method %q", path), http.StatusMethodNotAllowed)
return
}
// Parse the POST and URL parameters into r.Form
// Parse the POST and URL parameters into r.Form, for others r.Form will be empty value
err := r.ParseForm()
if err != nil {
writeError(errors.Wrap(err, "failed to parse form/URL parameters"), http.StatusBadRequest)
@ -119,7 +107,6 @@ func (s *server) handler(w http.ResponseWriter, r *http.Request) {
in[k] = vs[len(vs)-1]
}
}
fs.Debugf(nil, "form = %+v", r.Form)
// Parse a JSON blob from the input
if r.Header.Get("Content-Type") == "application/json" {
@ -130,6 +117,45 @@ func (s *server) handler(w http.ResponseWriter, r *http.Request) {
}
}
fs.Debugf(nil, "form = %+v", r.Form)
w.Header().Add("Access-Control-Allow-Origin", "*")
//echo back headers client needs
reqAccessHeaders := r.Header.Get("Access-Control-Request-Headers")
w.Header().Add("Access-Control-Allow-Headers", reqAccessHeaders)
switch r.Method {
case "POST":
s.handlePost(w, r, path, in)
case "OPTIONS":
s.handleOptions(w, r, in)
default:
writeError(errors.Errorf("method %q not allowed - POST or OPTIONS required", r.Method), http.StatusMethodNotAllowed)
return
}
}
func (s *server) handlePost(w http.ResponseWriter, r *http.Request, path string, in Params) {
writeError := func(err error, status int) {
fs.Errorf(nil, "rc: %q: error: %v", path, err)
w.WriteHeader(status)
err = WriteJSON(w, Params{
"error": err.Error(),
"input": in,
})
if err != nil {
// can't return the error at this point
fs.Errorf(nil, "rc: failed to write JSON output: %v", err)
}
}
// Find the call
call := registry.get(path)
if call == nil {
writeError(errors.Errorf("couldn't find method %q", path), http.StatusMethodNotAllowed)
return
}
fs.Debugf(nil, "rc: %q: with parameters %+v", path, in)
out, err := call.Fn(in)
if err != nil {
@ -144,3 +170,6 @@ func (s *server) handler(w http.ResponseWriter, r *http.Request) {
fs.Errorf(nil, "rc: failed to write JSON output: %v", err)
}
}
func (s *server) handleOptions(w http.ResponseWriter, r *http.Request, in Params) {
w.WriteHeader(http.StatusOK)
}