Repository: goadesign/goa
Pull request #2551 (2020-05-07 01:15:47)

Fail validation if HTTP request body is non-empty in a streaming endpoint

raphael: I see that we still allow having both `Payload` and `StreamingPayload` for endpoints. What is the semantic? should these be exclusive?

Patch:
diff --git a/Makefile b/Makefile
index 6d45cab3..4978e800 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@
 #
 MAJOR=3
 MINOR=1
-BUILD=2
+BUILD=3
 
 GOOS=$(shell go env GOOS)
 GO_FILES=$(shell find . -type f -name '*.go')
diff --git a/README.md b/README.md
index 2423fa03..389fd433 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ design-first approach.
 ---
 [![Build Status](https://github.com/goadesign/goa/workflows/build/badge.svg?branch=v3&event=push)](https://github.com/goadesign/goa/actions?query=branch%3Av3+event%3Apush)
 [![Godoc Packages](https://img.shields.io/badge/godoc-packages-blue)](https://pkg.go.dev/mod/goa.design/goa/v3?tab=packages)
-[![Godoc DSL](https://img.shields.io/badge/godoc-DSL-blue)](https://pkg.go.dev/goa.design/goa/v3@v3.1.2/dsl?tab=doc)
+[![Godoc DSL](https://img.shields.io/badge/godoc-DSL-blue)](https://pkg.go.dev/goa.design/goa/v3@v3.1.3/dsl?tab=doc)
 [![Slack](https://img.shields.io/badge/slack-gophers-orange.svg?style=flat)](https://gophers.slack.com/messages/goa/)
 
 ## Overview
@@ -97,7 +97,7 @@ without having to make changes.
 Releases are tagged with the corresponding version number. There is also a
 branch for each major version (`v1`, `v2` and `v3`).
 
-Current Release: `v3.1.2`
+Current Release: `v3.1.3`
 
 ## Teaser
 
diff --git a/cmd/goa/main.go b/cmd/goa/main.go
index fcd2d0cd..b3e191b3 100644
--- a/cmd/goa/main.go
+++ b/cmd/goa/main.go
@@ -111,8 +111,8 @@ func help() {
 Learn more at https://goa.design.
 
 Usage:
-  goa gen PACKAGE [--out DIRECTORY] [--debug]
-  goa example PACKAGE [--out DIRECTORY] [--debug]
+  goa gen PACKAGE [--output DIRECTORY] [--debug]
+  goa example PACKAGE [--output DIRECTORY] [--debug]
   goa version
 
 Commands:
diff --git a/codegen/funcs.go b/codegen/funcs.go
index 52add593..fecb7c74 100644
--- a/codegen/funcs.go
+++ b/codegen/funcs.go
@@ -145,10 +145,15 @@ func CamelCase(name string, firstUpper bool, acronym bool) string {
 		// [w,i] is a word.
 		word := string(runes[w:i])
 		// is it one of our initialisms?
-		if u := strings.ToUpper(word); acronym && commonInitialisms[u] {
-			if firstUpper {
-				u = strings.ToUpper(u)
-			} else if w == 0 {
+		if u := strings.ToUpper(word); commonInitialisms[u] {
+			switch {
+			case firstUpper && acronym:
+				// u is already in upper case. Nothing to do here.
+			case firstUpper && !acronym:
+				u = strings.Title(strings.ToLower(u))
+			case w > 0 && !acronym:
+				u = strings.Title(strings.ToLower(u))
+			case w == 0:
 				u = strings.ToLower(u)
 			}
 
diff --git a/codegen/service/convert.go b/codegen/service/convert.go
index ff062b81..a70b2951 100644
--- a/codegen/service/convert.go
+++ b/codegen/service/convert.go
@@ -554,6 +554,13 @@ func attributeName(obj *expr.Object, name string) (string, string) {
 			return ln, name
 		}
 	}
+	// next look for a lower camel case without acronym
+	lcn := codegen.CamelCase(name, false, false)
+	for _, nat := range *obj {
+		if nat.Name == lcn {
+			return lcn, name
+		}
+	}
 	// finally look for a snake case representation
 	sn := codegen.SnakeCase(name)
 	for _, nat := range *obj {
diff --git a/codegen/service/service_data.go b/codegen/service/service_data.go
index 52c97dc1..def040f5 100644
--- a/codegen/service/service_data.go
+++ b/codegen/service/service_data.go
@@ -761,7 +761,7 @@ func buildMethodData(m *expr.MethodExpr, svcPkgName string, service *expr.Servic
 	for _, req := range m.Requirements {
 		var rs SchemesData
 		for _, s := range req.Schemes {
-			sch := buildSchemeData(s, m)
+			sch := BuildSchemeData(s, m)
 			rs = rs.Append(sch)
 			schemes = schemes.Append(sch)
 		}
@@ -876,8 +876,8 @@ func initStreamData(data *MethodData, m *expr.MethodExpr, vname, rname, resultRe
 	data.StreamingPayloadEx = spayloadEx
 }
 
-// buildSchemeData builds the scheme data for the given scheme and method expr.
-func buildSchemeData(s *expr.SchemeExpr, m *expr.MethodExpr) *SchemeData {
+// BuildSchemeData builds the scheme data for the given scheme and method expr.
+func BuildSchemeData(s *expr.SchemeExpr, m *expr.MethodExpr) *SchemeData {
 	if !expr.IsObject(m.Payload.Type) {
 		return nil
 	}
diff --git a/dsl/error.go b/dsl/error.go
index 78dc8d18..d7250759 100644
--- a/dsl/error.go
+++ b/dsl/error.go
@@ -45,6 +45,8 @@ func Error(name string, args ...interface{}) {
 	}
 	erro := &expr.ErrorExpr{AttributeExpr: att, Name: name}
 	switch actual := eval.Current().(type) {
+	case *expr.APIExpr:
+		expr.Root.Errors = append(expr.Root.Errors, erro)
 	case *expr.ServiceExpr:
 		actual.Errors = append(actual.Errors, erro)
 	case *expr.MethodExpr:
diff --git a/dsl/http.go b/dsl/http.go
index 8ed3e7b4..8758c465 100644
--- a/dsl/http.go
+++ b/dsl/http.go
@@ -224,6 +224,11 @@ func Produces(args ...string) {
 // description of the wildcard syntax). The corresponding parameters must be
 // described using Params. Multiple base paths may be defined for services.
 //
+// GET("/") does not add a trailing slash when the base path is defined by Path.
+// For example, when Path('foo') is defined, the path generated by GET("/") will be '/foo'.
+// As a special case, if you want to generate a path with a trailing slash, you can use
+// GET("/./") to generate a path such as '/foo/'.
+//
 // Path must appear in a API HTTP expression or a Service HTTP expression.
 //
 // Path accepts one argument: the HTTP path prefix.
diff --git a/dsl/response.go b/dsl/response.go
index f40eb960..5ce03536 100644
--- a/dsl/response.go
+++ b/dsl/response.go
@@ -104,6 +104,14 @@ func Response(val interface{}, args ...interface{}) {
 		}
 	}
 	switch t := eval.Current().(type) {
+	case *expr.RootExpr:
+		if !ok {
+			eval.InvalidArgError("name of error", val)
+			return
+		}
+		if e := httpError(name, t, args...); e != nil {
+			t.API.HTTP.Errors = append(t.API.HTTP.Errors, e)
+		}
 	case *expr.HTTPExpr:
 		if !ok {
 			eval.InvalidArgError("name of error", val)
diff --git a/expr/http_body_types.go b/expr/http_body_types.go
index e6dcc43d..d95941eb 100644
--- a/expr/http_body_types.go
+++ b/expr/http_body_types.go
@@ -373,3 +373,86 @@ func removeAttribute(attr *MappedAttributeExpr, name string) {
 		}
 	}
 }
+
+// extendedHTTPRequestBody returns an attribute describing the HTTP request body.
+// This is used only in the validation phase to figure out the request body when
+// method Payload extends or references other types.
+func extendedHTTPRequestBody(a *HTTPEndpointExpr) *AttributeExpr {
+	const suffix = "RequestBody"
+	var (
+		name = concat(a.Name(), "Request", "Body")
+	)
+	if a.Body != nil {
+		a.Body = DupAtt(a.Body)
+		renameType(a.Body, name, suffix)
+		return a.Body
+	}
+
+	var (
+		payload  = a.MethodExpr.Payload
+		headers  = a.Headers
+		params   = a.Params
+		bodyOnly = headers.IsEmpty() && params.IsEmpty() && a.MapQueryParams == nil
+	)
+
+	// 1. If Payload is not an object then check whether there are params or
+	// headers defined and if so return empty type (payload encoded in
+	// request params or headers) otherwise return payload type (payload
+	// encoded in request body).
+	if !IsObject(payload.Type) {
+		if bodyOnly {
+			payload = DupAtt(payload)
+			renameType(payload, name, suffix)
+			return payload
+		}
+		return &AttributeExpr{Type: Empty}
+	}
+
+	// Merge extended and referenced types
+	payload = DupAtt(payload)
+	for _, ref := range payload.References {
+		ru, ok := ref.(UserType)
+		if !ok {
+			continue
+		}
+		payload.Inherit(ru.Attribute())
+	}
+	for _, base := range payload.Bases {
+		ru, ok := base.(UserType)
+		if !ok {
+			continue
+		}
+		payload.Merge(ru.Attribute())
+	}
+
+	// 2. Remove header and param attributes
+	body := NewMappedAttributeExpr(payload)
+	removeAttributes(body, headers)
+	removeAttributes(body, params)
+	if a.MapQueryParams != nil && *a.MapQueryParams != "" {
+		removeAttribute(body, *a.MapQueryParams)
+	}
+	for att := range defaultRequestHeaderAttributes(a) {
+		removeAttribute(body, att)
+	}
+
+	// 3. Return empty type if no attribute left
+	if len(*AsObject(body.Type)) == 0 {
+		return &AttributeExpr{Type: Empty}
+	}
+
+	// 4. Build computed user type
+	att := body.Attribute()
+	ut := &UserTypeExpr{
+		AttributeExpr: att,
+		TypeName:      name,
+		UID:           a.Service.Name() + "#" + a.Name(),
+	}
+	appendSuffix(ut.Attribute().Type, suffix)
+
+	return &AttributeExpr{
+		Type:         ut,
+		Validation:   att.Validation,
+		UserExamples: att.UserExamples,
+	}
+}
diff --git a/expr/http_endpoint.go b/expr/http_endpoint.go
index b5167cb0..f15cbf6b 100644
--- a/expr/http_endpoint.go
+++ b/expr/http_endpoint.go
@@ -260,6 +260,24 @@ func (e *HTTPEndpointExpr) Prepare() {
 		e.HTTPErrors = append(e.HTTPErrors, r.Dup())
 	}
 
+	// Lookup undefined HTTP errors in API.
+	for _, err := range e.MethodExpr.Errors {
+		found := false
+		for _, herr := range e.HTTPErrors {
+			if err.Name == herr.Name {
+				found = true
+				break
+			}
+		}
+		if !found {
+			for _, herr := range Root.API.HTTP.Errors {
+				if herr.Name == err.Name {
+					e.HTTPErrors = append(e.HTTPErrors, herr.Dup())
+				}
+			}
+		}
+	}
+
 	// Prepare responses
 	for _, r := range e.Responses {
 		r.Prepare()
@@ -559,11 +577,14 @@ func (e *HTTPEndpointExpr) Validate() error {
 		}
 	}
 
-	if e.SkipRequestBodyEncodeDecode {
-		body := httpRequestBody(e)
-		if body.Type != Empty {
-			verr.Add(e, "HTTP endpoint request body must be empty when using SkipRequestBodyEncodeDecode but not all method payload attributes are mapped to headers and params. Make sure to define Headers and Params as needed.")
-		}
+	body := extendedHTTPRequestBody(e)
+	if e.SkipRequestBodyEncodeDecode && body.Type != Empty {
+		verr.Add(e, "HTTP endpoint request body must be empty when using SkipRequestBodyEncodeDecode but not all method payload attributes are mapped to headers and params. Make sure to define Headers and Params as needed.")
+	}
+	if e.MethodExpr.IsStreaming() && body.Type != Empty {
+		// Refer Websocket protocol - https://tools.ietf.org/html/rfc6455
+		// Protocol does not allow HTTP request body to be passed.
+		verr.Add(e, "HTTP endpoint request body must be empty when the endpoint uses streaming. Payload attributes must be mapped to headers and/or params.")
 	}
 
 	return verr
@@ -644,24 +665,6 @@ func (e *HTTPEndpointExpr) Finalize() {
 		r.Body.Finalize()
 	}
 
-	// Lookup undefined HTTP errors in API.
-	for _, err := range e.MethodExpr.Errors {
-		found := false
-		for _, herr := range e.HTTPErrors {
-			if err.Name == herr.Name {
-				found = true
-				break
-			}
-		}
-		if !found {
-			for _, herr := range Root.API.HTTP.Errors {
-				if herr.Name == err.Name {
-					e.HTTPErrors = append(e.HTTPErrors, herr.Dup())
-				}
-			}
-		}
-	}
-
 	// Make sure all error types are user types and have a body.
 	for _, herr := range e.HTTPErrors {
 		herr.Finalize(e)
@@ -888,7 +891,13 @@ func (r *RouteExpr) FullPaths() []string {
 	res := make([]string, len(bases))
 	for i, b := range bases {
 		res[i] = httppath.Clean(path.Join(b, r.Path))
-		if res[i] != "/" && strings.HasSuffix(r.Path, "/") {
+		if res[i] == "/" {
+			continue
+		}
+		// path has trailing slash
+		if r.Path == "/" && strings.HasSuffix(b, "/") {
+			res[i] += "/"
+		} else if r.Path != "/" && strings.HasSuffix(r.Path, "/") {
 			res[i] += "/"
 		}
 	}
diff --git a/expr/http_response.go b/expr/http_response.go
index e517a50f..654d0907 100644
--- a/expr/http_response.go
+++ b/expr/http_response.go
@@ -286,7 +286,9 @@ func (r *HTTPResponseExpr) Dup() *HTTPResponseExpr {
 	if r.Body != nil {
 		res.Body = DupAtt(r.Body)
 	}
-	res.Headers = DupMappedAtt(r.Headers)
+	if r.Headers != nil {
+		res.Headers = DupMappedAtt(r.Headers)
+	}
 	return &res
 }
 
diff --git a/expr/http_service.go b/expr/http_service.go
index 32cf9cdd..eed7c84c 100644
--- a/expr/http_service.go
+++ b/expr/http_service.go
@@ -127,7 +127,12 @@ func (svc *HTTPServiceExpr) FullPaths() []string {
 			basePaths = []string{Root.API.HTTP.Path}
 		}
 		for _, base := range basePaths {
-			paths = append(paths, httppath.Clean(path.Join(base, p)))
+			v := httppath.Clean(path.Join(base, p))
+			// path has trailing slash
+			if strings.HasSuffix(p, "/") {
+				v += "/"
+			}
+			paths = append(paths, v)
 		}
 	}
 	return paths
@@ -163,6 +168,23 @@ func (svc *HTTPServiceExpr) EvalName() string {
 
 // Prepare initializes the error responses.
 func (svc *HTTPServiceExpr) Prepare() {
+	// Lookup undefined HTTP errors in API.
+	for _, err := range svc.ServiceExpr.Errors {
+		found := false
+		for _, herr := range svc.HTTPErrors {
+			if err.Name == herr.Name {
+				found = true
+				break
+			}
+		}
+		if !found {
+			for _, herr := range Root.API.HTTP.Errors {
+				if herr.Name == err.Name {
+					svc.HTTPErrors = append(svc.HTTPErrors, herr.Dup())
+				}
+			}
+		}
+	}
 	for _, er := range svc.HTTPErrors {
 		er.Response.Prepare()
 	}
diff --git a/grpc/codegen/protobuf.go b/grpc/codegen/protobuf.go
index 3a8f057a..20b03e15 100644
--- a/grpc/codegen/protobuf.go
+++ b/grpc/codegen/protobuf.go
@@ -107,12 +107,12 @@ func makeProtoBufMessageR(att *expr.AttributeExpr, tname *string, sd *ServiceDat
 		switch {
 		case expr.IsArray(att.Type):
 			wrapAttr(att, "ArrayOf"+tname+
-				protoBufify(protoBufMessageDef(expr.AsArray(att.Type).ElemType, sd), true), sd)
+				protoBufify(protoBufMessageDef(expr.AsArray(att.Type).ElemType, sd), true, true), sd)
 		case expr.IsMap(att.Type):
 			m := expr.AsMap(att.Type)
 			wrapAttr(att, tname+"MapOf"+
-				protoBufify(protoBufMessageDef(m.KeyType, sd), true)+
-				protoBufify(protoBufMessageDef(m.ElemType, sd), true), sd)
+				protoBufify(protoBufMessageDef(m.KeyType, sd), true, true)+
+				protoBufify(protoBufMessageDef(m.ElemType, sd), true, true), sd)
 		}
 	}
 
@@ -190,7 +190,7 @@ func protoBufMessageName(att *expr.AttributeExpr, s *codegen.NameScope) string {
 func protoBufFullMessageName(att *expr.AttributeExpr, pkg string, s *codegen.NameScope) string {
 	switch actual := att.Type.(type) {
 	case expr.UserType:
-		n := s.HashedUnique(actual, protoBufify(actual.Name(), true), "")
+		n := s.HashedUnique(actual, protoBufify(actual.Name(), true, true), "")
 		if pkg == "" {
 			return n
 		}
@@ -257,7 +257,7 @@ func protoBufMessageDef(att *expr.AttributeExpr, sd *ServiceData) string {
 				desc string
 			)
 			{
-				fn = codegen.SnakeCase(protoBufify(nat.Name, false))
+				fn = codegen.SnakeCase(protoBufify(nat.Name, false, false))
 				fnum = rpcTag(nat.Attribute)
 				if prim := getPrimitive(nat.Attribute); prim != nil {
 					typ = protoBufMessageDef(prim, sd)
@@ -295,7 +295,7 @@ func protoBufGoFullTypeRef(att *expr.AttributeExpr, pkg string, s *codegen.NameS
 //
 // If firstUpper is true the first character of the identifier is uppercase
 // otherwise it's lowercase.
-func protoBufify(str string, firstUpper bool) string {
+func protoBufify(str string, firstUpper, acronym bool) string {
 	// Optimize trivial case
 	if str == "" {
 		return ""
@@ -308,8 +308,7 @@ func protoBufify(str string, firstUpper bool) string {
 		str = str[:idx]
 	}
 
-	// We must disable acronyms to generate gRPC compatible names.
-	str = codegen.CamelCase(str, firstUpper, false)
+	str = codegen.CamelCase(str, firstUpper, acronym)
 	if str == "" {
 		// All characters are invalid. Produce a default value.
 		if firstUpper {
@@ -329,7 +328,7 @@ func protoBufifyAtt(att *expr.AttributeExpr, name string, upper bool) string {
 			name = tname[0]
 		}
 	}
-	return protoBufify(name, upper)
+	return protoBufify(name, upper, false)
 }
 
 // protoBufNativeMessageTypeName returns the protocol buffer built-in type
diff --git a/grpc/codegen/service_data.go b/grpc/codegen/service_data.go
index e5963672..bf3b5d35 100644
--- a/grpc/codegen/service_data.go
+++ b/grpc/codegen/service_data.go
@@ -451,16 +451,16 @@ func (d ServicesData) analyze(gs *expr.GRPCServiceExpr) *ServiceData {
 	}
 	for _, e := range gs.GRPCEndpoints {
 		// convert request and response types to protocol buffer message types
-		e.Request = makeProtoBufMessage(e.Request, protoBufify(e.Name()+"_request", true), sd)
+		e.Request = makeProtoBufMessage(e.Request, protoBufify(e.Name()+"_request", true, true), sd)
 		if e.MethodExpr.StreamingPayload.Type != expr.Empty {
-			e.StreamingRequest = makeProtoBufMessage(e.StreamingRequest, protoBufify(e.Name()+"_streaming_request", true), sd)
+			e.StreamingRequest = makeProtoBufMessage(e.StreamingRequest, protoBufify(e.Name()+"_streaming_request", true, true), sd)
 		}
-		e.Response.Message = makeProtoBufMessage(e.Response.Message, protoBufify(e.Name()+"_response", true), sd)
+		e.Response.Message = makeProtoBufMessage(e.Response.Message, protoBufify(e.Name()+"_response", true, true), sd)
 		for _, er := range e.GRPCErrors {
 			if er.ErrorExpr.Type == expr.ErrorResult || !expr.IsObject(er.ErrorExpr.Type) {
 				continue
 			}
-			er.Response.Message = makeProtoBufMessage(er.Response.Message, protoBufify(e.Name()+"_"+er.Name+"_error", true), sd)
+			er.Response.Message = makeProtoBufMessage(er.Response.Message, protoBufify(e.Name()+"_"+er.Name+"_error", true, true), sd)
 		}
 
 		// collect all the nested messages and return the top-level message
diff --git a/http/codegen/client.go b/http/codegen/client.go
index a238cffd..65b191cd 100644
--- a/http/codegen/client.go
+++ b/http/codegen/client.go
@@ -395,12 +395,12 @@ func {{ .RequestEncoder }}(encoder func(*http.Request) goahttp.Encoder) func(*ht
 			{{- else }}
 			{
 			{{- end }}
+			head := {{ if .FieldPointer }}*{{ end }}p.{{ .FieldName }}
 			{{- if (and (eq .Name "Authorization") (isBearer $.HeaderSchemes)) }}
-		if !strings.Contains({{ if .FieldPointer }}*{{ end }}p.{{ .FieldName }}, " ") {
-			req.Header.Set({{ printf "%q" .Name }}, "Bearer "+{{ if .FieldPointer }}*{{ end }}p.{{ .FieldName }})
+		if !strings.Contains(head, " ") {
+			req.Header.Set({{ printf "%q" .Name }}, "Bearer "+head)
 		} else {
 			{{- end }}
-			head := {{ if .FieldPointer }}*{{ end }}p.{{ .FieldName }}
 			{{- if eq .Type.Name "array" }}
 			for _, val := range head {
 				{{- if eq .Type.ElemType.Type.Name "string" }}
diff --git a/http/codegen/openapi/openapi_v2_builder.go b/http/codegen/openapi/openapi_v2_builder.go
index 331035e4..ef2c1ba9 100644
--- a/http/codegen/openapi/openapi_v2_builder.go
+++ b/http/codegen/openapi/openapi_v2_builder.go
@@ -60,15 +60,6 @@ func NewV2(root *expr.RootExpr, h *expr.HostExpr) (*V2, error) {
 		SecurityDefinitions: securitySpecFromExpr(root),
 		ExternalDocs:        docsFromExpr(root.API.Docs),
 	}
-
-	for _, he := range root.API.HTTP.Errors {
-		res := responseSpecFromExpr(s, root, he.Response, "")
-		if s.Responses == nil {
-			s.Responses = make(map[string]*Response)
-		}
-		s.Responses[he.Name] = res
-	}
-
 	for _, res := range root.API.HTTP.Services {
 		if !mustGenerate(res.Meta) || !mustGenerate(res.ServiceExpr.Meta) {
 			continue
diff --git a/http/codegen/server.go b/http/codegen/server.go
index 6d2afe92..b3b74226 100644
--- a/http/codegen/server.go
+++ b/http/codegen/server.go
@@ -1102,6 +1102,9 @@ func {{ .ErrorEncoder }}(encoder func(context.Context, http.ResponseWriter) goah
 		case {{ printf "%q" .Name }}:
 			res := v.({{ $err.Ref }})
 			{{- with .Response}}
+				{{- if .ContentType }}
+					ctx = context.WithValue(ctx, goahttp.ContentTypeKey, "{{ .ContentType }}")
+				{{- end }}
 				{{- template "response" . }}
 				{{- if .ServerBody }}
 				return enc.Encode(body)
diff --git a/http/codegen/service_data.go b/http/codegen/service_data.go
index f9c7c32b..f7ea71d5 100644
--- a/http/codegen/service_data.go
+++ b/http/codegen/service_data.go
@@ -121,6 +121,9 @@ type (
 		// apply to the method and are encoded in the request query
 		// string.
 		QuerySchemes service.SchemesData
+		// Requirements contains the security requirements for the
+		// method.
+		Requirements service.RequirementsData
 
 		// server
 
@@ -764,14 +767,19 @@ func (d ServicesData) analyze(hs *expr.HTTPServiceExpr) *ServiceData {
 		payload := buildPayloadData(a, rd)
 
 		var (
+			reqs  service.RequirementsData
 			hsch  service.SchemesData
 			bosch service.SchemesData
 			qsch  service.SchemesData
 			basch *service.SchemeData
 		)
 		{
-			for _, req := range ep.Requirements {
-				for _, s := range req.Schemes {
+
+			for _, req := range a.Requirements {
+				var rs service.SchemesData
+				for _, sch := range req.Schemes {
+					s := service.BuildSchemeData(sch, a.MethodExpr)
+					rs = rs.Append(s)
 					switch s.Type {
 					case "Basic":
 						basch = s
@@ -786,6 +794,7 @@ func (d ServicesData) analyze(hs *expr.HTTPServiceExpr) *ServiceData {
 						}
 					}
 				}
+				reqs = append(reqs, &service.RequirementData{Schemes: rs, Scopes: req.Scopes})
 			}
 		}
 
@@ -867,6 +876,7 @@ func (d ServicesData) analyze(hs *expr.HTTPServiceExpr) *ServiceData {
 			RequestInit:     requestInit,
 			RequestEncoder:  requestEncoder,
 			ResponseDecoder: fmt.Sprintf("Decode%sResponse", ep.VarName),
+			Requirements:    reqs,
 		}
 		if a.MethodExpr.IsStreaming() {
 			initWebSocketData(ad, a, rd)
@@ -1796,9 +1806,14 @@ func buildErrorsData(e *expr.HTTPEndpointExpr, sd *ServiceData) []*ErrorGroupDat
 					}
 				}
 			}
+			var contentType string
+			if v.Response.ContentType != expr.ErrorResultIdentifier {
+				contentType = v.Response.ContentType
+			}
 			responseData = &ResponseData{
 				StatusCode:   statusCodeToHTTPConst(v.Response.StatusCode),
 				Headers:      headers,
+				ContentType:  contentType,
 				ErrorHeader:  v.Name,
 				ServerBody:   serverBodyData,
 				ClientBody:   clientBodyData,
diff --git a/pkg/version.go b/pkg/version.go
index 8efcc5c3..5d2da221 100644
--- a/pkg/version.go
+++ b/pkg/version.go
@@ -12,7 +12,7 @@ const (
 	// Minor version number
 	Minor = 1
 	// Build number
-	Build = 2
+	Build = 3
 	// Suffix - set to empty string in release tag commits.
 	Suffix = ""
 )


Test patch:
diff --git a/codegen/funcs_test.go b/codegen/funcs_test.go
index 7b8f5bbc..0be4c956 100644
--- a/codegen/funcs_test.go
+++ b/codegen/funcs_test.go
@@ -36,26 +36,34 @@ func TestSnakeCase(t *testing.T) {
 
 func TestCamelCase(t *testing.T) {
 	cases := map[string]struct {
-		str         string
-		firstUpper  bool
-		useAcronyum bool
-		expected    string
+		str        string
+		firstUpper bool
+		useAcronym bool
+		expected   string
 	}{
-		"all lower":             {"aaa", false, true, "aaa"},
-		"all lower first upper": {"aaa", true, true, "Aaa"},
-		"start upper":           {"Aaa", false, true, "aaa"},
-		"mid upper":             {"a_aa", false, true, "aAa"},
-		"end upper":             {"aa_a", false, true, "aaA"},
-		"sequential uppers":     {"aa_aaaa", false, true, "aaAaaa"},
-		"end sequential uppers": {"aa_aa", false, true, "aaAa"},
-		"multiple_uppers":       {"aa_aaa_aaa", false, true, "aaAaaAaa"},
-		"underscores":           {"aa_aaa_aaa", false, true, "aaAaaAaa"},
-		"acronym":               {"aa_id", false, true, "aaID"},
-		"disable acronym":       {"aa_id", false, false, "aaId"},
+		"all lower":                     {"aaa", false, true, "aaa"},
+		"all lower first upper":         {"aaa", true, true, "Aaa"},
+		"start upper":                   {"Aaa", false, true, "aaa"},
+		"mid upper":                     {"a_aa", false, true, "aAa"},
+		"end upper":                     {"aa_a", false, true, "aaA"},
+		"sequential uppers":             {"aa_aaaa", false, true, "aaAaaa"},
+		"end sequential uppers":         {"aa_aa", false, true, "aaAa"},
+		"multiple_uppers":               {"aa_aaa_aaa", false, true, "aaAaaAaa"},
+		"underscores":                   {"aa_aaa_aaa", false, true, "aaAaaAaa"},
+		"acronym":                       {"aa_id", false, true, "aaID"},
+		"lower camel case":              {"aa_id", false, false, "aaId"},
+		"upper camel case":              {"aaID", false, true, "aaID"},
+		"lower camel case with acronym": {"aaId", false, true, "aaID"},
+
+		"disable acronym":                    {"aa_id", false, false, "aaId"},
+		"disable acronym first upper":        {"aaID", true, false, "AaId"},
+		"disable acronym upper case acronym": {"aa_ID", false, false, "aaId"},
+		"disable acronym upper camel case":   {"aaID", false, false, "aaId"},
+		"disable acronym lower camel case":   {"aaId", false, false, "aaId"},
 	}
 	for k, tc := range cases {
 		t.Run(k, func(t *testing.T) {
-			actual := CamelCase(tc.str, tc.firstUpper, tc.useAcronyum)
+			actual := CamelCase(tc.str, tc.firstUpper, tc.useAcronym)
 			if actual != tc.expected {
 				t.Errorf("got %q, expected %q", actual, tc.expected)
 			}
diff --git a/codegen/service/convert_test.go b/codegen/service/convert_test.go
index 8fe82f77..ab4d42c7 100644
--- a/codegen/service/convert_test.go
+++ b/codegen/service/convert_test.go
@@ -246,6 +246,7 @@ func TestConvertFile(t *testing.T) {
 		{"create-object-extra", testdata.CreateObjectExtraDSL, 1, testdata.CreateObjectExtraCode},
 		{"create-external-convert", testdata.CreateExternalDSL, 0, testdata.CreateExternalConvert},
 		{"create-alias-convert", testdata.CreateAliasDSL, 0, testdata.CreateAliasConvert},
+		{"mixed-case-convert", testdata.MixedCaseDSL, 0, testdata.MixedCaseConvert},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
diff --git a/codegen/service/testdata/create_dsls.go b/codegen/service/testdata/create_dsls.go
index 3542ac69..4fb2a428 100644
--- a/codegen/service/testdata/create_dsls.go
+++ b/codegen/service/testdata/create_dsls.go
@@ -248,3 +248,18 @@ var CreateAliasDSL = func() {
 		})
 	})
 }
+
+var MixedCaseDSL = func() {
+	var StringType = Type("StringType", func() {
+		CreateFrom(external.MixedCaseModel{})
+		Attribute("lowerCamelId", String)
+		Attribute("UpperCamelID", String)
+		Attribute("snake_id", String)
+	})
+
+	Service("Service", func() {
+		Method("Method", func() {
+			Payload(StringType)
+		})
+	})
+}
diff --git a/codegen/service/testdata/create_functions.go b/codegen/service/testdata/create_functions.go
index 1dfa0a83..1aa5e005 100644
--- a/codegen/service/testdata/create_functions.go
+++ b/codegen/service/testdata/create_functions.go
@@ -149,3 +149,25 @@ func (t *StringType) CreateFromConvertModel(v *aliasd.ConvertModel) {
 	*t = *temp
 }
 `
+
+var MixedCaseConvert = `// Service service type conversion functions
+//
+// Command:
+// $ goa
+
+package service
+
+import (
+	external "goa.design/goa/v3/codegen/service/testdata/external"
+)
+
+// CreateFromMixedCaseModel initializes t from the fields of v
+func (t *StringType) CreateFromMixedCaseModel(v *external.MixedCaseModel) {
+	temp := &StringType{
+		LowerCamelID: &v.LowerCamelID,
+		UpperCamelID: &v.UpperCamelID,
+		SnakeID:      &v.SnakeID,
+	}
+	*t = *temp
+}
+`
diff --git a/codegen/service/testdata/external/external.go b/codegen/service/testdata/external/external.go
index 03961783..88b8285e 100644
--- a/codegen/service/testdata/external/external.go
+++ b/codegen/service/testdata/external/external.go
@@ -3,3 +3,9 @@ package external
 type ConvertModel struct {
 	Foo string
 }
+
+type MixedCaseModel struct {
+	LowerCamelID string
+	UpperCamelID string
+	SnakeID      string
+}
diff --git a/expr/http_endpoint_test.go b/expr/http_endpoint_test.go
index 21b32037..0b157237 100644
--- a/expr/http_endpoint_test.go
+++ b/expr/http_endpoint_test.go
@@ -154,6 +154,12 @@ service "Service" HTTP endpoint "Method": HTTP endpoint response body must be em
 			DSL:   testdata.EndpointPayloadMissingRequired,
 			Error: `service "Service" HTTP endpoint "Method": The following HTTP request body attribute is required but the corresponding method payload attribute is not: nonreq. Use 'Required' to make the attribute required in the method payload as well.`,
 		},
+		"streaming-endpoint-has-request-body": {
+			DSL: testdata.StreamingEndpointRequestBody,
+			Error: `service "Service" HTTP endpoint "MethodA": HTTP endpoint request body must be empty when the endpoint uses streaming. Payload attributes must be mapped to headers and/or params.
+service "Service" HTTP endpoint "MethodB": HTTP endpoint request body must be empty when the endpoint uses streaming. Payload attributes must be mapped to headers and/or params.
+service "Service" HTTP endpoint "MethodC": HTTP endpoint request body must be empty when the endpoint uses streaming. Payload attributes must be mapped to headers and/or params.`,
+		},
 	}
 	for name, c := range cases {
 		t.Run(name, func(t *testing.T) {
diff --git a/expr/testdata/endpoint_dsls.go b/expr/testdata/endpoint_dsls.go
index a9d55713..0aa36621 100644
--- a/expr/testdata/endpoint_dsls.go
+++ b/expr/testdata/endpoint_dsls.go
@@ -427,6 +427,66 @@ var EndpointPayloadMissingRequired = func() {
 	})
 }
 
+var StreamingEndpointRequestBody = func() {
+	var PT = Type("Payload", func() {
+		Attribute("foo", String)
+	})
+	Service("Service", func() {
+		Method("MethodA", func() {
+			Payload(func() {
+				Attribute("bar", String)
+			})
+			StreamingResult(String)
+			HTTP(func() {
+				GET("/")
+			})
+		})
+		Method("MethodB", func() {
+			Payload(func() {
+				Extend(PT)
+			})
+			StreamingResult(String)
+			HTTP(func() {
+				GET("/")
+			})
+		})
+		Method("MethodC", func() {
+			Payload(String)
+			StreamingResult(String)
+			HTTP(func() {
+				GET("/")
+			})
+		})
+		Method("MethodD", func() {
+			Payload(func() {
+				Attribute("bar", String)
+			})
+			StreamingResult(String)
+			HTTP(func() {
+				GET("/{bar}")
+			})
+		})
+		Method("MethodE", func() {
+			Payload(func() {
+				Extend(PT)
+			})
+			StreamingResult(String)
+			HTTP(func() {
+				GET("/")
+				Param("foo")
+			})
+		})
+		Method("MethodF", func() {
+			Payload(String)
+			StreamingResult(String)
+			HTTP(func() {
+				GET("/")
+				Header("foo")
+			})
+		})
+	})
+}
+
 var FinalizeEndpointBodyAsExtendedTypeDSL = func() {
 	var EntityData = Type("EntityData", func() {
 		Attribute("name", String)
diff --git a/grpc/codegen/testdata/streaming_code.go b/grpc/codegen/testdata/streaming_code.go
index a6e43132..2b7068ac 100644
--- a/grpc/codegen/testdata/streaming_code.go
+++ b/grpc/codegen/testdata/streaming_code.go
@@ -328,7 +328,7 @@ func (s *MethodBidirectionalStreamingRPCClientStream) Recv() (*servicebidirectio
 	if err != nil {
 		return res, err
 	}
-	proj := NewIdView(v)
+	proj := NewIDView(v)
 	vres := &servicebidirectionalstreamingrpcviews.ID{Projected: proj, View: "default"}
 	return servicebidirectionalstreamingrpc.NewID(vres), nil
 }
diff --git a/grpc/middleware/xray/middleware_test.go b/grpc/middleware/xray/middleware_test.go
index 720698c9..7bf8b35a 100644
--- a/grpc/middleware/xray/middleware_test.go
+++ b/grpc/middleware/xray/middleware_test.go
@@ -63,7 +63,7 @@ func TestNewUnaryServer(t *testing.T) {
 		Success bool
 	}{
 		"ok":     {udplisten, true},
-		"not-ok": {"1002.0.0.0:62111", false},
+		"not-ok": {"foo:bar", false},
 	}
 	for k, c := range cases {
 		t.Run(k, func(t *testing.T) {
@@ -87,7 +87,7 @@ func TestNewStreamServer(t *testing.T) {
 		Success bool
 	}{
 		"ok":     {udplisten, true},
-		"not-ok": {"1002.0.0.0:62111", false},
+		"not-ok": {"foo:bar", false},
 	}
 	for k, c := range cases {
 		t.Run(k, func(t *testing.T) {
diff --git a/http/codegen/client_body_types_test.go b/http/codegen/client_body_types_test.go
index 29d419c1..8149035f 100644
--- a/http/codegen/client_body_types_test.go
+++ b/http/codegen/client_body_types_test.go
@@ -116,7 +116,7 @@ func TestClientTypeFiles(t *testing.T) {
 				}
 				code := codegen.FormatTestCode(t, "package foo\n"+buf.String())
 				if code != c.Codes[i] {
-					t.Errorf("invalid code at inded %d, got:\n%s\ngot vs. expected:\n%s", i, code, codegen.Diff(t, code, c.Codes[i]))
+					t.Errorf("invalid code at index %d, got:\n%s\ngot vs. expected:\n%s", i, code, codegen.Diff(t, code, c.Codes[i]))
 				}
 			}
 		})
@@ -365,13 +365,7 @@ func NewMethodQueryStringExtendedValidatePayloadRequestBody(p *servicequerystrin
 `
 
 var MultipleServicesSamePayloadAndResultClientTypesFiles = []string{
-	`// ListRequestBody is the type of the "ServiceA" service "list" endpoint HTTP
-// request body.
-type ListRequestBody struct {
-	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + "`" + `
-}
-
-// ListStreamingBody is the type of the "ServiceA" service "list" endpoint HTTP
+	`// ListStreamingBody is the type of the "ServiceA" service "list" endpoint HTTP
 // request body.
 type ListStreamingBody struct {
 	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + "`" + `
@@ -402,15 +396,6 @@ type ListSomethingWentWrongResponseBody struct {
 	Fault *bool ` + "`" + `form:"fault,omitempty" json:"fault,omitempty" xml:"fault,omitempty"` + "`" + `
 }
 
-// NewListRequestBody builds the HTTP request body from the payload of the
-// "list" endpoint of the "ServiceA" service.
-func NewListRequestBody(p *servicea.ListPayload) *ListRequestBody {
-	body := &ListRequestBody{
-		Name: p.Name,
-	}
-	return body
-}
-
 // NewListStreamingBody builds the HTTP request body from the payload of the
 // "list" endpoint of the "ServiceA" service.
 func NewListStreamingBody(p *servicea.ListStreamingPayload) *ListStreamingBody {
@@ -481,13 +466,7 @@ func ValidateListSomethingWentWrongResponseBody(body *ListSomethingWentWrongResp
 	return
 }
 `,
-	`// ListRequestBody is the type of the "ServiceB" service "list" endpoint HTTP
-// request body.
-type ListRequestBody struct {
-	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + "`" + `
-}
-
-// ListStreamingBody is the type of the "ServiceB" service "list" endpoint HTTP
+	`// ListStreamingBody is the type of the "ServiceB" service "list" endpoint HTTP
 // request body.
 type ListStreamingBody struct {
 	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + "`" + `
@@ -518,15 +497,6 @@ type ListSomethingWentWrongResponseBody struct {
 	Fault *bool ` + "`" + `form:"fault,omitempty" json:"fault,omitempty" xml:"fault,omitempty"` + "`" + `
 }
 
-// NewListRequestBody builds the HTTP request body from the payload of the
-// "list" endpoint of the "ServiceB" service.
-func NewListRequestBody(p *serviceb.ListPayload) *ListRequestBody {
-	body := &ListRequestBody{
-		Name: p.Name,
-	}
-	return body
-}
-
 // NewListStreamingBody builds the HTTP request body from the payload of the
 // "list" endpoint of the "ServiceB" service.
 func NewListStreamingBody(p *serviceb.ListStreamingPayload) *ListStreamingBody {
diff --git a/http/codegen/client_encode_test.go b/http/codegen/client_encode_test.go
index 90ab490c..2cdd7163 100644
--- a/http/codegen/client_encode_test.go
+++ b/http/codegen/client_encode_test.go
@@ -94,6 +94,7 @@ func TestClientEncode(t *testing.T) {
 
 		{"query-string-default", testdata.PayloadQueryStringDefaultDSL, testdata.PayloadQueryStringDefaultEncodeCode},
 		{"query-primitive-string-default", testdata.PayloadQueryPrimitiveStringDefaultDSL, testdata.PayloadQueryPrimitiveStringDefaultEncodeCode},
+		{"query-jwt-authorization", testdata.PayloadJWTAuthorizationQueryDSL, testdata.PayloadJWTAuthorizationQueryEncodeCode},
 
 		{"header-string", testdata.PayloadHeaderStringDSL, testdata.PayloadHeaderStringEncodeCode},
 		{"header-string-validate", testdata.PayloadHeaderStringValidateDSL, testdata.PayloadHeaderStringValidateEncodeCode},
@@ -111,6 +112,8 @@ func TestClientEncode(t *testing.T) {
 
 		{"header-string-default", testdata.PayloadHeaderStringDefaultDSL, testdata.PayloadHeaderStringDefaultEncodeCode},
 		{"header-primitive-string-default", testdata.PayloadHeaderPrimitiveStringDefaultDSL, testdata.PayloadHeaderPrimitiveStringDefaultEncodeCode},
+		{"header-jwt-authorization", testdata.PayloadJWTAuthorizationHeaderDSL, testdata.PayloadJWTAuthorizationHeaderEncodeCode},
+		{"header-jwt-custom-header", testdata.PayloadJWTAuthorizationCustomHeaderDSL, testdata.PayloadJWTAuthorizationCustomHeaderEncodeCode},
 
 		{"body-string", testdata.PayloadBodyStringDSL, testdata.PayloadBodyStringEncodeCode},
 		{"body-string-validate", testdata.PayloadBodyStringValidateDSL, testdata.PayloadBodyStringValidateEncodeCode},
diff --git a/http/codegen/paths_test.go b/http/codegen/paths_test.go
index 6b0f43cc..2dc12b56 100644
--- a/http/codegen/paths_test.go
+++ b/http/codegen/paths_test.go
@@ -15,9 +15,7 @@ func TestPaths(t *testing.T) {
 		Code string
 	}{
 		{"single-path-no-param", testdata.PathNoParamDSL, testdata.PathNoParamCode},
-		{"single-path-no-param-trailing-slash", testdata.PathNoParamTrailingSlashDSL, testdata.PathNoParamTrailingSlashCode},
 		{"single-path-one-param", testdata.PathOneParamDSL, testdata.PathOneParamCode},
-		{"single-path-one-param-trailing-slash", testdata.PathOneParamTrailingSlashDSL, testdata.PathOneParamTrailingSlashCode},
 		{"single-path-multiple-params", testdata.PathMultipleParamsDSL, testdata.PathMultipleParamsCode},
 		{"alternative-paths", testdata.PathAlternativesDSL, testdata.PathAlternativesCode},
 		{"path-with-string-slice-param", testdata.PathStringSliceParamDSL, testdata.PathStringSliceParamCode},
@@ -48,3 +46,33 @@ func TestPaths(t *testing.T) {
 		})
 	}
 }
+
+func TestPathTrailingShash(t *testing.T) {
+	cases := []struct {
+		Name string
+		DSL  func()
+		Code string
+	}{
+		{"slash_with_base_path_no_trailing", testdata.BasePathNoTrailing_SlashWithBasePathNoTrailingDSL, testdata.BasePathNoTrailing_SlashWithBasePathNoTrailingCode},
+		{"trailing_with_base_path_no_trailing", testdata.BasePathNoTrailing_TrailingWithBasePathNoTrailingDSL, testdata.BasePathNoTrailing_TrailingWithBasePathNoTrailingCode},
+		{"slash_with_base_path_with_trailing", testdata.BasePathWithTrailingSlash_WithBasePathWithTrailingDSL, testdata.BasePathWithTrailingSlash_WithBasePathWithTrailingCode},
+		{"slash_no_base_path", testdata.NoBasePath_SlashNoBasePathDSL, testdata.NoBasePath_SlashNoBasePathCode},
+		{"path-trailing_no_base_path", testdata.NoBasePath_TrailingNoBasePathDSL, testdata.NoBasePath_TrailingNoBasePathCode},
+		{"add-trailing-slash-to-base-path", testdata.BasePath_SpecialTrailingSlashDSL, testdata.BasePath_SpecialTrailingSlashCode},
+	}
+
+	for _, c := range cases {
+		t.Run(c.Name, func(t *testing.T) {
+			RunHTTPDSL(t, c.DSL)
+			if len(expr.Root.API.HTTP.Services) != 1 {
+				t.Fatalf("got %d file(s), expected 1", len(expr.Root.API.HTTP.Services))
+			}
+			fs := serverPath(expr.Root.API.HTTP.Services[0])
+			sections := fs.SectionTemplates
+			code := codegen.SectionCode(t, sections[1])
+			if code != c.Code {
+				t.Errorf("invalid code, got:\n%s\ngot vs. expected:\n%s", code, codegen.Diff(t, code, c.Code))
+			}
+		})
+	}
+}
diff --git a/http/codegen/server_error_encoder_test.go b/http/codegen/server_error_encoder_test.go
index 11c1d11f..bf070e09 100644
--- a/http/codegen/server_error_encoder_test.go
+++ b/http/codegen/server_error_encoder_test.go
@@ -16,8 +16,14 @@ func TestEncodeError(t *testing.T) {
 	}{
 		{"primitive-error-response", testdata.PrimitiveErrorResponseDSL, testdata.PrimitiveErrorResponseEncoderCode},
 		{"default-error-response", testdata.DefaultErrorResponseDSL, testdata.DefaultErrorResponseEncoderCode},
+		{"default-error-response-with-content-type", testdata.DefaultErrorResponseWithContentTypeDSL, testdata.DefaultErrorResponseWithContentTypeEncoderCode},
 		{"service-error-response", testdata.ServiceErrorResponseDSL, testdata.ServiceErrorResponseEncoderCode},
+		{"api-error-response", testdata.APIErrorResponseDSL, testdata.ServiceErrorResponseEncoderCode},
+		{"api-error-response-with-content-type", testdata.APIErrorResponseWithContentTypeDSL, testdata.ServiceErrorResponseWithContentTypeEncoderCode},
 		{"no-body-error-response", testdata.NoBodyErrorResponseDSL, testdata.NoBodyErrorResponseEncoderCode},
+		{"no-body-error-response-with-content-type", testdata.NoBodyErrorResponseWithContentTypeDSL, testdata.NoBodyErrorResponseWithContentTypeEncoderCode},
+		{"api-no-body-error-response", testdata.APINoBodyErrorResponseDSL, testdata.NoBodyErrorResponseEncoderCode},
+		{"api-no-body-error-response-with-content-type", testdata.APINoBodyErrorResponseWithContentTypeDSL, testdata.NoBodyErrorResponseWithContentTypeEncoderCode},
 	}
 	for _, c := range cases {
 		t.Run(c.Name, func(t *testing.T) {
diff --git a/http/codegen/testdata/error_encoder_code.go b/http/codegen/testdata/error_encoder_code.go
index e93144bb..d11d2484 100644
--- a/http/codegen/testdata/error_encoder_code.go
+++ b/http/codegen/testdata/error_encoder_code.go
@@ -71,6 +71,36 @@ func EncodeMethodDefaultErrorResponseError(encoder func(context.Context, http.Re
 }
 `
 
+var DefaultErrorResponseWithContentTypeEncoderCode = `// EncodeMethodDefaultErrorResponseError returns an encoder for errors returned
+// by the MethodDefaultErrorResponse ServiceDefaultErrorResponse endpoint.
+func EncodeMethodDefaultErrorResponseError(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, formatter func(err error) goahttp.Statuser) func(context.Context, http.ResponseWriter, error) error {
+	encodeError := goahttp.ErrorEncoder(encoder, formatter)
+	return func(ctx context.Context, w http.ResponseWriter, v error) error {
+		en, ok := v.(ErrorNamer)
+		if !ok {
+			return encodeError(ctx, w, v)
+		}
+		switch en.ErrorName() {
+		case "bad_request":
+			res := v.(*goa.ServiceError)
+			ctx = context.WithValue(ctx, goahttp.ContentTypeKey, "application/xml")
+			enc := encoder(ctx, w)
+			var body interface{}
+			if formatter != nil {
+				body = formatter(res)
+			} else {
+				body = NewMethodDefaultErrorResponseBadRequestResponseBody(res)
+			}
+			w.Header().Set("goa-error", "bad_request")
+			w.WriteHeader(http.StatusBadRequest)
+			return enc.Encode(body)
+		default:
+			return encodeError(ctx, w, v)
+		}
+	}
+}
+`
+
 var ServiceErrorResponseEncoderCode = `// EncodeMethodServiceErrorResponseError returns an encoder for errors returned
 // by the MethodServiceErrorResponse ServiceServiceErrorResponse endpoint.
 func EncodeMethodServiceErrorResponseError(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, formatter func(err error) goahttp.Statuser) func(context.Context, http.ResponseWriter, error) error {
@@ -112,6 +142,48 @@ func EncodeMethodServiceErrorResponseError(encoder func(context.Context, http.Re
 }
 `
 
+var ServiceErrorResponseWithContentTypeEncoderCode = `// EncodeMethodServiceErrorResponseError returns an encoder for errors returned
+// by the MethodServiceErrorResponse ServiceServiceErrorResponse endpoint.
+func EncodeMethodServiceErrorResponseError(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, formatter func(err error) goahttp.Statuser) func(context.Context, http.ResponseWriter, error) error {
+	encodeError := goahttp.ErrorEncoder(encoder, formatter)
+	return func(ctx context.Context, w http.ResponseWriter, v error) error {
+		en, ok := v.(ErrorNamer)
+		if !ok {
+			return encodeError(ctx, w, v)
+		}
+		switch en.ErrorName() {
+		case "internal_error":
+			res := v.(*goa.ServiceError)
+			enc := encoder(ctx, w)
+			var body interface{}
+			if formatter != nil {
+				body = formatter(res)
+			} else {
+				body = NewMethodServiceErrorResponseInternalErrorResponseBody(res)
+			}
+			w.Header().Set("goa-error", "internal_error")
+			w.WriteHeader(http.StatusInternalServerError)
+			return enc.Encode(body)
+		case "bad_request":
+			res := v.(*goa.ServiceError)
+			ctx = context.WithValue(ctx, goahttp.ContentTypeKey, "application/xml")
+			enc := encoder(ctx, w)
+			var body interface{}
+			if formatter != nil {
+				body = formatter(res)
+			} else {
+				body = NewMethodServiceErrorResponseBadRequestResponseBody(res)
+			}
+			w.Header().Set("goa-error", "bad_request")
+			w.WriteHeader(http.StatusBadRequest)
+			return enc.Encode(body)
+		default:
+			return encodeError(ctx, w, v)
+		}
+	}
+}
+`
+
 var NoBodyErrorResponseEncoderCode = `// EncodeMethodServiceErrorResponseError returns an encoder for errors returned
 // by the MethodServiceErrorResponse ServiceNoBodyErrorResponse endpoint.
 func EncodeMethodServiceErrorResponseError(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, formatter func(err error) goahttp.Statuser) func(context.Context, http.ResponseWriter, error) error {
@@ -136,3 +208,29 @@ func EncodeMethodServiceErrorResponseError(encoder func(context.Context, http.Re
 	}
 }
 `
+
+var NoBodyErrorResponseWithContentTypeEncoderCode = `// EncodeMethodServiceErrorResponseError returns an encoder for errors returned
+// by the MethodServiceErrorResponse ServiceNoBodyErrorResponse endpoint.
+func EncodeMethodServiceErrorResponseError(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, formatter func(err error) goahttp.Statuser) func(context.Context, http.ResponseWriter, error) error {
+	encodeError := goahttp.ErrorEncoder(encoder, formatter)
+	return func(ctx context.Context, w http.ResponseWriter, v error) error {
+		en, ok := v.(ErrorNamer)
+		if !ok {
+			return encodeError(ctx, w, v)
+		}
+		switch en.ErrorName() {
+		case "bad_request":
+			res := v.(*servicenobodyerrorresponse.StringError)
+			ctx = context.WithValue(ctx, goahttp.ContentTypeKey, "application/xml")
+			if res.Header != nil {
+				w.Header().Set("Header", *res.Header)
+			}
+			w.Header().Set("goa-error", "bad_request")
+			w.WriteHeader(http.StatusBadRequest)
+			return nil
+		default:
+			return encodeError(ctx, w, v)
+		}
+	}
+}
+`
diff --git a/http/codegen/testdata/error_response_dsls.go b/http/codegen/testdata/error_response_dsls.go
index 902c7b4d..08842133 100644
--- a/http/codegen/testdata/error_response_dsls.go
+++ b/http/codegen/testdata/error_response_dsls.go
@@ -16,6 +16,20 @@ var DefaultErrorResponseDSL = func() {
 	})
 }
 
+var DefaultErrorResponseWithContentTypeDSL = func() {
+	Service("ServiceDefaultErrorResponse", func() {
+		Method("MethodDefaultErrorResponse", func() {
+			Error("bad_request")
+			HTTP(func() {
+				GET("/one/two")
+				Response("bad_request", StatusBadRequest, func() {
+					ContentType("application/xml")
+				})
+			})
+		})
+	})
+}
+
 var PrimitiveErrorResponseDSL = func() {
 	Service("ServicePrimitiveErrorResponse", func() {
 		Method("MethodPrimitiveErrorResponse", func() {
@@ -46,6 +60,89 @@ var ServiceErrorResponseDSL = func() {
 	})
 }
 
+var APIErrorResponseDSL = func() {
+	var _ = API("test", func() {
+		Error("bad_request")
+		HTTP(func() {
+			Response(StatusBadRequest, "bad_request")
+		})
+	})
+	Service("ServiceServiceErrorResponse", func() {
+		Method("MethodServiceErrorResponse", func() {
+			Error("bad_request")
+			Error("internal_error")
+			HTTP(func() {
+				GET("/one/two")
+				Response("internal_error", StatusInternalServerError)
+			})
+		})
+	})
+}
+
+var APIErrorResponseWithContentTypeDSL = func() {
+	var _ = API("test", func() {
+		Error("bad_request")
+		HTTP(func() {
+			Response(StatusBadRequest, "bad_request", func() {
+				ContentType("application/xml")
+			})
+		})
+	})
+	Service("ServiceServiceErrorResponse", func() {
+		Method("MethodServiceErrorResponse", func() {
+			Error("bad_request")
+			Error("internal_error")
+			HTTP(func() {
+				GET("/one/two")
+				Response("internal_error", StatusInternalServerError)
+			})
+		})
+	})
+}
+
+var APINoBodyErrorResponseDSL = func() {
+	var StringError = Type("StringError", func() { Attribute("header") })
+	var _ = API("test", func() {
+		Error("bad_request", StringError)
+		HTTP(func() {
+			Response("bad_request", StatusBadRequest, func() {
+				Header("header")
+			})
+		})
+	})
+	Service("ServiceNoBodyErrorResponse", func() {
+		Error("bad_request")
+		Method("MethodServiceErrorResponse", func() {
+			HTTP(func() {
+				GET("/one/two")
+			})
+		})
+	})
+}
+
+var APINoBodyErrorResponseWithContentTypeDSL = func() {
+	var StringError = ResultType("application/vnd.string.error", func() {
+		ContentType("application/xml")
+		Attribute("header")
+	})
+	var _ = API("test", func() {
+		Error("bad_request", StringError)
+		HTTP(func() {
+			Response("bad_request", StatusBadRequest, func() {
+				Header("header")
+			})
+		})
+	})
+	Service("ServiceNoBodyErrorResponse", func() {
+		Error("bad_request")
+		Method("MethodServiceErrorResponse", func() {
+			HTTP(func() {
+				GET("/one/two")
+			})
+		})
+	})
+}
+
 var NoBodyErrorResponseDSL = func() {
 	var StringError = Type("StringError", func() { Attribute("header") })
 	Service("ServiceNoBodyErrorResponse", func() {
@@ -62,3 +159,23 @@ var NoBodyErrorResponseDSL = func() {
 		})
 	})
 }
+
+var NoBodyErrorResponseWithContentTypeDSL = func() {
+	var StringError = ResultType("application/vnd.string.error", func() {
+		ContentType("application/xml")
+		Attribute("header")
+	})
+	Service("ServiceNoBodyErrorResponse", func() {
+		Error("bad_request", StringError)
+		HTTP(func() {
+			Response("bad_request", StatusBadRequest, func() {
+				Header("header")
+			})
+		})
+		Method("MethodServiceErrorResponse", func() {
+			HTTP(func() {
+				GET("/one/two")
+			})
+		})
+	})
+}
diff --git a/http/codegen/testdata/path_dsls.go b/http/codegen/testdata/path_dsls.go
index e649382f..49cdb5b4 100644
--- a/http/codegen/testdata/path_dsls.go
+++ b/http/codegen/testdata/path_dsls.go
@@ -14,33 +14,84 @@ var PathNoParamDSL = func() {
 	})
 }
 
-var PathNoParamTrailingSlashDSL = func() {
-	Service("ServicePathNoParamTrailingSlash", func() {
-		Method("MethodPathNoParamTrailingSlash", func() {
+var BasePathNoTrailing_SlashWithBasePathNoTrailingDSL = func() {
+	Service("BasePathNoTrailing", func() {
+		HTTP(func() {
+			Path("foo")
+		})
+		Method("SlashWithBasePathNoTrailing", func() {
 			HTTP(func() {
-				GET("/one/two/")
+				GET("/")
 			})
 		})
 	})
 }
 
-var PathOneParamDSL = func() {
-	Service("ServicePathOneParam", func() {
-		Method("MethodPathOneParam", func() {
-			Payload(String)
+var BasePathNoTrailing_TrailingWithBasePathNoTrailingDSL = func() {
+	Service("BasePathNoTrailing", func() {
+		HTTP(func() {
+			Path("foo")
+		})
+		Method("TrailingWithBasePathNoTrailing", func() {
 			HTTP(func() {
-				GET("one/{a}/two")
+				GET("/bar/")
 			})
 		})
 	})
 }
 
-var PathOneParamTrailingSlashDSL = func() {
-	Service("ServicePathOneParamTrailingSlash", func() {
-		Method("MethodPathOneParamTrailingSlash", func() {
+var BasePathWithTrailingSlash_WithBasePathWithTrailingDSL = func() {
+	Service("BasePathWithTrailing", func() {
+		HTTP(func() {
+			Path("foo/")
+		})
+		Method("SlashWithBasePathWithTrailing", func() {
+			HTTP(func() {
+				GET("/")
+			})
+		})
+	})
+}
+
+var NoBasePath_SlashNoBasePathDSL = func() {
+	Service("NoBasePath", func() {
+		Method("SlashNoBasePath", func() {
+			HTTP(func() {
+				GET("/")
+			})
+		})
+	})
+}
+
+var NoBasePath_TrailingNoBasePathDSL = func() {
+	Service("NoBasePath", func() {
+		Method("TrailingNoBasePath", func() {
+			HTTP(func() {
+				GET("/foo/")
+			})
+		})
+	})
+}
+
+var BasePath_SpecialTrailingSlashDSL = func() {
+	Service("BasePath", func() {
+		HTTP(func() {
+			Path("/foo")
+		})
+		Method("SpecialTrailingSlash", func() {
+			HTTP(func() {
+				GET("/./")
+			})
+		})
+	})
+}
+
+var PathOneParamDSL = func() {
+	Service("ServicePathOneParam", func() {
+		Method("MethodPathOneParam", func() {
 			Payload(String)
 			HTTP(func() {
-				GET("one/{a}/")
+				GET("one/{a}/two")
 			})
 		})
 	})
diff --git a/http/codegen/testdata/path_functions.go b/http/codegen/testdata/path_functions.go
index 0378a7b4..aa24ec6b 100644
--- a/http/codegen/testdata/path_functions.go
+++ b/http/codegen/testdata/path_functions.go
@@ -6,21 +6,45 @@ func MethodPathNoParamServicePathNoParamPath() string {
 }
 `
 
-var PathNoParamTrailingSlashCode = `// MethodPathNoParamTrailingSlashServicePathNoParamTrailingSlashPath returns the URL path to the ServicePathNoParamTrailingSlash service MethodPathNoParamTrailingSlash HTTP endpoint.
-func MethodPathNoParamTrailingSlashServicePathNoParamTrailingSlashPath() string {
-	return "/one/two/"
+var BasePathNoTrailing_SlashWithBasePathNoTrailingCode = `// SlashWithBasePathNoTrailingBasePathNoTrailingPath returns the URL path to the BasePathNoTrailing service SlashWithBasePathNoTrailing HTTP endpoint.
+func SlashWithBasePathNoTrailingBasePathNoTrailingPath() string {
+	return "/foo"
 }
 `
 
-var PathOneParamCode = `// MethodPathOneParamServicePathOneParamPath returns the URL path to the ServicePathOneParam service MethodPathOneParam HTTP endpoint.
-func MethodPathOneParamServicePathOneParamPath(a string) string {
-	return fmt.Sprintf("/one/%v/two", a)
+var BasePathNoTrailing_TrailingWithBasePathNoTrailingCode = `// TrailingWithBasePathNoTrailingBasePathNoTrailingPath returns the URL path to the BasePathNoTrailing service TrailingWithBasePathNoTrailing HTTP endpoint.
+func TrailingWithBasePathNoTrailingBasePathNoTrailingPath() string {
+	return "/foo/bar/"
+}
+`
+
+var BasePathWithTrailingSlash_WithBasePathWithTrailingCode = `// SlashWithBasePathWithTrailingBasePathWithTrailingPath returns the URL path to the BasePathWithTrailing service SlashWithBasePathWithTrailing HTTP endpoint.
+func SlashWithBasePathWithTrailingBasePathWithTrailingPath() string {
+	return "/foo/"
+}
+`
+
+var NoBasePath_SlashNoBasePathCode = `// SlashNoBasePathNoBasePathPath returns the URL path to the NoBasePath service SlashNoBasePath HTTP endpoint.
+func SlashNoBasePathNoBasePathPath() string {
+	return "/"
 }
 `
 
-var PathOneParamTrailingSlashCode = `// MethodPathOneParamTrailingSlashServicePathOneParamTrailingSlashPath returns the URL path to the ServicePathOneParamTrailingSlash service MethodPathOneParamTrailingSlash HTTP endpoint.
-func MethodPathOneParamTrailingSlashServicePathOneParamTrailingSlashPath(a string) string {
-	return fmt.Sprintf("/one/%v/", a)
+var NoBasePath_TrailingNoBasePathCode = `// TrailingNoBasePathNoBasePathPath returns the URL path to the NoBasePath service TrailingNoBasePath HTTP endpoint.
+func TrailingNoBasePathNoBasePathPath() string {
+	return "/foo/"
+}
+`
+
+var BasePath_SpecialTrailingSlashCode = `// SpecialTrailingSlashBasePathPath returns the URL path to the BasePath service SpecialTrailingSlash HTTP endpoint.
+func SpecialTrailingSlashBasePathPath() string {
+	return "/foo/"
+}
+`
+
+var PathOneParamCode = `// MethodPathOneParamServicePathOneParamPath returns the URL path to the ServicePathOneParam service MethodPathOneParam HTTP endpoint.
+func MethodPathOneParamServicePathOneParamPath(a string) string {
+	return fmt.Sprintf("/one/%v/two", a)
 }
 `
 
diff --git a/http/codegen/testdata/payload_dsls.go b/http/codegen/testdata/payload_dsls.go
index bea7d82c..6a11e667 100644
--- a/http/codegen/testdata/payload_dsls.go
+++ b/http/codegen/testdata/payload_dsls.go
@@ -1338,6 +1338,24 @@ var PayloadQueryPrimitiveStringDefaultDSL = func() {
 	})
 }
 
+var PayloadJWTAuthorizationQueryDSL = func() {
+	var JWT = JWTSecurity("jwt", func() {
+		Scope("api:read")
+	})
+	Service("ServiceHeaderPrimitiveStringDefault", func() {
+		Method("MethodHeaderPrimitiveStringDefault", func() {
+			Security(JWT)
+			Payload(func() {
+				Token("token", String)
+			})
+			HTTP(func() {
+				GET("")
+				Param("token")
+			})
+		})
+	})
+}
+
 var PayloadExtendedQueryStringDSL = func() {
 	var UT = Type("UserType", func() {
 		Attribute("q", String)
@@ -1736,6 +1754,42 @@ var PayloadHeaderPrimitiveStringDefaultDSL = func() {
 	})
 }
 
+var PayloadJWTAuthorizationHeaderDSL = func() {
+	var JWT = JWTSecurity("jwt", func() {
+		Scope("api:read")
+	})
+	Service("ServiceHeaderPrimitiveStringDefault", func() {
+		Method("MethodHeaderPrimitiveStringDefault", func() {
+			Security(JWT)
+			Payload(func() {
+				Token("token", String)
+			})
+			HTTP(func() {
+				GET("")
+			})
+		})
+	})
+}
+
+var PayloadJWTAuthorizationCustomHeaderDSL = func() {
+	var JWT = JWTSecurity("jwt", func() {
+		Scope("api:read")
+	})
+	Service("ServiceHeaderPrimitiveStringDefault", func() {
+		Method("MethodHeaderPrimitiveStringDefault", func() {
+			Security(JWT)
+			Payload(func() {
+				Token("token", String)
+				Required("token")
+			})
+			HTTP(func() {
+				GET("")
+				Header("token:X-Auth")
+			})
+		})
+	})
+}
+
 var PayloadBodyStringDSL = func() {
 	Service("ServiceBodyString", func() {
 		Method("MethodBodyString", func() {
@@ -2739,7 +2793,7 @@ var MultipleServicesSamePayloadAndResultDSL = func() {
 			})
 			Error("something_went_wrong")
 			HTTP(func() {
-				GET("/")
+				GET("/{name}")
 				Response(StatusOK)
 				Response("something_went_wrong", StatusInternalServerError)
 			})
@@ -2760,7 +2814,7 @@ var MultipleServicesSamePayloadAndResultDSL = func() {
 			})
 			Error("something_went_wrong")
 			HTTP(func() {
-				GET("/")
+				GET("/{name}")
 				Response(StatusOK)
 				Response(StatusInternalServerError, "something_went_wrong")
 			})
diff --git a/http/codegen/testdata/payload_encode_functions.go b/http/codegen/testdata/payload_encode_functions.go
index 5334eed3..81495bd0 100644
--- a/http/codegen/testdata/payload_encode_functions.go
+++ b/http/codegen/testdata/payload_encode_functions.go
@@ -1449,6 +1449,25 @@ func EncodeMethodQueryPrimitiveStringDefaultRequest(encoder func(*http.Request)
 }
 `
 
+var PayloadJWTAuthorizationQueryEncodeCode = `// EncodeMethodHeaderPrimitiveStringDefaultRequest returns an encoder for
+// requests sent to the ServiceHeaderPrimitiveStringDefault
+// MethodHeaderPrimitiveStringDefault server.
+func EncodeMethodHeaderPrimitiveStringDefaultRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
+	return func(req *http.Request, v interface{}) error {
+		p, ok := v.(*serviceheaderprimitivestringdefault.MethodHeaderPrimitiveStringDefaultPayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceHeaderPrimitiveStringDefault", "MethodHeaderPrimitiveStringDefault", "*serviceheaderprimitivestringdefault.MethodHeaderPrimitiveStringDefaultPayload", v)
+		}
+		values := req.URL.Query()
+		if p.Token != nil {
+			values.Add("token", *p.Token)
+		}
+		req.URL.RawQuery = values.Encode()
+		return nil
+	}
+}
+`
+
 var PayloadHeaderStringEncodeCode = `// EncodeMethodHeaderStringRequest returns an encoder for requests sent to the
 // ServiceHeaderString MethodHeaderString server.
 func EncodeMethodHeaderStringRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
@@ -1686,6 +1705,46 @@ func EncodeMethodHeaderPrimitiveStringDefaultRequest(encoder func(*http.Request)
 }
 `
 
+var PayloadJWTAuthorizationHeaderEncodeCode = `// EncodeMethodHeaderPrimitiveStringDefaultRequest returns an encoder for
+// requests sent to the ServiceHeaderPrimitiveStringDefault
+// MethodHeaderPrimitiveStringDefault server.
+func EncodeMethodHeaderPrimitiveStringDefaultRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
+	return func(req *http.Request, v interface{}) error {
+		p, ok := v.(*serviceheaderprimitivestringdefault.MethodHeaderPrimitiveStringDefaultPayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceHeaderPrimitiveStringDefault", "MethodHeaderPrimitiveStringDefault", "*serviceheaderprimitivestringdefault.MethodHeaderPrimitiveStringDefaultPayload", v)
+		}
+		if p.Token != nil {
+			head := *p.Token
+			if !strings.Contains(head, " ") {
+				req.Header.Set("Authorization", "Bearer "+head)
+			} else {
+				req.Header.Set("Authorization", head)
+			}
+		}
+		return nil
+	}
+}
+`
+
+var PayloadJWTAuthorizationCustomHeaderEncodeCode = `// EncodeMethodHeaderPrimitiveStringDefaultRequest returns an encoder for
+// requests sent to the ServiceHeaderPrimitiveStringDefault
+// MethodHeaderPrimitiveStringDefault server.
+func EncodeMethodHeaderPrimitiveStringDefaultRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
+	return func(req *http.Request, v interface{}) error {
+		p, ok := v.(*serviceheaderprimitivestringdefault.MethodHeaderPrimitiveStringDefaultPayload)
+		if !ok {
+			return goahttp.ErrInvalidType("ServiceHeaderPrimitiveStringDefault", "MethodHeaderPrimitiveStringDefault", "*serviceheaderprimitivestringdefault.MethodHeaderPrimitiveStringDefaultPayload", v)
+		}
+		{
+			head := p.Token
+			req.Header.Set("X-Auth", head)
+		}
+		return nil
+	}
+}
+`
+
 var PayloadBodyStringEncodeCode = `// EncodeMethodBodyStringRequest returns an encoder for requests sent to the
 // ServiceBodyString MethodBodyString server.
 func EncodeMethodBodyStringRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
diff --git a/http/codegen/testdata/server_init_functions.go b/http/codegen/testdata/server_init_functions.go
index ad37c447..808405b9 100644
--- a/http/codegen/testdata/server_init_functions.go
+++ b/http/codegen/testdata/server_init_functions.go
@@ -17,7 +17,7 @@ func New(
 	return &Server{
 		Mounts: []*MountPoint{
 			{"MethodMultiEndpoints1", "GET", "/server_multi_endpoints/{id}"},
-			{"MethodMultiEndpoints2", "POST", "/server_multi_endpoints/"},
+			{"MethodMultiEndpoints2", "POST", "/server_multi_endpoints"},
 		},
 		MethodMultiEndpoints1: NewMethodMultiEndpoints1Handler(e.MethodMultiEndpoints1, mux, decoder, encoder, errhandler, formatter),
 		MethodMultiEndpoints2: NewMethodMultiEndpoints2Handler(e.MethodMultiEndpoints2, mux, decoder, encoder, errhandler, formatter),
@@ -143,7 +143,7 @@ func New(
 	}
 	return &Server{
 		Mounts: []*MountPoint{
-			{"StreamingResultMethod", "GET", "/"},
+			{"StreamingResultMethod", "GET", "/{x}"},
 		},
 		StreamingResultMethod: NewStreamingResultMethodHandler(e.StreamingResultMethod, mux, decoder, encoder, errhandler, formatter, upgrader, configurer.StreamingResultMethodFn),
 	}
diff --git a/http/codegen/testdata/streaming_code.go b/http/codegen/testdata/streaming_code.go
index 26dce361..28f55352 100644
--- a/http/codegen/testdata/streaming_code.go
+++ b/http/codegen/testdata/streaming_code.go
@@ -209,7 +209,6 @@ var StreamingResultClientEndpointCode = `// StreamingResultMethod returns an end
 // StreamingResultService service StreamingResultMethod server.
 func (c *Client) StreamingResultMethod() goa.Endpoint {
 	var (
-		encodeRequest  = EncodeStreamingResultMethodRequest(c.encoder)
 		decodeResponse = DecodeStreamingResultMethodResponse(c.decoder, c.RestoreResponseBody)
 	)
 	return func(ctx context.Context, v interface{}) (interface{}, error) {
@@ -217,10 +216,6 @@ func (c *Client) StreamingResultMethod() goa.Endpoint {
 		if err != nil {
 			return nil, err
 		}
-		err = encodeRequest(req, v)
-		if err != nil {
-			return nil, err
-		}
 		var cancel context.CancelFunc
 		ctx, cancel = context.WithCancel(ctx)
 		conn, resp, err := c.dialer.DialContext(ctx, req.URL.String(), req.Header)
@@ -292,7 +287,6 @@ var StreamingResultWithViewsClientEndpointCode = `// StreamingResultWithViewsMet
 // StreamingResultWithViewsMethod server.
 func (c *Client) StreamingResultWithViewsMethod() goa.Endpoint {
 	var (
-		encodeRequest  = EncodeStreamingResultWithViewsMethodRequest(c.encoder)
 		decodeResponse = DecodeStreamingResultWithViewsMethodResponse(c.decoder, c.RestoreResponseBody)
 	)
 	return func(ctx context.Context, v interface{}) (interface{}, error) {
@@ -300,10 +294,6 @@ func (c *Client) StreamingResultWithViewsMethod() goa.Endpoint {
 		if err != nil {
 			return nil, err
 		}
-		err = encodeRequest(req, v)
-		if err != nil {
-			return nil, err
-		}
 		var cancel context.CancelFunc
 		ctx, cancel = context.WithCancel(ctx)
 		conn, resp, err := c.dialer.DialContext(ctx, req.URL.String(), req.Header)
@@ -370,7 +360,6 @@ var StreamingResultWithExplicitViewClientEndpointCode = `// StreamingResultWithE
 // StreamingResultWithExplicitViewMethod server.
 func (c *Client) StreamingResultWithExplicitViewMethod() goa.Endpoint {
 	var (
-		encodeRequest  = EncodeStreamingResultWithExplicitViewMethodRequest(c.encoder)
 		decodeResponse = DecodeStreamingResultWithExplicitViewMethodResponse(c.decoder, c.RestoreResponseBody)
 	)
 	return func(ctx context.Context, v interface{}) (interface{}, error) {
@@ -378,10 +367,6 @@ func (c *Client) StreamingResultWithExplicitViewMethod() goa.Endpoint {
 		if err != nil {
 			return nil, err
 		}
-		err = encodeRequest(req, v)
-		if err != nil {
-			return nil, err
-		}
 		var cancel context.CancelFunc
 		ctx, cancel = context.WithCancel(ctx)
 		conn, resp, err := c.dialer.DialContext(ctx, req.URL.String(), req.Header)
@@ -576,7 +561,6 @@ var StreamingResultCollectionWithExplicitViewClientEndpointCode = `// StreamingR
 // service StreamingResultCollectionWithExplicitViewMethod server.
 func (c *Client) StreamingResultCollectionWithExplicitViewMethod() goa.Endpoint {
 	var (
-		encodeRequest  = EncodeStreamingResultCollectionWithExplicitViewMethodRequest(c.encoder)
 		decodeResponse = DecodeStreamingResultCollectionWithExplicitViewMethodResponse(c.decoder, c.RestoreResponseBody)
 	)
 	return func(ctx context.Context, v interface{}) (interface{}, error) {
@@ -584,10 +568,6 @@ func (c *Client) StreamingResultCollectionWithExplicitViewMethod() goa.Endpoint
 		if err != nil {
 			return nil, err
 		}
-		err = encodeRequest(req, v)
-		if err != nil {
-			return nil, err
-		}
 		var cancel context.CancelFunc
 		ctx, cancel = context.WithCancel(ctx)
 		conn, resp, err := c.dialer.DialContext(ctx, req.URL.String(), req.Header)
diff --git a/http/codegen/testdata/streaming_dsls.go b/http/codegen/testdata/streaming_dsls.go
index ca444ef7..8e247a9b 100644
--- a/http/codegen/testdata/streaming_dsls.go
+++ b/http/codegen/testdata/streaming_dsls.go
@@ -55,7 +55,7 @@ var StreamingResultDSL = func() {
 			Payload(Request)
 			StreamingResult(Result)
 			HTTP(func() {
-				GET("/")
+				GET("/{x}")
 				Response(StatusOK)
 			})
 		})
@@ -86,7 +86,7 @@ var StreamingResultWithViewsDSL = func() {
 			Payload(Request)
 			StreamingResult(Result)
 			HTTP(func() {
-				GET("/")
+				GET("/{x}")
 				Response(StatusOK)
 			})
 		})
@@ -119,7 +119,7 @@ var StreamingResultWithExplicitViewDSL = func() {
 				View("extended")
 			})
 			HTTP(func() {
-				GET("/")
+				GET("/{x}")
 				Response(StatusOK)
 			})
 		})
@@ -150,7 +150,7 @@ var StreamingResultCollectionWithViewsDSL = func() {
 			Payload(Request)
 			StreamingResult(CollectionOf(Result))
 			HTTP(func() {
-				GET("/")
+				GET("/{x}")
 				Response(StatusOK)
 			})
 		})
@@ -183,7 +183,7 @@ var StreamingResultCollectionWithExplicitViewDSL = func() {
 				View("tiny")
 			})
 			HTTP(func() {
-				GET("/")
+				GET("/{x}")
 				Response(StatusOK)
 			})
 		})
diff --git a/http/middleware/xray/middleware_test.go b/http/middleware/xray/middleware_test.go
index 13dbb7a4..c03a91ea 100644
--- a/http/middleware/xray/middleware_test.go
+++ b/http/middleware/xray/middleware_test.go
@@ -24,7 +24,7 @@ func TestNew(t *testing.T) {
 		Success bool
 	}{
 		"ok":     {udplisten, true},
-		"not-ok": {"1002.0.0.0:62111", false},
+		"not-ok": {"foo:bar", false},
 	}
 	for k, c := range cases {
 		t.Run(k, func(t *testing.T) {