1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 12:32:21 +00:00

vendor: 构造grpc例子

This commit is contained in:
chai2010 2018-07-14 14:31:29 +08:00
parent 1a54c34318
commit c86d359da9
10 changed files with 441 additions and 4 deletions

View File

@ -59,7 +59,7 @@ func startServer() {
// Create the TLS credentials
creds := credentials.NewTLS(&tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
ClientAuth: tls.RequireAndVerifyClientCert, // NOTE: this is optional!
Certificates: []tls.Certificate{certificate},
ClientCAs: certPool,
})
@ -93,9 +93,10 @@ func doClientWork() {
}
creds := credentials.NewTLS(&tls.Config{
ServerName: tlsServerName, // NOTE: this is required!
Certificates: []tls.Certificate{certificate},
RootCAs: certPool,
InsecureSkipVerify: false, // NOTE: this is required!
ServerName: tlsServerName, // NOTE: this is required!
Certificates: []tls.Certificate{certificate},
RootCAs: certPool,
})
conn, err := grpc.Dial("localhost"+port, grpc.WithTransportCredentials(creds))

View File

@ -0,0 +1,10 @@
run:
@go build -o a.out && ./a.out
-@rm ./a.out
gen:
protoc -I . --go_out=plugins=grpc:. helloworld.proto
clean:
-rm *.pb.go

View File

@ -0,0 +1,192 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: helloworld.proto
package main
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type HelloRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *HelloRequest) Reset() { *m = HelloRequest{} }
func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
func (*HelloRequest) ProtoMessage() {}
func (*HelloRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_helloworld_04dfe859c9b956ba, []int{0}
}
func (m *HelloRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HelloRequest.Unmarshal(m, b)
}
func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic)
}
func (dst *HelloRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_HelloRequest.Merge(dst, src)
}
func (m *HelloRequest) XXX_Size() int {
return xxx_messageInfo_HelloRequest.Size(m)
}
func (m *HelloRequest) XXX_DiscardUnknown() {
xxx_messageInfo_HelloRequest.DiscardUnknown(m)
}
var xxx_messageInfo_HelloRequest proto.InternalMessageInfo
func (m *HelloRequest) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type HelloReply struct {
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *HelloReply) Reset() { *m = HelloReply{} }
func (m *HelloReply) String() string { return proto.CompactTextString(m) }
func (*HelloReply) ProtoMessage() {}
func (*HelloReply) Descriptor() ([]byte, []int) {
return fileDescriptor_helloworld_04dfe859c9b956ba, []int{1}
}
func (m *HelloReply) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HelloReply.Unmarshal(m, b)
}
func (m *HelloReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_HelloReply.Marshal(b, m, deterministic)
}
func (dst *HelloReply) XXX_Merge(src proto.Message) {
xxx_messageInfo_HelloReply.Merge(dst, src)
}
func (m *HelloReply) XXX_Size() int {
return xxx_messageInfo_HelloReply.Size(m)
}
func (m *HelloReply) XXX_DiscardUnknown() {
xxx_messageInfo_HelloReply.DiscardUnknown(m)
}
var xxx_messageInfo_HelloReply proto.InternalMessageInfo
func (m *HelloReply) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func init() {
proto.RegisterType((*HelloRequest)(nil), "main.HelloRequest")
proto.RegisterType((*HelloReply)(nil), "main.HelloReply")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// GreeterClient is the client API for Greeter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GreeterClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}
type greeterClient struct {
cc *grpc.ClientConn
}
func NewGreeterClient(cc *grpc.ClientConn) GreeterClient {
return &greeterClient{cc}
}
func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := c.cc.Invoke(ctx, "/main.Greeter/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GreeterServer is the server API for Greeter service.
type GreeterServer interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
}
func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) {
s.RegisterService(&_Greeter_serviceDesc, srv)
}
func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HelloRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GreeterServer).SayHello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/main.Greeter/SayHello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Greeter_serviceDesc = grpc.ServiceDesc{
ServiceName: "main.Greeter",
HandlerType: (*GreeterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _Greeter_SayHello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "helloworld.proto",
}
func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_helloworld_04dfe859c9b956ba) }
var fileDescriptor_helloworld_04dfe859c9b956ba = []byte{
// 142 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9,
0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d,
0xcc, 0xcc, 0x53, 0x52, 0xe2, 0xe2, 0xf1, 0x00, 0xc9, 0x04, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97,
0x08, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x06, 0x81,
0xd9, 0x4a, 0x6a, 0x5c, 0x5c, 0x50, 0x35, 0x05, 0x39, 0x95, 0x42, 0x12, 0x5c, 0xec, 0xb9, 0xa9,
0xc5, 0xc5, 0x89, 0xe9, 0x30, 0x45, 0x30, 0xae, 0x91, 0x35, 0x17, 0xbb, 0x7b, 0x51, 0x6a, 0x6a,
0x49, 0x6a, 0x91, 0x90, 0x01, 0x17, 0x47, 0x70, 0x62, 0x25, 0x58, 0x97, 0x90, 0x90, 0x1e, 0xc8,
0x26, 0x3d, 0x64, 0x6b, 0xa4, 0x04, 0x50, 0xc4, 0x0a, 0x72, 0x2a, 0x93, 0xd8, 0xc0, 0xae, 0x32,
0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x18, 0x38, 0x13, 0xf1, 0xa9, 0x00, 0x00, 0x00,
}

