ref: Pass the language from client to server across RPCs.

MultiPart: 2/3

Change-Id: Iabc73c3a617cb8396df7e3c89e76a1d4cae92d3b
diff --git a/profiles/internal/rpc/client.go b/profiles/internal/rpc/client.go
index 5995f66..40dde63 100644
--- a/profiles/internal/rpc/client.go
+++ b/profiles/internal/rpc/client.go
@@ -858,6 +858,7 @@
 		Blessings:        blessingsRequest,
 		Discharges:       fc.discharges,
 		TraceRequest:     vtrace.GetRequest(fc.ctx),
+		Language:         string(i18n.GetLangID(fc.ctx)),
 	}
 	if err := fc.enc.Encode(req); err != nil {
 		berr := verror.New(errRequestEncoding, fc.ctx, fmt.Sprintf("%#v", req), err)
diff --git a/profiles/internal/rpc/full_test.go b/profiles/internal/rpc/full_test.go
index ad89931..12445ee 100644
--- a/profiles/internal/rpc/full_test.go
+++ b/profiles/internal/rpc/full_test.go
@@ -25,6 +25,7 @@
 
 	"v.io/v23"
 	"v.io/v23/context"
+	"v.io/v23/i18n"
 	"v.io/v23/namespace"
 	"v.io/v23/naming"
 	"v.io/v23/options"
@@ -110,6 +111,10 @@
 	return fmt.Sprintf("method:%q,suffix:%q,arg:%q", "EchoUser", call.Suffix(), arg), u, nil
 }
 
+func (*testServer) EchoLang(ctx *context.T, call rpc.ServerCall) (string, error) {
+	return string(i18n.GetLangID(ctx)), nil
+}
+
 func (*testServer) EchoBlessings(ctx *context.T, call rpc.ServerCall) (server, client string, _ error) {
 	local := security.LocalBlessingNames(ctx, call.Security())
 	remote, _ := security.RemoteBlessingNames(ctx, call.Security())
@@ -714,6 +719,7 @@
 			{"mountpoint/server/suffix", "EchoBlessings", nil, nil, nil, v{"[server]", "[client]"}, nil},
 			{"mountpoint/server/suffix", "EchoAndError", v{"bugs bunny"}, nil, nil, v{`method:"EchoAndError",suffix:"suffix",arg:"bugs bunny"`}, nil},
 			{"mountpoint/server/suffix", "EchoAndError", v{"error"}, nil, nil, nil, errMethod},
+			{"mountpoint/server/suffix", "EchoLang", nil, nil, nil, v{"foolang"}, nil},
 		}
 		name = func(t testcase) string {
 			return fmt.Sprintf("%s.%s(%v)", t.name, t.method, t.args)
@@ -724,6 +730,7 @@
 	)
 	defer b.cleanup(t, ctx)
 	ctx, _ = v23.WithPrincipal(ctx, pclient)
+	ctx = i18n.WithLangID(ctx, "foolang")
 	for _, test := range tests {
 		vlog.VI(1).Infof("%s client.StartCall", name(test))
 		vname := test.name
diff --git a/profiles/internal/rpc/server.go b/profiles/internal/rpc/server.go
index c842b2d..95ebf68 100644
--- a/profiles/internal/rpc/server.go
+++ b/profiles/internal/rpc/server.go
@@ -19,6 +19,7 @@
 	"v.io/x/lib/vlog"
 
 	"v.io/v23/context"
+	"v.io/v23/i18n"
 	"v.io/v23/namespace"
 	"v.io/v23/naming"
 	"v.io/v23/options"
@@ -1089,6 +1090,10 @@
 	fs.method = req.Method
 	fs.suffix = strings.TrimLeft(req.Suffix, "/")
 
+	if req.Language != "" {
+		fs.ctx = i18n.WithLangID(fs.ctx, i18n.LangID(req.Language))
+	}
+
 	// TODO(mattr): Currently this allows users to trigger trace collection
 	// on the server even if they will not be allowed to collect the
 	// results later.  This might be considered a DOS vector.