Merge pull request #738 from Kilowhisky/cors_support
Add support for CORS in http requests
This commit is contained in:
commit
4ef11351f3
@ -867,6 +867,7 @@ func (s *Server) handleInputCommand(client *Client, msg *Message) error {
|
|||||||
"Connection: close\r\n"+
|
"Connection: close\r\n"+
|
||||||
"Content-Length: %d\r\n"+
|
"Content-Length: %d\r\n"+
|
||||||
"Content-Type: application/json; charset=utf-8\r\n"+
|
"Content-Type: application/json; charset=utf-8\r\n"+
|
||||||
|
"Access-Control-Allow-Origin: *\r\n"+
|
||||||
"\r\n", status, len(res)+2)
|
"\r\n", status, len(res)+2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1444,6 +1445,22 @@ func readNextHTTPCommand(packet []byte, argsIn [][]byte, msg *Message, wr io.Wri
|
|||||||
}
|
}
|
||||||
method := parts[0]
|
method := parts[0]
|
||||||
path := parts[1]
|
path := parts[1]
|
||||||
|
// Handle CORS request for allowed origins
|
||||||
|
if method == "OPTIONS" {
|
||||||
|
if wr == nil {
|
||||||
|
return false, errors.New("connection is nil")
|
||||||
|
}
|
||||||
|
corshead := "HTTP/1.1 204 No Content\r\n" +
|
||||||
|
"Connection: close\r\n" +
|
||||||
|
"Access-Control-Allow-Origin: *\r\n" +
|
||||||
|
"Access-Control-Allow-Headers: *, Authorization\r\n" +
|
||||||
|
"Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n\r\n"
|
||||||
|
|
||||||
|
if _, err = wr.Write([]byte(corshead)); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
if len(path) == 0 || path[0] != '/' {
|
if len(path) == 0 || path[0] != '/' {
|
||||||
return false, errInvalidHTTP
|
return false, errInvalidHTTP
|
||||||
}
|
}
|
||||||
@ -1528,7 +1545,7 @@ func readNextHTTPCommand(packet []byte, argsIn [][]byte, msg *Message, wr io.Wri
|
|||||||
func readNextCommand(packet []byte, argsIn [][]byte, msg *Message, wr io.Writer) (
|
func readNextCommand(packet []byte, argsIn [][]byte, msg *Message, wr io.Writer) (
|
||||||
complete bool, args [][]byte, kind redcon.Kind, leftover []byte, err error,
|
complete bool, args [][]byte, kind redcon.Kind, leftover []byte, err error,
|
||||||
) {
|
) {
|
||||||
if packet[0] == 'G' || packet[0] == 'P' {
|
if packet[0] == 'G' || packet[0] == 'P' || packet[0] == 'O' {
|
||||||
// could be an HTTP request
|
// could be an HTTP request
|
||||||
var line []byte
|
var line []byte
|
||||||
for i := 1; i < len(packet); i++ {
|
for i := 1; i < len(packet); i++ {
|
||||||
|
56
tests/proto_test.go
Normal file
56
tests/proto_test.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func subTestProto(g *testGroup) {
|
||||||
|
g.regSubTest("HTTP CORS", proto_HTTP_CORS_test)
|
||||||
|
}
|
||||||
|
|
||||||
|
func proto_HTTP_CORS_test(mc *mockServer) error {
|
||||||
|
// Make CORS request for GET /SERVER
|
||||||
|
morigin := "http://my-test-origin"
|
||||||
|
url := fmt.Sprintf("http://127.0.0.1:%d/SERVER", mc.port)
|
||||||
|
req, err := http.NewRequest(http.MethodOptions, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Add("Origin", morigin)
|
||||||
|
req.Header.Add("Access-Control-Request-Method", "GET")
|
||||||
|
req.Header.Add("Access-Control-Request-Headers", "Authorization")
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
|
||||||
|
// Validate CORS response
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 204 {
|
||||||
|
return fmt.Errorf("expected http stuats '204', got '%d'", resp.StatusCode)
|
||||||
|
}
|
||||||
|
origin := resp.Header.Get("Access-Control-Allow-Origin")
|
||||||
|
methods := resp.Header.Get("Access-Control-Allow-Methods")
|
||||||
|
headers := resp.Header.Get("Access-Control-Allow-Headers")
|
||||||
|
if !(origin == "*" || origin == morigin) {
|
||||||
|
return fmt.Errorf("expected http access-control-allow-origin value '*', got '%s'", origin)
|
||||||
|
}
|
||||||
|
if methods != "POST, GET, OPTIONS" {
|
||||||
|
return fmt.Errorf("expected http access-control-allow-Methods value 'POST, GET, OPTIONS', got '%s'", methods)
|
||||||
|
}
|
||||||
|
if headers != "*, Authorization" {
|
||||||
|
return fmt.Errorf("expected http access-control-allow-headers value '*, Authorization', got '%s'", headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the actual request now
|
||||||
|
resp, err = http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
origin = resp.Header.Get("Access-Control-Allow-Origin")
|
||||||
|
if !(origin == "*" || origin == morigin) {
|
||||||
|
return fmt.Errorf("expected http access-control-allow-origin value '*', got '%s'", origin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -57,6 +57,7 @@ func TestIntegration(t *testing.T) {
|
|||||||
regTestGroup("follower", subTestFollower)
|
regTestGroup("follower", subTestFollower)
|
||||||
regTestGroup("aof", subTestAOF)
|
regTestGroup("aof", subTestAOF)
|
||||||
regTestGroup("monitor", subTestMonitor)
|
regTestGroup("monitor", subTestMonitor)
|
||||||
|
regTestGroup("proto", subTestProto)
|
||||||
runTestGroups(t)
|
runTestGroups(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user