View File

@ -0,0 +1,15 @@
syntax = "proto3";
package main;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}

View File

@ -0,0 +1,109 @@
package main
import (
fmt "fmt"
"log"
"net"
"time"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
)
var (
port = ":5000"
)
type myGrpcServer struct{}
func (s *myGrpcServer) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, fmt.Errorf("missing credentials")
}
var (
appid string
appkey string
)
if val, ok := md["login"]; ok {
appid = val[0]
}
if val, ok := md["password"]; ok {
appkey = val[0]
}
if appid != "gopher" || appkey != "password" {
return nil, grpc.Errorf(codes.Unauthenticated, "invalid token: appid=%s, appkey=%s", appid, appkey)
}
return &HelloReply{Message: "Hello " + in.Name}, nil
}
type Authentication struct {
Login string
Password string
}
func (a *Authentication) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
return map[string]string{"login": a.Login, "password": a.Password}, nil
}
func (a *Authentication) RequireTransportSecurity() bool {
return true
}
func main() {
go startServer()
time.Sleep(time.Second)
doClientWork()
}
func startServer() {
creds, err := credentials.NewServerTLSFromFile("tls-config/server.crt", "tls-config/server.key")
if err != nil {
log.Fatalf("could not load tls cert: %s", err)
}
server := grpc.NewServer(grpc.Creds(creds))
RegisterGreeterServer(server, new(myGrpcServer))
lis, err := net.Listen("tcp", port)
if err != nil {
log.Panicf("could not list on %s: %s", port, err)
}
if err := server.Serve(lis); err != nil {
log.Panicf("grpc serve error: %s", err)
}
}
func doClientWork() {
creds, err := credentials.NewClientTLSFromFile("tls-config/server.crt", "server.grpc.io")
if err != nil {
log.Fatalf("could not load tls cert: %s", err)
}
auth := Authentication{
Login: "gopher",
Password: "password",
}
conn, err := grpc.Dial("localhost"+port, grpc.WithTransportCredentials(creds), grpc.WithPerRPCCredentials(&auth))
if err != nil {
log.Fatal(err)
}
defer conn.Close()
c := NewGreeterClient(conn)
r, err := c.SayHello(context.Background(), &HelloRequest{Name: "gopher"})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("doClientWork: %s", r.Message)
}

View File

