github.com/vcilabs/webrpc@v0.5.2-0.20201116131534-162e27b1b33b/_examples/golang-imports/api.gen.go (about) 1 // example-api-service v1.0.0 0d503533eece70559645300ec8c6afd39be48810 2 // -- 3 // This file has been generated by https://github.com/webrpc/webrpc using gen/golang 4 // Do not edit by hand. Update your webrpc schema and re-generate. 5 package main 6 7 import ( 8 "bytes" 9 "context" 10 "encoding/json" 11 "errors" 12 "fmt" 13 "io" 14 "io/ioutil" 15 "net/http" 16 "net/url" 17 "strings" 18 ) 19 20 // WebRPC description and code-gen version 21 func WebRPCVersion() string { 22 return "v1" 23 } 24 25 // Schema version of your RIDL schema 26 func WebRPCSchemaVersion() string { 27 return "v1.0.0" 28 } 29 30 // Schema hash generated from your RIDL schema 31 func WebRPCSchemaHash() string { 32 return "0d503533eece70559645300ec8c6afd39be48810" 33 } 34 35 // 36 // Types 37 // 38 39 type User struct { 40 Username string `json:"username"` 41 Age uint32 `json:"age"` 42 } 43 44 type Location uint32 45 46 const ( 47 Location_TORONTO Location = 0 48 Location_NEW_YORK Location = 1 49 ) 50 51 var Location_name = map[uint32]string{ 52 0: "TORONTO", 53 1: "NEW_YORK", 54 } 55 56 var Location_value = map[string]uint32{ 57 "TORONTO": 0, 58 "NEW_YORK": 1, 59 } 60 61 func (x Location) String() string { 62 return Location_name[uint32(x)] 63 } 64 65 func (x Location) MarshalJSON() ([]byte, error) { 66 buf := bytes.NewBufferString(`"`) 67 buf.WriteString(Location_name[uint32(x)]) 68 buf.WriteString(`"`) 69 return buf.Bytes(), nil 70 } 71 72 func (x *Location) UnmarshalJSON(b []byte) error { 73 var j string 74 err := json.Unmarshal(b, &j) 75 if err != nil { 76 return err 77 } 78 *x = Location(Location_value[j]) 79 return nil 80 } 81 82 type ExampleAPI interface { 83 Ping(ctx context.Context) error 84 Status(ctx context.Context) (bool, error) 85 GetUsers(ctx context.Context) ([]*User, *Location, error) 86 } 87 88 var WebRPCServices = map[string][]string{ 89 "ExampleAPI": { 90 "Ping", 91 "Status", 92 "GetUsers", 93 }, 94 } 95 96 // 97 // Server 98 // 99 100 type WebRPCServer interface { 101 http.Handler 102 } 103 104 type exampleAPIServer struct { 105 ExampleAPI 106 } 107 108 func NewExampleAPIServer(svc ExampleAPI) WebRPCServer { 109 return &exampleAPIServer{ 110 ExampleAPI: svc, 111 } 112 } 113 114 func (s *exampleAPIServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { 115 ctx := r.Context() 116 ctx = context.WithValue(ctx, HTTPResponseWriterCtxKey, w) 117 ctx = context.WithValue(ctx, HTTPRequestCtxKey, r) 118 ctx = context.WithValue(ctx, ServiceNameCtxKey, "ExampleAPI") 119 120 if r.Method != "POST" { 121 err := Errorf(ErrBadRoute, "unsupported method %q (only POST is allowed)", r.Method) 122 RespondWithError(w, err) 123 return 124 } 125 126 switch r.URL.Path { 127 case "/rpc/ExampleAPI/Ping": 128 s.servePing(ctx, w, r) 129 return 130 case "/rpc/ExampleAPI/Status": 131 s.serveStatus(ctx, w, r) 132 return 133 case "/rpc/ExampleAPI/GetUsers": 134 s.serveGetUsers(ctx, w, r) 135 return 136 default: 137 err := Errorf(ErrBadRoute, "no handler for path %q", r.URL.Path) 138 RespondWithError(w, err) 139 return 140 } 141 } 142 143 func (s *exampleAPIServer) servePing(ctx context.Context, w http.ResponseWriter, r *http.Request) { 144 header := r.Header.Get("Content-Type") 145 i := strings.Index(header, ";") 146 if i == -1 { 147 i = len(header) 148 } 149 150 switch strings.TrimSpace(strings.ToLower(header[:i])) { 151 case "application/json": 152 s.servePingJSON(ctx, w, r) 153 default: 154 err := Errorf(ErrBadRoute, "unexpected Content-Type: %q", r.Header.Get("Content-Type")) 155 RespondWithError(w, err) 156 } 157 } 158 159 func (s *exampleAPIServer) servePingJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { 160 var err error 161 ctx = context.WithValue(ctx, MethodNameCtxKey, "Ping") 162 163 // Call service method 164 func() { 165 defer func() { 166 // In case of a panic, serve a 500 error and then panic. 167 if rr := recover(); rr != nil { 168 RespondWithError(w, ErrorInternal("internal service panic")) 169 panic(rr) 170 } 171 }() 172 err = s.ExampleAPI.Ping(ctx) 173 }() 174 175 if err != nil { 176 RespondWithError(w, err) 177 return 178 } 179 180 w.Header().Set("Content-Type", "application/json") 181 w.WriteHeader(http.StatusOK) 182 } 183 184 func (s *exampleAPIServer) serveStatus(ctx context.Context, w http.ResponseWriter, r *http.Request) { 185 header := r.Header.Get("Content-Type") 186 i := strings.Index(header, ";") 187 if i == -1 { 188 i = len(header) 189 } 190 191 switch strings.TrimSpace(strings.ToLower(header[:i])) { 192 case "application/json": 193 s.serveStatusJSON(ctx, w, r) 194 default: 195 err := Errorf(ErrBadRoute, "unexpected Content-Type: %q", r.Header.Get("Content-Type")) 196 RespondWithError(w, err) 197 } 198 } 199 200 func (s *exampleAPIServer) serveStatusJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { 201 var err error 202 ctx = context.WithValue(ctx, MethodNameCtxKey, "Status") 203 204 // Call service method 205 var ret0 bool 206 func() { 207 defer func() { 208 // In case of a panic, serve a 500 error and then panic. 209 if rr := recover(); rr != nil { 210 RespondWithError(w, ErrorInternal("internal service panic")) 211 panic(rr) 212 } 213 }() 214 ret0, err = s.ExampleAPI.Status(ctx) 215 }() 216 respContent := struct { 217 Ret0 bool `json:"status"` 218 }{ret0} 219 220 if err != nil { 221 RespondWithError(w, err) 222 return 223 } 224 respBody, err := json.Marshal(respContent) 225 if err != nil { 226 err = WrapError(ErrInternal, err, "failed to marshal json response") 227 RespondWithError(w, err) 228 return 229 } 230 231 w.Header().Set("Content-Type", "application/json") 232 w.WriteHeader(http.StatusOK) 233 w.Write(respBody) 234 } 235 236 func (s *exampleAPIServer) serveGetUsers(ctx context.Context, w http.ResponseWriter, r *http.Request) { 237 header := r.Header.Get("Content-Type") 238 i := strings.Index(header, ";") 239 if i == -1 { 240 i = len(header) 241 } 242 243 switch strings.TrimSpace(strings.ToLower(header[:i])) { 244 case "application/json": 245 s.serveGetUsersJSON(ctx, w, r) 246 default: 247 err := Errorf(ErrBadRoute, "unexpected Content-Type: %q", r.Header.Get("Content-Type")) 248 RespondWithError(w, err) 249 } 250 } 251 252 func (s *exampleAPIServer) serveGetUsersJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { 253 var err error 254 ctx = context.WithValue(ctx, MethodNameCtxKey, "GetUsers") 255 256 // Call service method 257 var ret0 []*User 258 var ret1 *Location 259 func() { 260 defer func() { 261 // In case of a panic, serve a 500 error and then panic. 262 if rr := recover(); rr != nil { 263 RespondWithError(w, ErrorInternal("internal service panic")) 264 panic(rr) 265 } 266 }() 267 ret0, ret1, err = s.ExampleAPI.GetUsers(ctx) 268 }() 269 respContent := struct { 270 Ret0 []*User `json:"users"` 271 Ret1 *Location `json:"location"` 272 }{ret0, ret1} 273 274 if err != nil { 275 RespondWithError(w, err) 276 return 277 } 278 respBody, err := json.Marshal(respContent) 279 if err != nil { 280 err = WrapError(ErrInternal, err, "failed to marshal json response") 281 RespondWithError(w, err) 282 return 283 } 284 285 w.Header().Set("Content-Type", "application/json") 286 w.WriteHeader(http.StatusOK) 287 w.Write(respBody) 288 } 289 290 func RespondWithError(w http.ResponseWriter, err error) { 291 rpcErr, ok := err.(Error) 292 if !ok { 293 rpcErr = WrapError(ErrInternal, err, "webrpc error") 294 } 295 296 statusCode := HTTPStatusFromErrorCode(rpcErr.Code()) 297 298 w.Header().Set("Content-Type", "application/json") 299 w.WriteHeader(statusCode) 300 301 respBody, _ := json.Marshal(rpcErr.Payload()) 302 w.Write(respBody) 303 } 304 305 // 306 // Client 307 // 308 309 const ExampleAPIPathPrefix = "/rpc/ExampleAPI/" 310 311 type exampleAPIClient struct { 312 client HTTPClient 313 urls [3]string 314 } 315 316 func NewExampleAPIClient(addr string, client HTTPClient) ExampleAPI { 317 prefix := urlBase(addr) + ExampleAPIPathPrefix 318 urls := [3]string{ 319 prefix + "Ping", 320 prefix + "Status", 321 prefix + "GetUsers", 322 } 323 return &exampleAPIClient{ 324 client: client, 325 urls: urls, 326 } 327 } 328 329 func (c *exampleAPIClient) Ping(ctx context.Context) error { 330 331 err := doJSONRequest(ctx, c.client, c.urls[0], nil, nil) 332 return err 333 } 334 335 func (c *exampleAPIClient) Status(ctx context.Context) (bool, error) { 336 out := struct { 337 Ret0 bool `json:"status"` 338 }{} 339 340 err := doJSONRequest(ctx, c.client, c.urls[1], nil, &out) 341 return out.Ret0, err 342 } 343 344 func (c *exampleAPIClient) GetUsers(ctx context.Context) ([]*User, *Location, error) { 345 out := struct { 346 Ret0 []*User `json:"users"` 347 Ret1 *Location `json:"location"` 348 }{} 349 350 err := doJSONRequest(ctx, c.client, c.urls[2], nil, &out) 351 return out.Ret0, out.Ret1, err 352 } 353 354 // HTTPClient is the interface used by generated clients to send HTTP requests. 355 // It is fulfilled by *(net/http).Client, which is sufficient for most users. 356 // Users can provide their own implementation for special retry policies. 357 type HTTPClient interface { 358 Do(req *http.Request) (*http.Response, error) 359 } 360 361 // urlBase helps ensure that addr specifies a scheme. If it is unparsable 362 // as a URL, it returns addr unchanged. 363 func urlBase(addr string) string { 364 // If the addr specifies a scheme, use it. If not, default to 365 // http. If url.Parse fails on it, return it unchanged. 366 url, err := url.Parse(addr) 367 if err != nil { 368 return addr 369 } 370 if url.Scheme == "" { 371 url.Scheme = "http" 372 } 373 return url.String() 374 } 375 376 // newRequest makes an http.Request from a client, adding common headers. 377 func newRequest(ctx context.Context, url string, reqBody io.Reader, contentType string) (*http.Request, error) { 378 req, err := http.NewRequest("POST", url, reqBody) 379 if err != nil { 380 return nil, err 381 } 382 req.Header.Set("Accept", contentType) 383 req.Header.Set("Content-Type", contentType) 384 if headers, ok := HTTPRequestHeaders(ctx); ok { 385 for k := range headers { 386 for _, v := range headers[k] { 387 req.Header.Add(k, v) 388 } 389 } 390 } 391 return req, nil 392 } 393 394 // doJSONRequest is common code to make a request to the remote service. 395 func doJSONRequest(ctx context.Context, client HTTPClient, url string, in, out interface{}) error { 396 reqBody, err := json.Marshal(in) 397 if err != nil { 398 return clientError("failed to marshal json request", err) 399 } 400 if err = ctx.Err(); err != nil { 401 return clientError("aborted because context was done", err) 402 } 403 404 req, err := newRequest(ctx, url, bytes.NewBuffer(reqBody), "application/json") 405 if err != nil { 406 return clientError("could not build request", err) 407 } 408 resp, err := client.Do(req) 409 if err != nil { 410 return clientError("request failed", err) 411 } 412 413 defer func() { 414 cerr := resp.Body.Close() 415 if err == nil && cerr != nil { 416 err = clientError("failed to close response body", cerr) 417 } 418 }() 419 420 if err = ctx.Err(); err != nil { 421 return clientError("aborted because context was done", err) 422 } 423 424 if resp.StatusCode != 200 { 425 return errorFromResponse(resp) 426 } 427 428 if out != nil { 429 respBody, err := ioutil.ReadAll(resp.Body) 430 if err != nil { 431 return clientError("failed to read response body", err) 432 } 433 434 err = json.Unmarshal(respBody, &out) 435 if err != nil { 436 return clientError("failed to unmarshal json response body", err) 437 } 438 if err = ctx.Err(); err != nil { 439 return clientError("aborted because context was done", err) 440 } 441 } 442 443 return nil 444 } 445 446 // errorFromResponse builds a webrpc Error from a non-200 HTTP response. 447 func errorFromResponse(resp *http.Response) Error { 448 respBody, err := ioutil.ReadAll(resp.Body) 449 if err != nil { 450 return clientError("failed to read server error response body", err) 451 } 452 453 var respErr ErrorPayload 454 if err := json.Unmarshal(respBody, &respErr); err != nil { 455 return clientError("failed unmarshal error response", err) 456 } 457 458 errCode := ErrorCode(respErr.Code) 459 460 if HTTPStatusFromErrorCode(errCode) == 0 { 461 return ErrorInternal("invalid code returned from server error response: %s", respErr.Code) 462 } 463 464 return &rpcErr{ 465 code: errCode, 466 msg: respErr.Msg, 467 cause: errors.New(respErr.Cause), 468 } 469 } 470 471 func clientError(desc string, err error) Error { 472 return WrapError(ErrInternal, err, desc) 473 } 474 475 func WithHTTPRequestHeaders(ctx context.Context, h http.Header) (context.Context, error) { 476 if _, ok := h["Accept"]; ok { 477 return nil, errors.New("provided header cannot set Accept") 478 } 479 if _, ok := h["Content-Type"]; ok { 480 return nil, errors.New("provided header cannot set Content-Type") 481 } 482 483 copied := make(http.Header, len(h)) 484 for k, vv := range h { 485 if vv == nil { 486 copied[k] = nil 487 continue 488 } 489 copied[k] = make([]string, len(vv)) 490 copy(copied[k], vv) 491 } 492 493 return context.WithValue(ctx, HTTPClientRequestHeadersCtxKey, copied), nil 494 } 495 496 func HTTPRequestHeaders(ctx context.Context) (http.Header, bool) { 497 h, ok := ctx.Value(HTTPClientRequestHeadersCtxKey).(http.Header) 498 return h, ok 499 } 500 501 // 502 // Helpers 503 // 504 505 type ErrorPayload struct { 506 Status int `json:"status"` 507 Code string `json:"code"` 508 Cause string `json:"cause,omitempty"` 509 Msg string `json:"msg"` 510 Error string `json:"error"` 511 } 512 513 type Error interface { 514 // Code is of the valid error codes 515 Code() ErrorCode 516 517 // Msg returns a human-readable, unstructured messages describing the error 518 Msg() string 519 520 // Cause is reason for the error 521 Cause() error 522 523 // Error returns a string of the form "webrpc error <Code>: <Msg>" 524 Error() string 525 526 // Error response payload 527 Payload() ErrorPayload 528 } 529 530 func Errorf(code ErrorCode, msgf string, args ...interface{}) Error { 531 msg := fmt.Sprintf(msgf, args...) 532 if IsValidErrorCode(code) { 533 return &rpcErr{code: code, msg: msg} 534 } 535 return &rpcErr{code: ErrInternal, msg: "invalid error type " + string(code)} 536 } 537 538 func WrapError(code ErrorCode, cause error, format string, args ...interface{}) Error { 539 msg := fmt.Sprintf(format, args...) 540 if IsValidErrorCode(code) { 541 return &rpcErr{code: code, msg: msg, cause: cause} 542 } 543 return &rpcErr{code: ErrInternal, msg: "invalid error type " + string(code), cause: cause} 544 } 545 546 func Failf(format string, args ...interface{}) Error { 547 return Errorf(ErrFail, format, args...) 548 } 549 550 func WrapFailf(cause error, format string, args ...interface{}) Error { 551 return WrapError(ErrFail, cause, format, args...) 552 } 553 554 func ErrorNotFound(format string, args ...interface{}) Error { 555 return Errorf(ErrNotFound, format, args...) 556 } 557 558 func ErrorInvalidArgument(argument string, validationMsg string) Error { 559 return Errorf(ErrInvalidArgument, argument+" "+validationMsg) 560 } 561 562 func ErrorRequiredArgument(argument string) Error { 563 return ErrorInvalidArgument(argument, "is required") 564 } 565 566 func ErrorInternal(format string, args ...interface{}) Error { 567 return Errorf(ErrInternal, format, args...) 568 } 569 570 type ErrorCode string 571 572 const ( 573 // Unknown error. For example when handling errors raised by APIs that do not 574 // return enough error information. 575 ErrUnknown ErrorCode = "unknown" 576 577 // Fail error. General failure error type. 578 ErrFail ErrorCode = "fail" 579 580 // Canceled indicates the operation was cancelled (typically by the caller). 581 ErrCanceled ErrorCode = "canceled" 582 583 // InvalidArgument indicates client specified an invalid argument. It 584 // indicates arguments that are problematic regardless of the state of the 585 // system (i.e. a malformed file name, required argument, number out of range, 586 // etc.). 587 ErrInvalidArgument ErrorCode = "invalid argument" 588 589 // DeadlineExceeded means operation expired before completion. For operations 590 // that change the state of the system, this error may be returned even if the 591 // operation has completed successfully (timeout). 592 ErrDeadlineExceeded ErrorCode = "deadline exceeded" 593 594 // NotFound means some requested entity was not found. 595 ErrNotFound ErrorCode = "not found" 596 597 // BadRoute means that the requested URL path wasn't routable to a webrpc 598 // service and method. This is returned by the generated server, and usually 599 // shouldn't be returned by applications. Instead, applications should use 600 // NotFound or Unimplemented. 601 ErrBadRoute ErrorCode = "bad route" 602 603 // AlreadyExists means an attempt to create an entity failed because one 604 // already exists. 605 ErrAlreadyExists ErrorCode = "already exists" 606 607 // PermissionDenied indicates the caller does not have permission to execute 608 // the specified operation. It must not be used if the caller cannot be 609 // identified (Unauthenticated). 610 ErrPermissionDenied ErrorCode = "permission denied" 611 612 // Unauthenticated indicates the request does not have valid authentication 613 // credentials for the operation. 614 ErrUnauthenticated ErrorCode = "unauthenticated" 615 616 // ResourceExhausted indicates some resource has been exhausted, perhaps a 617 // per-user quota, or perhaps the entire file system is out of space. 618 ErrResourceExhausted ErrorCode = "resource exhausted" 619 620 // FailedPrecondition indicates operation was rejected because the system is 621 // not in a state required for the operation's execution. For example, doing 622 // an rmdir operation on a directory that is non-empty, or on a non-directory 623 // object, or when having conflicting read-modify-write on the same resource. 624 ErrFailedPrecondition ErrorCode = "failed precondition" 625 626 // Aborted indicates the operation was aborted, typically due to a concurrency 627 // issue like sequencer check failures, transaction aborts, etc. 628 ErrAborted ErrorCode = "aborted" 629 630 // OutOfRange means operation was attempted past the valid range. For example, 631 // seeking or reading past end of a paginated collection. 632 // 633 // Unlike InvalidArgument, this error indicates a problem that may be fixed if 634 // the system state changes (i.e. adding more items to the collection). 635 // 636 // There is a fair bit of overlap between FailedPrecondition and OutOfRange. 637 // We recommend using OutOfRange (the more specific error) when it applies so 638 // that callers who are iterating through a space can easily look for an 639 // OutOfRange error to detect when they are done. 640 ErrOutOfRange ErrorCode = "out of range" 641 642 // Unimplemented indicates operation is not implemented or not 643 // supported/enabled in this service. 644 ErrUnimplemented ErrorCode = "unimplemented" 645 646 // Internal errors. When some invariants expected by the underlying system 647 // have been broken. In other words, something bad happened in the library or 648 // backend service. Do not confuse with HTTP Internal Server Error; an 649 // Internal error could also happen on the client code, i.e. when parsing a 650 // server response. 651 ErrInternal ErrorCode = "internal" 652 653 // Unavailable indicates the service is currently unavailable. This is a most 654 // likely a transient condition and may be corrected by retrying with a 655 // backoff. 656 ErrUnavailable ErrorCode = "unavailable" 657 658 // DataLoss indicates unrecoverable data loss or corruption. 659 ErrDataLoss ErrorCode = "data loss" 660 661 // ErrNone is the zero-value, is considered an empty error and should not be 662 // used. 663 ErrNone ErrorCode = "" 664 ) 665 666 func HTTPStatusFromErrorCode(code ErrorCode) int { 667 switch code { 668 case ErrCanceled: 669 return 408 // RequestTimeout 670 case ErrUnknown: 671 return 400 // Bad Request 672 case ErrFail: 673 return 422 // Unprocessable Entity 674 case ErrInvalidArgument: 675 return 400 // BadRequest 676 case ErrDeadlineExceeded: 677 return 408 // RequestTimeout 678 case ErrNotFound: 679 return 404 // Not Found 680 case ErrBadRoute: 681 return 404 // Not Found 682 case ErrAlreadyExists: 683 return 409 // Conflict 684 case ErrPermissionDenied: 685 return 403 // Forbidden 686 case ErrUnauthenticated: 687 return 401 // Unauthorized 688 case ErrResourceExhausted: 689 return 403 // Forbidden 690 case ErrFailedPrecondition: 691 return 412 // Precondition Failed 692 case ErrAborted: 693 return 409 // Conflict 694 case ErrOutOfRange: 695 return 400 // Bad Request 696 case ErrUnimplemented: 697 return 501 // Not Implemented 698 case ErrInternal: 699 return 500 // Internal Server Error 700 case ErrUnavailable: 701 return 503 // Service Unavailable 702 case ErrDataLoss: 703 return 500 // Internal Server Error 704 case ErrNone: 705 return 200 // OK 706 default: 707 return 0 // Invalid! 708 } 709 } 710 711 func IsErrorCode(err error, code ErrorCode) bool { 712 if rpcErr, ok := err.(Error); ok { 713 if rpcErr.Code() == code { 714 return true 715 } 716 } 717 return false 718 } 719 720 func IsValidErrorCode(code ErrorCode) bool { 721 return HTTPStatusFromErrorCode(code) != 0 722 } 723 724 type rpcErr struct { 725 code ErrorCode 726 msg string 727 cause error 728 } 729 730 func (e *rpcErr) Code() ErrorCode { 731 return e.code 732 } 733 734 func (e *rpcErr) Msg() string { 735 return e.msg 736 } 737 738 func (e *rpcErr) Cause() error { 739 return e.cause 740 } 741 742 func (e *rpcErr) Error() string { 743 if e.cause != nil && e.cause.Error() != "" { 744 if e.msg != "" { 745 return fmt.Sprintf("webrpc %s error: %s -- %s", e.code, e.cause.Error(), e.msg) 746 } else { 747 return fmt.Sprintf("webrpc %s error: %s", e.code, e.cause.Error()) 748 } 749 } else { 750 return fmt.Sprintf("webrpc %s error: %s", e.code, e.msg) 751 } 752 } 753 754 func (e *rpcErr) Payload() ErrorPayload { 755 statusCode := HTTPStatusFromErrorCode(e.Code()) 756 errPayload := ErrorPayload{ 757 Status: statusCode, 758 Code: string(e.Code()), 759 Msg: e.Msg(), 760 Error: e.Error(), 761 } 762 if e.Cause() != nil { 763 errPayload.Cause = e.Cause().Error() 764 } 765 return errPayload 766 } 767 768 type contextKey struct { 769 name string 770 } 771 772 func (k *contextKey) String() string { 773 return "webrpc context value " + k.name 774 } 775 776 var ( 777 // For Client 778 HTTPClientRequestHeadersCtxKey = &contextKey{"HTTPClientRequestHeaders"} 779 780 // For Server 781 HTTPResponseWriterCtxKey = &contextKey{"HTTPResponseWriter"} 782 783 HTTPRequestCtxKey = &contextKey{"HTTPRequest"} 784 785 ServiceNameCtxKey = &contextKey{"ServiceName"} 786 787 MethodNameCtxKey = &contextKey{"MethodName"} 788 )