fn: URL parsing updates to fix json request_url (#657)

*) Updated fn-test-utils to latest fdk-go
*) Added hot-json to runner tests
*) Removed anon function in FromRequest which had
a side effect to set req.URL.Host. This is now more
explicit and eliminates some corresponding logic in
protocol http.
*) in gin, http request RequestURI is not set, removed
code that references this. (use Call.URL instead)
This commit is contained in:
Tolga Ceylan
2018-01-08 10:28:50 -08:00
committed by GitHub
parent b34a31aacc
commit 6f1f5e365d
7 changed files with 52 additions and 58 deletions

View File

@@ -72,7 +72,7 @@ func (ci callInfoImpl) Request() *http.Request {
return ci.req
}
func (ci callInfoImpl) RequestURL() string {
return ci.req.URL.RequestURI()
return ci.call.URL
}
func (ci callInfoImpl) Headers() map[string][]string {

View File

@@ -27,7 +27,7 @@ func (p *HTTPProtocol) IsStreamable() bool { return true }
// TODO maybe we should take io.Writer, io.Reader but then we have to
// dump the request to a buffer again :(
func (h *HTTPProtocol) Dispatch(ctx context.Context, ci CallInfo, w io.Writer) error {
err := DumpRequestTo(h.in, ci.Request()) // TODO timeout
err := DumpRequestTo(h.in, ci) // TODO timeout
if err != nil {
return err
}
@@ -70,32 +70,17 @@ func (h *HTTPProtocol) Dispatch(ctx context.Context, ci CallInfo, w io.Writer) e
// the body in the process.
//
// TODO we should support h2!
func DumpRequestTo(w io.Writer, req *http.Request) error {
// By default, print out the unmodified req.RequestURI, which
// is always set for incoming server requests. But because we
// previously used req.URL.RequestURI and the docs weren't
// always so clear about when to use DumpRequest vs
// DumpRequestOut, fall back to the old way if the caller
// provides a non-server Request.
func DumpRequestTo(w io.Writer, ci CallInfo) error {
reqURI := req.RequestURI
if reqURI == "" {
reqURI = req.URL.RequestURI()
}
req := ci.Request()
reqURI := ci.RequestURL()
fmt.Fprintf(w, "%s %s HTTP/%d.%d\r\n", valueOrDefault(req.Method, "GET"),
reqURI, req.ProtoMajor, req.ProtoMinor)
absRequestURI := strings.HasPrefix(req.RequestURI, "http://") || strings.HasPrefix(req.RequestURI, "https://")
if !absRequestURI {
host := req.Host
if host == "" && req.URL != nil {
host = req.URL.Host
}
if host != "" {
fmt.Fprintf(w, "Host: %s\r\n", host)
}
absRequestURI := strings.HasPrefix(reqURI, "http://") || strings.HasPrefix(reqURI, "https://")
if !absRequestURI && req.URL.Host != "" {
fmt.Fprintf(w, "Host: %s\r\n", req.URL.Host)
}
chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked"

View File

@@ -16,7 +16,7 @@ type RequestData struct {
A string `json:"a"`
}
func setupRequest(data interface{}) *http.Request {
func setupRequest(data interface{}) *callInfoImpl {
req := &http.Request{
Method: http.MethodPost,
URL: &url.URL{
@@ -40,15 +40,20 @@ func setupRequest(data interface{}) *http.Request {
_ = json.NewEncoder(&buf).Encode(data)
}
req.Body = ioutil.NopCloser(&buf)
return req
call := &models.Call{Type: "json"}
// fixup URL in models.Call
call.URL = req.URL.String()
ci := &callInfoImpl{call, req}
return ci
}
func TestJSONProtocolwriteJSONInputRequestWithData(t *testing.T) {
rDataBefore := RequestData{A: "a"}
req := setupRequest(rDataBefore)
ci := setupRequest(rDataBefore)
r, w := io.Pipe()
call := &models.Call{Type: "json"}
ci := &callInfoImpl{call, req}
proto := JSONProtocol{w, r}
go func() {
err := proto.writeJSONToContainer(ci)
@@ -77,18 +82,15 @@ func TestJSONProtocolwriteJSONInputRequestWithData(t *testing.T) {
t.Errorf("Request data assertion mismatch: expected: %s, got %s",
rDataBefore.A, rDataAfter.A)
}
if incomingReq.Protocol.Type != call.Type {
if incomingReq.Protocol.Type != ci.call.Type {
t.Errorf("Call protocol type assertion mismatch: expected: %s, got %s",
call.Type, incomingReq.Protocol.Type)
ci.call.Type, incomingReq.Protocol.Type)
}
}
func TestJSONProtocolwriteJSONInputRequestWithoutData(t *testing.T) {
req := setupRequest(nil)
call := &models.Call{Type: "json"}
ci := setupRequest(nil)
r, w := io.Pipe()
ci := &callInfoImpl{call, req}
proto := JSONProtocol{w, r}
go func() {
err := proto.writeJSONToContainer(ci)
@@ -112,18 +114,15 @@ func TestJSONProtocolwriteJSONInputRequestWithoutData(t *testing.T) {
t.Errorf("Request body assertion mismatch: expected: %s, got %s",
"<empty-string>", incomingReq.Body)
}
if !models.Headers(req.Header).Equals(models.Headers(incomingReq.Protocol.Headers)) {
if !models.Headers(ci.req.Header).Equals(models.Headers(incomingReq.Protocol.Headers)) {
t.Errorf("Request headers assertion mismatch: expected: %s, got %s",
req.Header, incomingReq.Protocol.Headers)
ci.req.Header, incomingReq.Protocol.Headers)
}
}
func TestJSONProtocolwriteJSONInputRequestWithQuery(t *testing.T) {
req := setupRequest(nil)
ci := setupRequest(nil)
r, w := io.Pipe()
call := &models.Call{Type: "json"}
ci := &callInfoImpl{call, req}
proto := JSONProtocol{w, r}
go func() {
err := proto.writeJSONToContainer(ci)
@@ -143,8 +142,8 @@ func TestJSONProtocolwriteJSONInputRequestWithQuery(t *testing.T) {
if err != nil {
t.Error(err.Error())
}
if incomingReq.Protocol.RequestURL != req.URL.RequestURI() {
if incomingReq.Protocol.RequestURL != ci.call.URL {
t.Errorf("Request URL does not match protocol URL: expected: %s, got %s",
req.URL.RequestURI(), incomingReq.Protocol.RequestURL)
ci.call.URL, incomingReq.Protocol.RequestURL)
}
}