@ -0,0 +1,18 @@
default:
# server
openssl genrsa -out server.key 2048
openssl req -new -x509 -days 3650 \
-subj "/C=GB/L=China/O=grpc-server/CN=server.grpc.io" \
-key server.key -out server.crt
# client
openssl genrsa -out client.key 2048
openssl req -new -x509 -days 3650 \
-subj "/C=GB/L=China/O=grpc-client/CN=client.grpc.io" \
-key client.key -out client.crt
clean:
-rm *.key *.crt *.csr *.srl

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFDCCAfwCCQCrJq8HthdiHTANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJH
QjEOMAwGA1UEBwwFQ2hpbmExFDASBgNVBAoMC2dycGMtY2xpZW50MRcwFQYDVQQD
DA5jbGllbnQuZ3JwYy5pbzAeFw0xODA3MTQwNzEyMTRaFw0yODA3MTEwNzEyMTRa
MEwxCzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEUMBIGA1UECgwLZ3JwYy1j
bGllbnQxFzAVBgNVBAMMDmNsaWVudC5ncnBjLmlvMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAo4r8TJGDq6sVHchIROy8ySwiyyHyNegGwopPYSJ1SgPP
BGwOEidDosYR+wAVXkNP4H5wD0VW1At7jOcQ8nkjRlxKPFywLhdjz4qmZPor50JU
pWj5aizU9z24qk0EGL62CjvxTqHutNjHDkHSS+Londdh+x/AIwSVGP4egCerpoH+
nG+m1TO90bj34FgrUvD+6Pt0PnEvWThWo6/6+6XWFqOeXEqjXKgbqtvZRv1epNu2
p0DNkJENB0XEctcM/frJdFp0F5r08mhppUN1fQZw0G/Fz5fEuHnLvS9v3ap6gwIL
rzqbamR8W8sb9pYKu6kMBU4vPyI6fpKBPZTR43oC5wIDAQABMA0GCSqGSIb3DQEB
CwUAA4IBAQBlH6Au0Owv/ui7I7dzwKRTKpgwJXTs75rdWMN9xmWrMN93yXJJceXC
HSIMcG8KYYPVlMuTOHD21R7doUdCjSIFDmyI1eqThzwrfa4zc3qqWJYcGMbZXu+U
pAyDERQIxjAZnV4o5ZL18NXwAsUuF9AheR5YBszeG/xZurxDSVp2nPYLkjpE52Kw
Nros7xxCIGaOrbUjgtATPKEgjxc3AgnKLVaeemTijI1Q8T+yoFYLK5d2ARZX9YNy
TgbXSe3Bx8Hk1a3V/V799zBK4O9XyaCKjbpbgBWEzq70zz2gqYmjoHb5Rj+jqAJ2
zQzUmp6WfH9TynsNwhoV8DYWch/97JJF
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAo4r8TJGDq6sVHchIROy8ySwiyyHyNegGwopPYSJ1SgPPBGwO
EidDosYR+wAVXkNP4H5wD0VW1At7jOcQ8nkjRlxKPFywLhdjz4qmZPor50JUpWj5
aizU9z24qk0EGL62CjvxTqHutNjHDkHSS+Londdh+x/AIwSVGP4egCerpoH+nG+m
1TO90bj34FgrUvD+6Pt0PnEvWThWo6/6+6XWFqOeXEqjXKgbqtvZRv1epNu2p0DN
kJENB0XEctcM/frJdFp0F5r08mhppUN1fQZw0G/Fz5fEuHnLvS9v3ap6gwILrzqb
amR8W8sb9pYKu6kMBU4vPyI6fpKBPZTR43oC5wIDAQABAoIBACZPUHq/O5DjKrcn
S4aZzj9xz1S2Rv7Js4uuypl+cOs9qSjoBwPJntZqf5vEkTzbl8KG28k3/Pb/GZoQ
JrAmIFVDGUC6laq2X/MmD4Rn9hDeQOXeiU6N4fVox/FcyTDiu9H56LT6yegjP73f
PVv5c3RGF/WzolaRpDuOi6aJpHQEb7pGQ44ZEMBh3DyYNGSrU/fB/abICwkYXWhB
V3cTbV/c1Fb/JQAXjP9SnnASEgOsjLaPUzOWzjChZtcPD4ZfvUa82Yxpt/G1b72M
KLN5ozCBbTlGbRRCHPtrjluV35WkhFgBLwySFux0z+OAR9PEOUFBiwvL5aU9ckc7
koRDV0ECgYEAzopb84ULwlYqG06MEooEaN5I16Up90Fcj+UqmZLrKClwVFVbM1T0
7xp8XRFWYaTsNXUMmah4K2ZTN/wsUS6SckUgzBKdfncdajLbfeFjAF6BTQgXKhHJ
/5xGCidUgaC1faJS2+zyXJaecKc5Ju5xh0XkQVHfpGgg0eKiANotC8MCgYEAyrS6
fXqidx93cGfVr3LiTa+eHGLBQJyrxrvfsulIAx2444KKpt8RziIwTEXrQXkW2h+6
HBzCAaef2QdxqS0zuA9wnQ81Jwy+5pWPN4OWQS9JW2K47XMSwvcDpeSwf/Zf3Xur
u4Z/ih3TN4Laf/Lm/i+xOmk1fR9UnHeqe6lJTg0CgYEAyTBvl4wvQzOpuoXN3jVB
TGHS9PS3J1os7yJdV9GMbcfH2u52c087dDoJkKLV0THUwdHt3zQDMstvHubuyHmk
P9lktEUh01H2fj9iHYHSbUahj0blQZ6odOxmMXfUUp0YjXP0YLSz9UrmtXe/LVQx
lIKZcKNvRXgFGE46XrgoDv8CgYB/SUeFvblBNjgpFHrBRlHG2I1fY7/YU8kl7RmG
XiiDFGniKznnmVGz8BIGAy28Gk54P839Ey3cHicpABymUCUW4lMjvMXytHU3lBiv
kmiKnCfjQ7W+HTFdzgCzbkxKvinqiVsIUWfLEfls9TVBfQUB/m66sBAPdtoJurcK
Gf5XDQKBgEeEVsspejC4duFKsXwq7R8JHRDmvVc9rUdthfhyU8e2po1cfInqmKrb
K6Cn03Pfaa/xZa2YfIiDyWjBbXgpmi+KzaAS9Iay+U0iPYuoeeQrnztXGazInVqf
HLAeZ4xWePJYh9vc3a8ALTJKYIiuainaO/kiTAL2UtN+LOqx3Ho8
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDFDCCAfwCCQDIYtSF3tbGvDANBgkqhkiG9w0BAQsFADBMMQswCQYDVQQGEwJH
QjEOMAwGA1UEBwwFQ2hpbmExFDASBgNVBAoMC2dycGMtc2VydmVyMRcwFQYDVQQD
DA5zZXJ2ZXIuZ3JwYy5pbzAeFw0xODA3MTQwNzEyMTNaFw0yODA3MTEwNzEyMTNa
MEwxCzAJBgNVBAYTAkdCMQ4wDAYDVQQHDAVDaGluYTEUMBIGA1UECgwLZ3JwYy1z
ZXJ2ZXIxFzAVBgNVBAMMDnNlcnZlci5ncnBjLmlvMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA2cZFGgh2jU2sbs0aBN8o5Ce6zZHD/Q3wnR0axeMCsbO8
uV1b/TIA6WiUW7uDwQIEnCcu9Izyi6BW/1xoOyvP3FMb4yQBrueDgkHZIpVV43X/
wgfwsT20kbQjM1DYvn/08e9MmHliIEUOQ3rUOluLqABcZuqGHeJQoocYJyaaEK7U
eMhJhHQPOopClZdMfrtzw860sLgIe/vgEH9MlGFO/5ay1w3N+VsI7d8AmCzqPSua
bxxdRl4z9kXkhMLvHd9MHuZ0VQgeZMMGVxYxxno7Y9HWqpLzv4ANSOxZHYaXEnr4
+Y0qmmPOn8bcXbL+oa8hcNScqbte5sKUODI5n4AqRQIDAQABMA0GCSqGSIb3DQEB
CwUAA4IBAQBNaCkvbLkUxKGT0W1b7wEU7ipDjjn+YsiRc98+go6nkNDfQPuf1AY9
KyEd9b9gHgqiQoZIQR7OzRDIalh22TvNEfKav4lg3WiNSm405AuYqylg4jQ6K06w
qH9dNN8si3H+D3jGdKezVyYJrpyi88HDIKeQ7EAeoxTlSbdzYjj1lJ23prFf7fLl
tYn3bIPsamYtXlB9NMdaPeq0YL7FlkKFhfkfJTH+Wehk16dhDBzjFStIwSAQOnDl
5ckrLrD8Su1fXSK69SPilvAOaCQTKQg5PiBuA/NAN8eW1ph38ooWvGVwOreZXAmR
P+QZkg7xMgYLBVbWNLgXhol9afRoo3K5
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA2cZFGgh2jU2sbs0aBN8o5Ce6zZHD/Q3wnR0axeMCsbO8uV1b
/TIA6WiUW7uDwQIEnCcu9Izyi6BW/1xoOyvP3FMb4yQBrueDgkHZIpVV43X/wgfw
sT20kbQjM1DYvn/08e9MmHliIEUOQ3rUOluLqABcZuqGHeJQoocYJyaaEK7UeMhJ
hHQPOopClZdMfrtzw860sLgIe/vgEH9MlGFO/5ay1w3N+VsI7d8AmCzqPSuabxxd
Rl4z9kXkhMLvHd9MHuZ0VQgeZMMGVxYxxno7Y9HWqpLzv4ANSOxZHYaXEnr4+Y0q
mmPOn8bcXbL+oa8hcNScqbte5sKUODI5n4AqRQIDAQABAoIBAQCmGKvhtCy/j0uB
4tsCdjZY9dhrK88gtb4cBvPBlGgcourBMmyTy8yYOVRWNsnBrslXVCdjDBF93xgb
gh5ZawwJjjXJ40+JWDicY5652s58QyaDlczFUjvjmVHztKjreuqWkB6KeKIX3LOJ
UiiGLgZxZ30SXbNXHaLEo2cPjUiaiWVpAzngBDGwVVb4RmsQKru4ZxQDhPKFbY7E
4bP7EXA1ZRUfA/KhhKF5v2ZLV7VuE8/jecblsW3Ra79cQGDDztNQkMQwzqj0MGGg
L0B+9KJgRVXco7EQDQgnmPLnMKaRTB1tup3YN1iOtVk1znFvpoTBYhNKebeoTKy8
0091rYlBAoGBAPIXbEXLuMAjmHUshXtadcuVRhH8/nMw5hej7ODg3gKV5IvwYpvg
nv78+7CY39CmLD1QtXSZQmOOtv+CMAViI2ktXhvCxoSBq5lHSCu38dq8TNMpkNo2
cbevpS58lDfbCjqqPeBLPhLDLB7oMbSZjqXCYSDpxJKY59OgsG6IYHJ1AoGBAOZJ
M/hGE1L1dGUXgdQO1uogQDRkLrulhVGXi1qLlU88Voz2aCgWNVEc7w0Dln90AtTJ
f7XovK3N35ND5TIPCF7zAdcfHVjUN4NuAX3agzqM9fVP8jgp2ey02hCi3VA8gIok
g5Fm7ktbTn8FhPCJnBwdNIf43pFAshEPEFwtqz6RAoGBAKvRRe3vXYs4eC7JT18x
36KCqj2AElNM5DDpDei4j7jEC3XqQQIilJWilTtL9KVQGtvVmUNMtpqUInsLOevI
MBuosD8BqQVIRrK9rZIhtgwpUlkYCg9lTqYwigqJLmTKF+N1Cf9TR5XnYTv6TbTA
u0YXw/mpD/N/hCFlzXJVZiY1AoGAWOV7VWUfwo+UTg4EBStxVVH71v2xeKiNzZB1
sA9gJQVC2Amq7YadMGG9+kUfTLYo/aGHVl6wr1tg6kV0bZ2V+qlOVY/iUU8i2u6V
TtMSg4C01ez1sS6evJyX7YIhcv7YE/vCelfEt3xY0fn8dqp4g/XWOIMez+2sj59E
DoFmsLECgYEAvGbIyb+imwE67p4YbdwwQ2Lu8oFMOTWnY6QQf2WpuMT9P7T3Lf8h
qoO6Lo6kDvDu8itd5LNVtrnnlG68Wj70ZODsi4h7I6Pa6mI3xWRFJ+h/p3lLYTsR
tAKvMYqax97rWb+okg3P428BoAO2p+rNxT21+DOe0vegGuvzfFLQx4w=
-----END RSA PRIVATE KEY-----