EDITED: to fix bad use of 'type synonyms'
For number 1:
Gorilla/rpc/json's CodecRequest.WriteResponse (which implements Gorilla/rpc's CodecRequest) is the one place where the code touches an http.ResponseWriter.
This means that we have to have our own implementation of CodecRequest which sets the CORS header.
Every CodecRequest used by the server is actually generated by a Codec; Codecs are factories for making CodecRequests, to put it another way.
This means that we have to create a Codec to generate our CodecRequests that will set CORS headers.
The great thing about Go is that it's really easy to compose this extra behavior!
Try this:
package cors_codec
import (
"Gorilla/rpc"
"net/http"
"strings"
)
//interface: ain't nobody dope like me I feel so fresh and clean
func CodecWithCors([]string corsDomains, unpimped rpc.Codec) rpc.Codec {
return corsCodecRequest{corsDomains, unpimped}
}
//use a type synonym so that our anonymous field has a very clear name
type underlyingCodecRequest rpc.CodecRequest
type corsCodecRequest struct {
corsDomains []string
underlyingCodecRequest rpc.CodecRequest
}
//override exactly one method of the underlying anonymous field and delegate to it.
func (ccr corsCodecRequest) WriteResponse(w http.ResponseWriter, reply interface{}, methodErr error) error {
w.Header().add("Access-Control-Allow-Origin", strings.join(ccr.corsDomains, " "))
return ccr.underlyingCodecRequest.WriteResponse(w, reply, error)
}
//use a type synonym so that our anonymous field has a very clear name
type underlyingCodec rpc.Codec
type corsCodec struct {
corsDomains []string
underlyingCodec rpc.Codec
}
//override exactly one method of the underlying anonymous field and delegate to it.
func (cc corsCodec) NewRequest(req *http.Request) rpc.CodecRequest {
return corsCodecRequest{cc.corsDomains, cc.underlyingCodec.NewRequest(req)}
}
That was a fun exercise!