github.com/whoyao/protocol@v0.0.0-20230519045905-2d8ace718ca5/livekit/livekit_egress.twirp.go (about) 1 // Code generated by protoc-gen-twirp v8.1.3, DO NOT EDIT. 2 // source: livekit_egress.proto 3 4 package livekit 5 6 import context "context" 7 import fmt "fmt" 8 import http "net/http" 9 import io "io" 10 import json "encoding/json" 11 import strconv "strconv" 12 import strings "strings" 13 14 import protojson "google.golang.org/protobuf/encoding/protojson" 15 import proto "google.golang.org/protobuf/proto" 16 import twirp "github.com/twitchtv/twirp" 17 import ctxsetters "github.com/twitchtv/twirp/ctxsetters" 18 19 import bytes "bytes" 20 import errors "errors" 21 import path "path" 22 import url "net/url" 23 24 // Version compatibility assertion. 25 // If the constant is not defined in the package, that likely means 26 // the package needs to be updated to work with this generated code. 27 // See https://twitchtv.github.io/twirp/docs/version_matrix.html 28 const _ = twirp.TwirpPackageMinVersion_8_1_0 29 30 // ================ 31 // Egress Interface 32 // ================ 33 34 type Egress interface { 35 // start recording or streaming a room, participant, or tracks 36 StartRoomCompositeEgress(context.Context, *RoomCompositeEgressRequest) (*EgressInfo, error) 37 38 StartTrackCompositeEgress(context.Context, *TrackCompositeEgressRequest) (*EgressInfo, error) 39 40 StartTrackEgress(context.Context, *TrackEgressRequest) (*EgressInfo, error) 41 42 StartWebEgress(context.Context, *WebEgressRequest) (*EgressInfo, error) 43 44 // update web composite layout 45 UpdateLayout(context.Context, *UpdateLayoutRequest) (*EgressInfo, error) 46 47 // add or remove stream endpoints 48 UpdateStream(context.Context, *UpdateStreamRequest) (*EgressInfo, error) 49 50 // list available egress 51 ListEgress(context.Context, *ListEgressRequest) (*ListEgressResponse, error) 52 53 // stop a recording or stream 54 StopEgress(context.Context, *StopEgressRequest) (*EgressInfo, error) 55 } 56 57 // ====================== 58 // Egress Protobuf Client 59 // ====================== 60 61 type egressProtobufClient struct { 62 client HTTPClient 63 urls [8]string 64 interceptor twirp.Interceptor 65 opts twirp.ClientOptions 66 } 67 68 // NewEgressProtobufClient creates a Protobuf client that implements the Egress interface. 69 // It communicates using Protobuf and can be configured with a custom HTTPClient. 70 func NewEgressProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Egress { 71 if c, ok := client.(*http.Client); ok { 72 client = withoutRedirects(c) 73 } 74 75 clientOpts := twirp.ClientOptions{} 76 for _, o := range opts { 77 o(&clientOpts) 78 } 79 80 // Using ReadOpt allows backwards and forwards compatibility with new options in the future 81 literalURLs := false 82 _ = clientOpts.ReadOpt("literalURLs", &literalURLs) 83 var pathPrefix string 84 if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { 85 pathPrefix = "/twirp" // default prefix 86 } 87 88 // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method> 89 serviceURL := sanitizeBaseURL(baseURL) 90 serviceURL += baseServicePath(pathPrefix, "livekit", "Egress") 91 urls := [8]string{ 92 serviceURL + "StartRoomCompositeEgress", 93 serviceURL + "StartTrackCompositeEgress", 94 serviceURL + "StartTrackEgress", 95 serviceURL + "StartWebEgress", 96 serviceURL + "UpdateLayout", 97 serviceURL + "UpdateStream", 98 serviceURL + "ListEgress", 99 serviceURL + "StopEgress", 100 } 101 102 return &egressProtobufClient{ 103 client: client, 104 urls: urls, 105 interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), 106 opts: clientOpts, 107 } 108 } 109 110 func (c *egressProtobufClient) StartRoomCompositeEgress(ctx context.Context, in *RoomCompositeEgressRequest) (*EgressInfo, error) { 111 ctx = ctxsetters.WithPackageName(ctx, "livekit") 112 ctx = ctxsetters.WithServiceName(ctx, "Egress") 113 ctx = ctxsetters.WithMethodName(ctx, "StartRoomCompositeEgress") 114 caller := c.callStartRoomCompositeEgress 115 if c.interceptor != nil { 116 caller = func(ctx context.Context, req *RoomCompositeEgressRequest) (*EgressInfo, error) { 117 resp, err := c.interceptor( 118 func(ctx context.Context, req interface{}) (interface{}, error) { 119 typedReq, ok := req.(*RoomCompositeEgressRequest) 120 if !ok { 121 return nil, twirp.InternalError("failed type assertion req.(*RoomCompositeEgressRequest) when calling interceptor") 122 } 123 return c.callStartRoomCompositeEgress(ctx, typedReq) 124 }, 125 )(ctx, req) 126 if resp != nil { 127 typedResp, ok := resp.(*EgressInfo) 128 if !ok { 129 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 130 } 131 return typedResp, err 132 } 133 return nil, err 134 } 135 } 136 return caller(ctx, in) 137 } 138 139 func (c *egressProtobufClient) callStartRoomCompositeEgress(ctx context.Context, in *RoomCompositeEgressRequest) (*EgressInfo, error) { 140 out := new(EgressInfo) 141 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) 142 if err != nil { 143 twerr, ok := err.(twirp.Error) 144 if !ok { 145 twerr = twirp.InternalErrorWith(err) 146 } 147 callClientError(ctx, c.opts.Hooks, twerr) 148 return nil, err 149 } 150 151 callClientResponseReceived(ctx, c.opts.Hooks) 152 153 return out, nil 154 } 155 156 func (c *egressProtobufClient) StartTrackCompositeEgress(ctx context.Context, in *TrackCompositeEgressRequest) (*EgressInfo, error) { 157 ctx = ctxsetters.WithPackageName(ctx, "livekit") 158 ctx = ctxsetters.WithServiceName(ctx, "Egress") 159 ctx = ctxsetters.WithMethodName(ctx, "StartTrackCompositeEgress") 160 caller := c.callStartTrackCompositeEgress 161 if c.interceptor != nil { 162 caller = func(ctx context.Context, req *TrackCompositeEgressRequest) (*EgressInfo, error) { 163 resp, err := c.interceptor( 164 func(ctx context.Context, req interface{}) (interface{}, error) { 165 typedReq, ok := req.(*TrackCompositeEgressRequest) 166 if !ok { 167 return nil, twirp.InternalError("failed type assertion req.(*TrackCompositeEgressRequest) when calling interceptor") 168 } 169 return c.callStartTrackCompositeEgress(ctx, typedReq) 170 }, 171 )(ctx, req) 172 if resp != nil { 173 typedResp, ok := resp.(*EgressInfo) 174 if !ok { 175 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 176 } 177 return typedResp, err 178 } 179 return nil, err 180 } 181 } 182 return caller(ctx, in) 183 } 184 185 func (c *egressProtobufClient) callStartTrackCompositeEgress(ctx context.Context, in *TrackCompositeEgressRequest) (*EgressInfo, error) { 186 out := new(EgressInfo) 187 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out) 188 if err != nil { 189 twerr, ok := err.(twirp.Error) 190 if !ok { 191 twerr = twirp.InternalErrorWith(err) 192 } 193 callClientError(ctx, c.opts.Hooks, twerr) 194 return nil, err 195 } 196 197 callClientResponseReceived(ctx, c.opts.Hooks) 198 199 return out, nil 200 } 201 202 func (c *egressProtobufClient) StartTrackEgress(ctx context.Context, in *TrackEgressRequest) (*EgressInfo, error) { 203 ctx = ctxsetters.WithPackageName(ctx, "livekit") 204 ctx = ctxsetters.WithServiceName(ctx, "Egress") 205 ctx = ctxsetters.WithMethodName(ctx, "StartTrackEgress") 206 caller := c.callStartTrackEgress 207 if c.interceptor != nil { 208 caller = func(ctx context.Context, req *TrackEgressRequest) (*EgressInfo, error) { 209 resp, err := c.interceptor( 210 func(ctx context.Context, req interface{}) (interface{}, error) { 211 typedReq, ok := req.(*TrackEgressRequest) 212 if !ok { 213 return nil, twirp.InternalError("failed type assertion req.(*TrackEgressRequest) when calling interceptor") 214 } 215 return c.callStartTrackEgress(ctx, typedReq) 216 }, 217 )(ctx, req) 218 if resp != nil { 219 typedResp, ok := resp.(*EgressInfo) 220 if !ok { 221 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 222 } 223 return typedResp, err 224 } 225 return nil, err 226 } 227 } 228 return caller(ctx, in) 229 } 230 231 func (c *egressProtobufClient) callStartTrackEgress(ctx context.Context, in *TrackEgressRequest) (*EgressInfo, error) { 232 out := new(EgressInfo) 233 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out) 234 if err != nil { 235 twerr, ok := err.(twirp.Error) 236 if !ok { 237 twerr = twirp.InternalErrorWith(err) 238 } 239 callClientError(ctx, c.opts.Hooks, twerr) 240 return nil, err 241 } 242 243 callClientResponseReceived(ctx, c.opts.Hooks) 244 245 return out, nil 246 } 247 248 func (c *egressProtobufClient) StartWebEgress(ctx context.Context, in *WebEgressRequest) (*EgressInfo, error) { 249 ctx = ctxsetters.WithPackageName(ctx, "livekit") 250 ctx = ctxsetters.WithServiceName(ctx, "Egress") 251 ctx = ctxsetters.WithMethodName(ctx, "StartWebEgress") 252 caller := c.callStartWebEgress 253 if c.interceptor != nil { 254 caller = func(ctx context.Context, req *WebEgressRequest) (*EgressInfo, error) { 255 resp, err := c.interceptor( 256 func(ctx context.Context, req interface{}) (interface{}, error) { 257 typedReq, ok := req.(*WebEgressRequest) 258 if !ok { 259 return nil, twirp.InternalError("failed type assertion req.(*WebEgressRequest) when calling interceptor") 260 } 261 return c.callStartWebEgress(ctx, typedReq) 262 }, 263 )(ctx, req) 264 if resp != nil { 265 typedResp, ok := resp.(*EgressInfo) 266 if !ok { 267 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 268 } 269 return typedResp, err 270 } 271 return nil, err 272 } 273 } 274 return caller(ctx, in) 275 } 276 277 func (c *egressProtobufClient) callStartWebEgress(ctx context.Context, in *WebEgressRequest) (*EgressInfo, error) { 278 out := new(EgressInfo) 279 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out) 280 if err != nil { 281 twerr, ok := err.(twirp.Error) 282 if !ok { 283 twerr = twirp.InternalErrorWith(err) 284 } 285 callClientError(ctx, c.opts.Hooks, twerr) 286 return nil, err 287 } 288 289 callClientResponseReceived(ctx, c.opts.Hooks) 290 291 return out, nil 292 } 293 294 func (c *egressProtobufClient) UpdateLayout(ctx context.Context, in *UpdateLayoutRequest) (*EgressInfo, error) { 295 ctx = ctxsetters.WithPackageName(ctx, "livekit") 296 ctx = ctxsetters.WithServiceName(ctx, "Egress") 297 ctx = ctxsetters.WithMethodName(ctx, "UpdateLayout") 298 caller := c.callUpdateLayout 299 if c.interceptor != nil { 300 caller = func(ctx context.Context, req *UpdateLayoutRequest) (*EgressInfo, error) { 301 resp, err := c.interceptor( 302 func(ctx context.Context, req interface{}) (interface{}, error) { 303 typedReq, ok := req.(*UpdateLayoutRequest) 304 if !ok { 305 return nil, twirp.InternalError("failed type assertion req.(*UpdateLayoutRequest) when calling interceptor") 306 } 307 return c.callUpdateLayout(ctx, typedReq) 308 }, 309 )(ctx, req) 310 if resp != nil { 311 typedResp, ok := resp.(*EgressInfo) 312 if !ok { 313 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 314 } 315 return typedResp, err 316 } 317 return nil, err 318 } 319 } 320 return caller(ctx, in) 321 } 322 323 func (c *egressProtobufClient) callUpdateLayout(ctx context.Context, in *UpdateLayoutRequest) (*EgressInfo, error) { 324 out := new(EgressInfo) 325 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out) 326 if err != nil { 327 twerr, ok := err.(twirp.Error) 328 if !ok { 329 twerr = twirp.InternalErrorWith(err) 330 } 331 callClientError(ctx, c.opts.Hooks, twerr) 332 return nil, err 333 } 334 335 callClientResponseReceived(ctx, c.opts.Hooks) 336 337 return out, nil 338 } 339 340 func (c *egressProtobufClient) UpdateStream(ctx context.Context, in *UpdateStreamRequest) (*EgressInfo, error) { 341 ctx = ctxsetters.WithPackageName(ctx, "livekit") 342 ctx = ctxsetters.WithServiceName(ctx, "Egress") 343 ctx = ctxsetters.WithMethodName(ctx, "UpdateStream") 344 caller := c.callUpdateStream 345 if c.interceptor != nil { 346 caller = func(ctx context.Context, req *UpdateStreamRequest) (*EgressInfo, error) { 347 resp, err := c.interceptor( 348 func(ctx context.Context, req interface{}) (interface{}, error) { 349 typedReq, ok := req.(*UpdateStreamRequest) 350 if !ok { 351 return nil, twirp.InternalError("failed type assertion req.(*UpdateStreamRequest) when calling interceptor") 352 } 353 return c.callUpdateStream(ctx, typedReq) 354 }, 355 )(ctx, req) 356 if resp != nil { 357 typedResp, ok := resp.(*EgressInfo) 358 if !ok { 359 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 360 } 361 return typedResp, err 362 } 363 return nil, err 364 } 365 } 366 return caller(ctx, in) 367 } 368 369 func (c *egressProtobufClient) callUpdateStream(ctx context.Context, in *UpdateStreamRequest) (*EgressInfo, error) { 370 out := new(EgressInfo) 371 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[5], in, out) 372 if err != nil { 373 twerr, ok := err.(twirp.Error) 374 if !ok { 375 twerr = twirp.InternalErrorWith(err) 376 } 377 callClientError(ctx, c.opts.Hooks, twerr) 378 return nil, err 379 } 380 381 callClientResponseReceived(ctx, c.opts.Hooks) 382 383 return out, nil 384 } 385 386 func (c *egressProtobufClient) ListEgress(ctx context.Context, in *ListEgressRequest) (*ListEgressResponse, error) { 387 ctx = ctxsetters.WithPackageName(ctx, "livekit") 388 ctx = ctxsetters.WithServiceName(ctx, "Egress") 389 ctx = ctxsetters.WithMethodName(ctx, "ListEgress") 390 caller := c.callListEgress 391 if c.interceptor != nil { 392 caller = func(ctx context.Context, req *ListEgressRequest) (*ListEgressResponse, error) { 393 resp, err := c.interceptor( 394 func(ctx context.Context, req interface{}) (interface{}, error) { 395 typedReq, ok := req.(*ListEgressRequest) 396 if !ok { 397 return nil, twirp.InternalError("failed type assertion req.(*ListEgressRequest) when calling interceptor") 398 } 399 return c.callListEgress(ctx, typedReq) 400 }, 401 )(ctx, req) 402 if resp != nil { 403 typedResp, ok := resp.(*ListEgressResponse) 404 if !ok { 405 return nil, twirp.InternalError("failed type assertion resp.(*ListEgressResponse) when calling interceptor") 406 } 407 return typedResp, err 408 } 409 return nil, err 410 } 411 } 412 return caller(ctx, in) 413 } 414 415 func (c *egressProtobufClient) callListEgress(ctx context.Context, in *ListEgressRequest) (*ListEgressResponse, error) { 416 out := new(ListEgressResponse) 417 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[6], in, out) 418 if err != nil { 419 twerr, ok := err.(twirp.Error) 420 if !ok { 421 twerr = twirp.InternalErrorWith(err) 422 } 423 callClientError(ctx, c.opts.Hooks, twerr) 424 return nil, err 425 } 426 427 callClientResponseReceived(ctx, c.opts.Hooks) 428 429 return out, nil 430 } 431 432 func (c *egressProtobufClient) StopEgress(ctx context.Context, in *StopEgressRequest) (*EgressInfo, error) { 433 ctx = ctxsetters.WithPackageName(ctx, "livekit") 434 ctx = ctxsetters.WithServiceName(ctx, "Egress") 435 ctx = ctxsetters.WithMethodName(ctx, "StopEgress") 436 caller := c.callStopEgress 437 if c.interceptor != nil { 438 caller = func(ctx context.Context, req *StopEgressRequest) (*EgressInfo, error) { 439 resp, err := c.interceptor( 440 func(ctx context.Context, req interface{}) (interface{}, error) { 441 typedReq, ok := req.(*StopEgressRequest) 442 if !ok { 443 return nil, twirp.InternalError("failed type assertion req.(*StopEgressRequest) when calling interceptor") 444 } 445 return c.callStopEgress(ctx, typedReq) 446 }, 447 )(ctx, req) 448 if resp != nil { 449 typedResp, ok := resp.(*EgressInfo) 450 if !ok { 451 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 452 } 453 return typedResp, err 454 } 455 return nil, err 456 } 457 } 458 return caller(ctx, in) 459 } 460 461 func (c *egressProtobufClient) callStopEgress(ctx context.Context, in *StopEgressRequest) (*EgressInfo, error) { 462 out := new(EgressInfo) 463 ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[7], in, out) 464 if err != nil { 465 twerr, ok := err.(twirp.Error) 466 if !ok { 467 twerr = twirp.InternalErrorWith(err) 468 } 469 callClientError(ctx, c.opts.Hooks, twerr) 470 return nil, err 471 } 472 473 callClientResponseReceived(ctx, c.opts.Hooks) 474 475 return out, nil 476 } 477 478 // ================== 479 // Egress JSON Client 480 // ================== 481 482 type egressJSONClient struct { 483 client HTTPClient 484 urls [8]string 485 interceptor twirp.Interceptor 486 opts twirp.ClientOptions 487 } 488 489 // NewEgressJSONClient creates a JSON client that implements the Egress interface. 490 // It communicates using JSON and can be configured with a custom HTTPClient. 491 func NewEgressJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Egress { 492 if c, ok := client.(*http.Client); ok { 493 client = withoutRedirects(c) 494 } 495 496 clientOpts := twirp.ClientOptions{} 497 for _, o := range opts { 498 o(&clientOpts) 499 } 500 501 // Using ReadOpt allows backwards and forwards compatibility with new options in the future 502 literalURLs := false 503 _ = clientOpts.ReadOpt("literalURLs", &literalURLs) 504 var pathPrefix string 505 if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { 506 pathPrefix = "/twirp" // default prefix 507 } 508 509 // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method> 510 serviceURL := sanitizeBaseURL(baseURL) 511 serviceURL += baseServicePath(pathPrefix, "livekit", "Egress") 512 urls := [8]string{ 513 serviceURL + "StartRoomCompositeEgress", 514 serviceURL + "StartTrackCompositeEgress", 515 serviceURL + "StartTrackEgress", 516 serviceURL + "StartWebEgress", 517 serviceURL + "UpdateLayout", 518 serviceURL + "UpdateStream", 519 serviceURL + "ListEgress", 520 serviceURL + "StopEgress", 521 } 522 523 return &egressJSONClient{ 524 client: client, 525 urls: urls, 526 interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), 527 opts: clientOpts, 528 } 529 } 530 531 func (c *egressJSONClient) StartRoomCompositeEgress(ctx context.Context, in *RoomCompositeEgressRequest) (*EgressInfo, error) { 532 ctx = ctxsetters.WithPackageName(ctx, "livekit") 533 ctx = ctxsetters.WithServiceName(ctx, "Egress") 534 ctx = ctxsetters.WithMethodName(ctx, "StartRoomCompositeEgress") 535 caller := c.callStartRoomCompositeEgress 536 if c.interceptor != nil { 537 caller = func(ctx context.Context, req *RoomCompositeEgressRequest) (*EgressInfo, error) { 538 resp, err := c.interceptor( 539 func(ctx context.Context, req interface{}) (interface{}, error) { 540 typedReq, ok := req.(*RoomCompositeEgressRequest) 541 if !ok { 542 return nil, twirp.InternalError("failed type assertion req.(*RoomCompositeEgressRequest) when calling interceptor") 543 } 544 return c.callStartRoomCompositeEgress(ctx, typedReq) 545 }, 546 )(ctx, req) 547 if resp != nil { 548 typedResp, ok := resp.(*EgressInfo) 549 if !ok { 550 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 551 } 552 return typedResp, err 553 } 554 return nil, err 555 } 556 } 557 return caller(ctx, in) 558 } 559 560 func (c *egressJSONClient) callStartRoomCompositeEgress(ctx context.Context, in *RoomCompositeEgressRequest) (*EgressInfo, error) { 561 out := new(EgressInfo) 562 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) 563 if err != nil { 564 twerr, ok := err.(twirp.Error) 565 if !ok { 566 twerr = twirp.InternalErrorWith(err) 567 } 568 callClientError(ctx, c.opts.Hooks, twerr) 569 return nil, err 570 } 571 572 callClientResponseReceived(ctx, c.opts.Hooks) 573 574 return out, nil 575 } 576 577 func (c *egressJSONClient) StartTrackCompositeEgress(ctx context.Context, in *TrackCompositeEgressRequest) (*EgressInfo, error) { 578 ctx = ctxsetters.WithPackageName(ctx, "livekit") 579 ctx = ctxsetters.WithServiceName(ctx, "Egress") 580 ctx = ctxsetters.WithMethodName(ctx, "StartTrackCompositeEgress") 581 caller := c.callStartTrackCompositeEgress 582 if c.interceptor != nil { 583 caller = func(ctx context.Context, req *TrackCompositeEgressRequest) (*EgressInfo, error) { 584 resp, err := c.interceptor( 585 func(ctx context.Context, req interface{}) (interface{}, error) { 586 typedReq, ok := req.(*TrackCompositeEgressRequest) 587 if !ok { 588 return nil, twirp.InternalError("failed type assertion req.(*TrackCompositeEgressRequest) when calling interceptor") 589 } 590 return c.callStartTrackCompositeEgress(ctx, typedReq) 591 }, 592 )(ctx, req) 593 if resp != nil { 594 typedResp, ok := resp.(*EgressInfo) 595 if !ok { 596 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 597 } 598 return typedResp, err 599 } 600 return nil, err 601 } 602 } 603 return caller(ctx, in) 604 } 605 606 func (c *egressJSONClient) callStartTrackCompositeEgress(ctx context.Context, in *TrackCompositeEgressRequest) (*EgressInfo, error) { 607 out := new(EgressInfo) 608 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out) 609 if err != nil { 610 twerr, ok := err.(twirp.Error) 611 if !ok { 612 twerr = twirp.InternalErrorWith(err) 613 } 614 callClientError(ctx, c.opts.Hooks, twerr) 615 return nil, err 616 } 617 618 callClientResponseReceived(ctx, c.opts.Hooks) 619 620 return out, nil 621 } 622 623 func (c *egressJSONClient) StartTrackEgress(ctx context.Context, in *TrackEgressRequest) (*EgressInfo, error) { 624 ctx = ctxsetters.WithPackageName(ctx, "livekit") 625 ctx = ctxsetters.WithServiceName(ctx, "Egress") 626 ctx = ctxsetters.WithMethodName(ctx, "StartTrackEgress") 627 caller := c.callStartTrackEgress 628 if c.interceptor != nil { 629 caller = func(ctx context.Context, req *TrackEgressRequest) (*EgressInfo, error) { 630 resp, err := c.interceptor( 631 func(ctx context.Context, req interface{}) (interface{}, error) { 632 typedReq, ok := req.(*TrackEgressRequest) 633 if !ok { 634 return nil, twirp.InternalError("failed type assertion req.(*TrackEgressRequest) when calling interceptor") 635 } 636 return c.callStartTrackEgress(ctx, typedReq) 637 }, 638 )(ctx, req) 639 if resp != nil { 640 typedResp, ok := resp.(*EgressInfo) 641 if !ok { 642 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 643 } 644 return typedResp, err 645 } 646 return nil, err 647 } 648 } 649 return caller(ctx, in) 650 } 651 652 func (c *egressJSONClient) callStartTrackEgress(ctx context.Context, in *TrackEgressRequest) (*EgressInfo, error) { 653 out := new(EgressInfo) 654 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out) 655 if err != nil { 656 twerr, ok := err.(twirp.Error) 657 if !ok { 658 twerr = twirp.InternalErrorWith(err) 659 } 660 callClientError(ctx, c.opts.Hooks, twerr) 661 return nil, err 662 } 663 664 callClientResponseReceived(ctx, c.opts.Hooks) 665 666 return out, nil 667 } 668 669 func (c *egressJSONClient) StartWebEgress(ctx context.Context, in *WebEgressRequest) (*EgressInfo, error) { 670 ctx = ctxsetters.WithPackageName(ctx, "livekit") 671 ctx = ctxsetters.WithServiceName(ctx, "Egress") 672 ctx = ctxsetters.WithMethodName(ctx, "StartWebEgress") 673 caller := c.callStartWebEgress 674 if c.interceptor != nil { 675 caller = func(ctx context.Context, req *WebEgressRequest) (*EgressInfo, error) { 676 resp, err := c.interceptor( 677 func(ctx context.Context, req interface{}) (interface{}, error) { 678 typedReq, ok := req.(*WebEgressRequest) 679 if !ok { 680 return nil, twirp.InternalError("failed type assertion req.(*WebEgressRequest) when calling interceptor") 681 } 682 return c.callStartWebEgress(ctx, typedReq) 683 }, 684 )(ctx, req) 685 if resp != nil { 686 typedResp, ok := resp.(*EgressInfo) 687 if !ok { 688 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 689 } 690 return typedResp, err 691 } 692 return nil, err 693 } 694 } 695 return caller(ctx, in) 696 } 697 698 func (c *egressJSONClient) callStartWebEgress(ctx context.Context, in *WebEgressRequest) (*EgressInfo, error) { 699 out := new(EgressInfo) 700 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out) 701 if err != nil { 702 twerr, ok := err.(twirp.Error) 703 if !ok { 704 twerr = twirp.InternalErrorWith(err) 705 } 706 callClientError(ctx, c.opts.Hooks, twerr) 707 return nil, err 708 } 709 710 callClientResponseReceived(ctx, c.opts.Hooks) 711 712 return out, nil 713 } 714 715 func (c *egressJSONClient) UpdateLayout(ctx context.Context, in *UpdateLayoutRequest) (*EgressInfo, error) { 716 ctx = ctxsetters.WithPackageName(ctx, "livekit") 717 ctx = ctxsetters.WithServiceName(ctx, "Egress") 718 ctx = ctxsetters.WithMethodName(ctx, "UpdateLayout") 719 caller := c.callUpdateLayout 720 if c.interceptor != nil { 721 caller = func(ctx context.Context, req *UpdateLayoutRequest) (*EgressInfo, error) { 722 resp, err := c.interceptor( 723 func(ctx context.Context, req interface{}) (interface{}, error) { 724 typedReq, ok := req.(*UpdateLayoutRequest) 725 if !ok { 726 return nil, twirp.InternalError("failed type assertion req.(*UpdateLayoutRequest) when calling interceptor") 727 } 728 return c.callUpdateLayout(ctx, typedReq) 729 }, 730 )(ctx, req) 731 if resp != nil { 732 typedResp, ok := resp.(*EgressInfo) 733 if !ok { 734 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 735 } 736 return typedResp, err 737 } 738 return nil, err 739 } 740 } 741 return caller(ctx, in) 742 } 743 744 func (c *egressJSONClient) callUpdateLayout(ctx context.Context, in *UpdateLayoutRequest) (*EgressInfo, error) { 745 out := new(EgressInfo) 746 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out) 747 if err != nil { 748 twerr, ok := err.(twirp.Error) 749 if !ok { 750 twerr = twirp.InternalErrorWith(err) 751 } 752 callClientError(ctx, c.opts.Hooks, twerr) 753 return nil, err 754 } 755 756 callClientResponseReceived(ctx, c.opts.Hooks) 757 758 return out, nil 759 } 760 761 func (c *egressJSONClient) UpdateStream(ctx context.Context, in *UpdateStreamRequest) (*EgressInfo, error) { 762 ctx = ctxsetters.WithPackageName(ctx, "livekit") 763 ctx = ctxsetters.WithServiceName(ctx, "Egress") 764 ctx = ctxsetters.WithMethodName(ctx, "UpdateStream") 765 caller := c.callUpdateStream 766 if c.interceptor != nil { 767 caller = func(ctx context.Context, req *UpdateStreamRequest) (*EgressInfo, error) { 768 resp, err := c.interceptor( 769 func(ctx context.Context, req interface{}) (interface{}, error) { 770 typedReq, ok := req.(*UpdateStreamRequest) 771 if !ok { 772 return nil, twirp.InternalError("failed type assertion req.(*UpdateStreamRequest) when calling interceptor") 773 } 774 return c.callUpdateStream(ctx, typedReq) 775 }, 776 )(ctx, req) 777 if resp != nil { 778 typedResp, ok := resp.(*EgressInfo) 779 if !ok { 780 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 781 } 782 return typedResp, err 783 } 784 return nil, err 785 } 786 } 787 return caller(ctx, in) 788 } 789 790 func (c *egressJSONClient) callUpdateStream(ctx context.Context, in *UpdateStreamRequest) (*EgressInfo, error) { 791 out := new(EgressInfo) 792 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[5], in, out) 793 if err != nil { 794 twerr, ok := err.(twirp.Error) 795 if !ok { 796 twerr = twirp.InternalErrorWith(err) 797 } 798 callClientError(ctx, c.opts.Hooks, twerr) 799 return nil, err 800 } 801 802 callClientResponseReceived(ctx, c.opts.Hooks) 803 804 return out, nil 805 } 806 807 func (c *egressJSONClient) ListEgress(ctx context.Context, in *ListEgressRequest) (*ListEgressResponse, error) { 808 ctx = ctxsetters.WithPackageName(ctx, "livekit") 809 ctx = ctxsetters.WithServiceName(ctx, "Egress") 810 ctx = ctxsetters.WithMethodName(ctx, "ListEgress") 811 caller := c.callListEgress 812 if c.interceptor != nil { 813 caller = func(ctx context.Context, req *ListEgressRequest) (*ListEgressResponse, error) { 814 resp, err := c.interceptor( 815 func(ctx context.Context, req interface{}) (interface{}, error) { 816 typedReq, ok := req.(*ListEgressRequest) 817 if !ok { 818 return nil, twirp.InternalError("failed type assertion req.(*ListEgressRequest) when calling interceptor") 819 } 820 return c.callListEgress(ctx, typedReq) 821 }, 822 )(ctx, req) 823 if resp != nil { 824 typedResp, ok := resp.(*ListEgressResponse) 825 if !ok { 826 return nil, twirp.InternalError("failed type assertion resp.(*ListEgressResponse) when calling interceptor") 827 } 828 return typedResp, err 829 } 830 return nil, err 831 } 832 } 833 return caller(ctx, in) 834 } 835 836 func (c *egressJSONClient) callListEgress(ctx context.Context, in *ListEgressRequest) (*ListEgressResponse, error) { 837 out := new(ListEgressResponse) 838 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[6], in, out) 839 if err != nil { 840 twerr, ok := err.(twirp.Error) 841 if !ok { 842 twerr = twirp.InternalErrorWith(err) 843 } 844 callClientError(ctx, c.opts.Hooks, twerr) 845 return nil, err 846 } 847 848 callClientResponseReceived(ctx, c.opts.Hooks) 849 850 return out, nil 851 } 852 853 func (c *egressJSONClient) StopEgress(ctx context.Context, in *StopEgressRequest) (*EgressInfo, error) { 854 ctx = ctxsetters.WithPackageName(ctx, "livekit") 855 ctx = ctxsetters.WithServiceName(ctx, "Egress") 856 ctx = ctxsetters.WithMethodName(ctx, "StopEgress") 857 caller := c.callStopEgress 858 if c.interceptor != nil { 859 caller = func(ctx context.Context, req *StopEgressRequest) (*EgressInfo, error) { 860 resp, err := c.interceptor( 861 func(ctx context.Context, req interface{}) (interface{}, error) { 862 typedReq, ok := req.(*StopEgressRequest) 863 if !ok { 864 return nil, twirp.InternalError("failed type assertion req.(*StopEgressRequest) when calling interceptor") 865 } 866 return c.callStopEgress(ctx, typedReq) 867 }, 868 )(ctx, req) 869 if resp != nil { 870 typedResp, ok := resp.(*EgressInfo) 871 if !ok { 872 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 873 } 874 return typedResp, err 875 } 876 return nil, err 877 } 878 } 879 return caller(ctx, in) 880 } 881 882 func (c *egressJSONClient) callStopEgress(ctx context.Context, in *StopEgressRequest) (*EgressInfo, error) { 883 out := new(EgressInfo) 884 ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[7], in, out) 885 if err != nil { 886 twerr, ok := err.(twirp.Error) 887 if !ok { 888 twerr = twirp.InternalErrorWith(err) 889 } 890 callClientError(ctx, c.opts.Hooks, twerr) 891 return nil, err 892 } 893 894 callClientResponseReceived(ctx, c.opts.Hooks) 895 896 return out, nil 897 } 898 899 // ===================== 900 // Egress Server Handler 901 // ===================== 902 903 type egressServer struct { 904 Egress 905 interceptor twirp.Interceptor 906 hooks *twirp.ServerHooks 907 pathPrefix string // prefix for routing 908 jsonSkipDefaults bool // do not include unpopulated fields (default values) in the response 909 jsonCamelCase bool // JSON fields are serialized as lowerCamelCase rather than keeping the original proto names 910 } 911 912 // NewEgressServer builds a TwirpServer that can be used as an http.Handler to handle 913 // HTTP requests that are routed to the right method in the provided svc implementation. 914 // The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks). 915 func NewEgressServer(svc Egress, opts ...interface{}) TwirpServer { 916 serverOpts := newServerOpts(opts) 917 918 // Using ReadOpt allows backwards and forwards compatibility with new options in the future 919 jsonSkipDefaults := false 920 _ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults) 921 jsonCamelCase := false 922 _ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase) 923 var pathPrefix string 924 if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { 925 pathPrefix = "/twirp" // default prefix 926 } 927 928 return &egressServer{ 929 Egress: svc, 930 hooks: serverOpts.Hooks, 931 interceptor: twirp.ChainInterceptors(serverOpts.Interceptors...), 932 pathPrefix: pathPrefix, 933 jsonSkipDefaults: jsonSkipDefaults, 934 jsonCamelCase: jsonCamelCase, 935 } 936 } 937 938 // writeError writes an HTTP response with a valid Twirp error format, and triggers hooks. 939 // If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err) 940 func (s *egressServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) { 941 writeError(ctx, resp, err, s.hooks) 942 } 943 944 // handleRequestBodyError is used to handle error when the twirp server cannot read request 945 func (s *egressServer) handleRequestBodyError(ctx context.Context, resp http.ResponseWriter, msg string, err error) { 946 if context.Canceled == ctx.Err() { 947 s.writeError(ctx, resp, twirp.NewError(twirp.Canceled, "failed to read request: context canceled")) 948 return 949 } 950 if context.DeadlineExceeded == ctx.Err() { 951 s.writeError(ctx, resp, twirp.NewError(twirp.DeadlineExceeded, "failed to read request: deadline exceeded")) 952 return 953 } 954 s.writeError(ctx, resp, twirp.WrapError(malformedRequestError(msg), err)) 955 } 956 957 // EgressPathPrefix is a convenience constant that may identify URL paths. 958 // Should be used with caution, it only matches routes generated by Twirp Go clients, 959 // with the default "/twirp" prefix and default CamelCase service and method names. 960 // More info: https://twitchtv.github.io/twirp/docs/routing.html 961 const EgressPathPrefix = "/twirp/livekit.Egress/" 962 963 func (s *egressServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 964 ctx := req.Context() 965 ctx = ctxsetters.WithPackageName(ctx, "livekit") 966 ctx = ctxsetters.WithServiceName(ctx, "Egress") 967 ctx = ctxsetters.WithResponseWriter(ctx, resp) 968 969 var err error 970 ctx, err = callRequestReceived(ctx, s.hooks) 971 if err != nil { 972 s.writeError(ctx, resp, err) 973 return 974 } 975 976 if req.Method != "POST" { 977 msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method) 978 s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 979 return 980 } 981 982 // Verify path format: [<prefix>]/<package>.<Service>/<Method> 983 prefix, pkgService, method := parseTwirpPath(req.URL.Path) 984 if pkgService != "livekit.Egress" { 985 msg := fmt.Sprintf("no handler for path %q", req.URL.Path) 986 s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 987 return 988 } 989 if prefix != s.pathPrefix { 990 msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path) 991 s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 992 return 993 } 994 995 switch method { 996 case "StartRoomCompositeEgress": 997 s.serveStartRoomCompositeEgress(ctx, resp, req) 998 return 999 case "StartTrackCompositeEgress": 1000 s.serveStartTrackCompositeEgress(ctx, resp, req) 1001 return 1002 case "StartTrackEgress": 1003 s.serveStartTrackEgress(ctx, resp, req) 1004 return 1005 case "StartWebEgress": 1006 s.serveStartWebEgress(ctx, resp, req) 1007 return 1008 case "UpdateLayout": 1009 s.serveUpdateLayout(ctx, resp, req) 1010 return 1011 case "UpdateStream": 1012 s.serveUpdateStream(ctx, resp, req) 1013 return 1014 case "ListEgress": 1015 s.serveListEgress(ctx, resp, req) 1016 return 1017 case "StopEgress": 1018 s.serveStopEgress(ctx, resp, req) 1019 return 1020 default: 1021 msg := fmt.Sprintf("no handler for path %q", req.URL.Path) 1022 s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 1023 return 1024 } 1025 } 1026 1027 func (s *egressServer) serveStartRoomCompositeEgress(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1028 header := req.Header.Get("Content-Type") 1029 i := strings.Index(header, ";") 1030 if i == -1 { 1031 i = len(header) 1032 } 1033 switch strings.TrimSpace(strings.ToLower(header[:i])) { 1034 case "application/json": 1035 s.serveStartRoomCompositeEgressJSON(ctx, resp, req) 1036 case "application/protobuf": 1037 s.serveStartRoomCompositeEgressProtobuf(ctx, resp, req) 1038 default: 1039 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 1040 twerr := badRouteError(msg, req.Method, req.URL.Path) 1041 s.writeError(ctx, resp, twerr) 1042 } 1043 } 1044 1045 func (s *egressServer) serveStartRoomCompositeEgressJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1046 var err error 1047 ctx = ctxsetters.WithMethodName(ctx, "StartRoomCompositeEgress") 1048 ctx, err = callRequestRouted(ctx, s.hooks) 1049 if err != nil { 1050 s.writeError(ctx, resp, err) 1051 return 1052 } 1053 1054 d := json.NewDecoder(req.Body) 1055 rawReqBody := json.RawMessage{} 1056 if err := d.Decode(&rawReqBody); err != nil { 1057 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1058 return 1059 } 1060 reqContent := new(RoomCompositeEgressRequest) 1061 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 1062 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 1063 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1064 return 1065 } 1066 1067 handler := s.Egress.StartRoomCompositeEgress 1068 if s.interceptor != nil { 1069 handler = func(ctx context.Context, req *RoomCompositeEgressRequest) (*EgressInfo, error) { 1070 resp, err := s.interceptor( 1071 func(ctx context.Context, req interface{}) (interface{}, error) { 1072 typedReq, ok := req.(*RoomCompositeEgressRequest) 1073 if !ok { 1074 return nil, twirp.InternalError("failed type assertion req.(*RoomCompositeEgressRequest) when calling interceptor") 1075 } 1076 return s.Egress.StartRoomCompositeEgress(ctx, typedReq) 1077 }, 1078 )(ctx, req) 1079 if resp != nil { 1080 typedResp, ok := resp.(*EgressInfo) 1081 if !ok { 1082 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1083 } 1084 return typedResp, err 1085 } 1086 return nil, err 1087 } 1088 } 1089 1090 // Call service method 1091 var respContent *EgressInfo 1092 func() { 1093 defer ensurePanicResponses(ctx, resp, s.hooks) 1094 respContent, err = handler(ctx, reqContent) 1095 }() 1096 1097 if err != nil { 1098 s.writeError(ctx, resp, err) 1099 return 1100 } 1101 if respContent == nil { 1102 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartRoomCompositeEgress. nil responses are not supported")) 1103 return 1104 } 1105 1106 ctx = callResponsePrepared(ctx, s.hooks) 1107 1108 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 1109 respBytes, err := marshaler.Marshal(respContent) 1110 if err != nil { 1111 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 1112 return 1113 } 1114 1115 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1116 resp.Header().Set("Content-Type", "application/json") 1117 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1118 resp.WriteHeader(http.StatusOK) 1119 1120 if n, err := resp.Write(respBytes); err != nil { 1121 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1122 twerr := twirp.NewError(twirp.Unknown, msg) 1123 ctx = callError(ctx, s.hooks, twerr) 1124 } 1125 callResponseSent(ctx, s.hooks) 1126 } 1127 1128 func (s *egressServer) serveStartRoomCompositeEgressProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1129 var err error 1130 ctx = ctxsetters.WithMethodName(ctx, "StartRoomCompositeEgress") 1131 ctx, err = callRequestRouted(ctx, s.hooks) 1132 if err != nil { 1133 s.writeError(ctx, resp, err) 1134 return 1135 } 1136 1137 buf, err := io.ReadAll(req.Body) 1138 if err != nil { 1139 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 1140 return 1141 } 1142 reqContent := new(RoomCompositeEgressRequest) 1143 if err = proto.Unmarshal(buf, reqContent); err != nil { 1144 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 1145 return 1146 } 1147 1148 handler := s.Egress.StartRoomCompositeEgress 1149 if s.interceptor != nil { 1150 handler = func(ctx context.Context, req *RoomCompositeEgressRequest) (*EgressInfo, error) { 1151 resp, err := s.interceptor( 1152 func(ctx context.Context, req interface{}) (interface{}, error) { 1153 typedReq, ok := req.(*RoomCompositeEgressRequest) 1154 if !ok { 1155 return nil, twirp.InternalError("failed type assertion req.(*RoomCompositeEgressRequest) when calling interceptor") 1156 } 1157 return s.Egress.StartRoomCompositeEgress(ctx, typedReq) 1158 }, 1159 )(ctx, req) 1160 if resp != nil { 1161 typedResp, ok := resp.(*EgressInfo) 1162 if !ok { 1163 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1164 } 1165 return typedResp, err 1166 } 1167 return nil, err 1168 } 1169 } 1170 1171 // Call service method 1172 var respContent *EgressInfo 1173 func() { 1174 defer ensurePanicResponses(ctx, resp, s.hooks) 1175 respContent, err = handler(ctx, reqContent) 1176 }() 1177 1178 if err != nil { 1179 s.writeError(ctx, resp, err) 1180 return 1181 } 1182 if respContent == nil { 1183 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartRoomCompositeEgress. nil responses are not supported")) 1184 return 1185 } 1186 1187 ctx = callResponsePrepared(ctx, s.hooks) 1188 1189 respBytes, err := proto.Marshal(respContent) 1190 if err != nil { 1191 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 1192 return 1193 } 1194 1195 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1196 resp.Header().Set("Content-Type", "application/protobuf") 1197 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1198 resp.WriteHeader(http.StatusOK) 1199 if n, err := resp.Write(respBytes); err != nil { 1200 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1201 twerr := twirp.NewError(twirp.Unknown, msg) 1202 ctx = callError(ctx, s.hooks, twerr) 1203 } 1204 callResponseSent(ctx, s.hooks) 1205 } 1206 1207 func (s *egressServer) serveStartTrackCompositeEgress(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1208 header := req.Header.Get("Content-Type") 1209 i := strings.Index(header, ";") 1210 if i == -1 { 1211 i = len(header) 1212 } 1213 switch strings.TrimSpace(strings.ToLower(header[:i])) { 1214 case "application/json": 1215 s.serveStartTrackCompositeEgressJSON(ctx, resp, req) 1216 case "application/protobuf": 1217 s.serveStartTrackCompositeEgressProtobuf(ctx, resp, req) 1218 default: 1219 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 1220 twerr := badRouteError(msg, req.Method, req.URL.Path) 1221 s.writeError(ctx, resp, twerr) 1222 } 1223 } 1224 1225 func (s *egressServer) serveStartTrackCompositeEgressJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1226 var err error 1227 ctx = ctxsetters.WithMethodName(ctx, "StartTrackCompositeEgress") 1228 ctx, err = callRequestRouted(ctx, s.hooks) 1229 if err != nil { 1230 s.writeError(ctx, resp, err) 1231 return 1232 } 1233 1234 d := json.NewDecoder(req.Body) 1235 rawReqBody := json.RawMessage{} 1236 if err := d.Decode(&rawReqBody); err != nil { 1237 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1238 return 1239 } 1240 reqContent := new(TrackCompositeEgressRequest) 1241 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 1242 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 1243 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1244 return 1245 } 1246 1247 handler := s.Egress.StartTrackCompositeEgress 1248 if s.interceptor != nil { 1249 handler = func(ctx context.Context, req *TrackCompositeEgressRequest) (*EgressInfo, error) { 1250 resp, err := s.interceptor( 1251 func(ctx context.Context, req interface{}) (interface{}, error) { 1252 typedReq, ok := req.(*TrackCompositeEgressRequest) 1253 if !ok { 1254 return nil, twirp.InternalError("failed type assertion req.(*TrackCompositeEgressRequest) when calling interceptor") 1255 } 1256 return s.Egress.StartTrackCompositeEgress(ctx, typedReq) 1257 }, 1258 )(ctx, req) 1259 if resp != nil { 1260 typedResp, ok := resp.(*EgressInfo) 1261 if !ok { 1262 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1263 } 1264 return typedResp, err 1265 } 1266 return nil, err 1267 } 1268 } 1269 1270 // Call service method 1271 var respContent *EgressInfo 1272 func() { 1273 defer ensurePanicResponses(ctx, resp, s.hooks) 1274 respContent, err = handler(ctx, reqContent) 1275 }() 1276 1277 if err != nil { 1278 s.writeError(ctx, resp, err) 1279 return 1280 } 1281 if respContent == nil { 1282 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartTrackCompositeEgress. nil responses are not supported")) 1283 return 1284 } 1285 1286 ctx = callResponsePrepared(ctx, s.hooks) 1287 1288 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 1289 respBytes, err := marshaler.Marshal(respContent) 1290 if err != nil { 1291 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 1292 return 1293 } 1294 1295 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1296 resp.Header().Set("Content-Type", "application/json") 1297 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1298 resp.WriteHeader(http.StatusOK) 1299 1300 if n, err := resp.Write(respBytes); err != nil { 1301 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1302 twerr := twirp.NewError(twirp.Unknown, msg) 1303 ctx = callError(ctx, s.hooks, twerr) 1304 } 1305 callResponseSent(ctx, s.hooks) 1306 } 1307 1308 func (s *egressServer) serveStartTrackCompositeEgressProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1309 var err error 1310 ctx = ctxsetters.WithMethodName(ctx, "StartTrackCompositeEgress") 1311 ctx, err = callRequestRouted(ctx, s.hooks) 1312 if err != nil { 1313 s.writeError(ctx, resp, err) 1314 return 1315 } 1316 1317 buf, err := io.ReadAll(req.Body) 1318 if err != nil { 1319 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 1320 return 1321 } 1322 reqContent := new(TrackCompositeEgressRequest) 1323 if err = proto.Unmarshal(buf, reqContent); err != nil { 1324 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 1325 return 1326 } 1327 1328 handler := s.Egress.StartTrackCompositeEgress 1329 if s.interceptor != nil { 1330 handler = func(ctx context.Context, req *TrackCompositeEgressRequest) (*EgressInfo, error) { 1331 resp, err := s.interceptor( 1332 func(ctx context.Context, req interface{}) (interface{}, error) { 1333 typedReq, ok := req.(*TrackCompositeEgressRequest) 1334 if !ok { 1335 return nil, twirp.InternalError("failed type assertion req.(*TrackCompositeEgressRequest) when calling interceptor") 1336 } 1337 return s.Egress.StartTrackCompositeEgress(ctx, typedReq) 1338 }, 1339 )(ctx, req) 1340 if resp != nil { 1341 typedResp, ok := resp.(*EgressInfo) 1342 if !ok { 1343 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1344 } 1345 return typedResp, err 1346 } 1347 return nil, err 1348 } 1349 } 1350 1351 // Call service method 1352 var respContent *EgressInfo 1353 func() { 1354 defer ensurePanicResponses(ctx, resp, s.hooks) 1355 respContent, err = handler(ctx, reqContent) 1356 }() 1357 1358 if err != nil { 1359 s.writeError(ctx, resp, err) 1360 return 1361 } 1362 if respContent == nil { 1363 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartTrackCompositeEgress. nil responses are not supported")) 1364 return 1365 } 1366 1367 ctx = callResponsePrepared(ctx, s.hooks) 1368 1369 respBytes, err := proto.Marshal(respContent) 1370 if err != nil { 1371 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 1372 return 1373 } 1374 1375 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1376 resp.Header().Set("Content-Type", "application/protobuf") 1377 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1378 resp.WriteHeader(http.StatusOK) 1379 if n, err := resp.Write(respBytes); err != nil { 1380 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1381 twerr := twirp.NewError(twirp.Unknown, msg) 1382 ctx = callError(ctx, s.hooks, twerr) 1383 } 1384 callResponseSent(ctx, s.hooks) 1385 } 1386 1387 func (s *egressServer) serveStartTrackEgress(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1388 header := req.Header.Get("Content-Type") 1389 i := strings.Index(header, ";") 1390 if i == -1 { 1391 i = len(header) 1392 } 1393 switch strings.TrimSpace(strings.ToLower(header[:i])) { 1394 case "application/json": 1395 s.serveStartTrackEgressJSON(ctx, resp, req) 1396 case "application/protobuf": 1397 s.serveStartTrackEgressProtobuf(ctx, resp, req) 1398 default: 1399 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 1400 twerr := badRouteError(msg, req.Method, req.URL.Path) 1401 s.writeError(ctx, resp, twerr) 1402 } 1403 } 1404 1405 func (s *egressServer) serveStartTrackEgressJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1406 var err error 1407 ctx = ctxsetters.WithMethodName(ctx, "StartTrackEgress") 1408 ctx, err = callRequestRouted(ctx, s.hooks) 1409 if err != nil { 1410 s.writeError(ctx, resp, err) 1411 return 1412 } 1413 1414 d := json.NewDecoder(req.Body) 1415 rawReqBody := json.RawMessage{} 1416 if err := d.Decode(&rawReqBody); err != nil { 1417 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1418 return 1419 } 1420 reqContent := new(TrackEgressRequest) 1421 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 1422 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 1423 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1424 return 1425 } 1426 1427 handler := s.Egress.StartTrackEgress 1428 if s.interceptor != nil { 1429 handler = func(ctx context.Context, req *TrackEgressRequest) (*EgressInfo, error) { 1430 resp, err := s.interceptor( 1431 func(ctx context.Context, req interface{}) (interface{}, error) { 1432 typedReq, ok := req.(*TrackEgressRequest) 1433 if !ok { 1434 return nil, twirp.InternalError("failed type assertion req.(*TrackEgressRequest) when calling interceptor") 1435 } 1436 return s.Egress.StartTrackEgress(ctx, typedReq) 1437 }, 1438 )(ctx, req) 1439 if resp != nil { 1440 typedResp, ok := resp.(*EgressInfo) 1441 if !ok { 1442 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1443 } 1444 return typedResp, err 1445 } 1446 return nil, err 1447 } 1448 } 1449 1450 // Call service method 1451 var respContent *EgressInfo 1452 func() { 1453 defer ensurePanicResponses(ctx, resp, s.hooks) 1454 respContent, err = handler(ctx, reqContent) 1455 }() 1456 1457 if err != nil { 1458 s.writeError(ctx, resp, err) 1459 return 1460 } 1461 if respContent == nil { 1462 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartTrackEgress. nil responses are not supported")) 1463 return 1464 } 1465 1466 ctx = callResponsePrepared(ctx, s.hooks) 1467 1468 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 1469 respBytes, err := marshaler.Marshal(respContent) 1470 if err != nil { 1471 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 1472 return 1473 } 1474 1475 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1476 resp.Header().Set("Content-Type", "application/json") 1477 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1478 resp.WriteHeader(http.StatusOK) 1479 1480 if n, err := resp.Write(respBytes); err != nil { 1481 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1482 twerr := twirp.NewError(twirp.Unknown, msg) 1483 ctx = callError(ctx, s.hooks, twerr) 1484 } 1485 callResponseSent(ctx, s.hooks) 1486 } 1487 1488 func (s *egressServer) serveStartTrackEgressProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1489 var err error 1490 ctx = ctxsetters.WithMethodName(ctx, "StartTrackEgress") 1491 ctx, err = callRequestRouted(ctx, s.hooks) 1492 if err != nil { 1493 s.writeError(ctx, resp, err) 1494 return 1495 } 1496 1497 buf, err := io.ReadAll(req.Body) 1498 if err != nil { 1499 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 1500 return 1501 } 1502 reqContent := new(TrackEgressRequest) 1503 if err = proto.Unmarshal(buf, reqContent); err != nil { 1504 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 1505 return 1506 } 1507 1508 handler := s.Egress.StartTrackEgress 1509 if s.interceptor != nil { 1510 handler = func(ctx context.Context, req *TrackEgressRequest) (*EgressInfo, error) { 1511 resp, err := s.interceptor( 1512 func(ctx context.Context, req interface{}) (interface{}, error) { 1513 typedReq, ok := req.(*TrackEgressRequest) 1514 if !ok { 1515 return nil, twirp.InternalError("failed type assertion req.(*TrackEgressRequest) when calling interceptor") 1516 } 1517 return s.Egress.StartTrackEgress(ctx, typedReq) 1518 }, 1519 )(ctx, req) 1520 if resp != nil { 1521 typedResp, ok := resp.(*EgressInfo) 1522 if !ok { 1523 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1524 } 1525 return typedResp, err 1526 } 1527 return nil, err 1528 } 1529 } 1530 1531 // Call service method 1532 var respContent *EgressInfo 1533 func() { 1534 defer ensurePanicResponses(ctx, resp, s.hooks) 1535 respContent, err = handler(ctx, reqContent) 1536 }() 1537 1538 if err != nil { 1539 s.writeError(ctx, resp, err) 1540 return 1541 } 1542 if respContent == nil { 1543 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartTrackEgress. nil responses are not supported")) 1544 return 1545 } 1546 1547 ctx = callResponsePrepared(ctx, s.hooks) 1548 1549 respBytes, err := proto.Marshal(respContent) 1550 if err != nil { 1551 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 1552 return 1553 } 1554 1555 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1556 resp.Header().Set("Content-Type", "application/protobuf") 1557 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1558 resp.WriteHeader(http.StatusOK) 1559 if n, err := resp.Write(respBytes); err != nil { 1560 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1561 twerr := twirp.NewError(twirp.Unknown, msg) 1562 ctx = callError(ctx, s.hooks, twerr) 1563 } 1564 callResponseSent(ctx, s.hooks) 1565 } 1566 1567 func (s *egressServer) serveStartWebEgress(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1568 header := req.Header.Get("Content-Type") 1569 i := strings.Index(header, ";") 1570 if i == -1 { 1571 i = len(header) 1572 } 1573 switch strings.TrimSpace(strings.ToLower(header[:i])) { 1574 case "application/json": 1575 s.serveStartWebEgressJSON(ctx, resp, req) 1576 case "application/protobuf": 1577 s.serveStartWebEgressProtobuf(ctx, resp, req) 1578 default: 1579 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 1580 twerr := badRouteError(msg, req.Method, req.URL.Path) 1581 s.writeError(ctx, resp, twerr) 1582 } 1583 } 1584 1585 func (s *egressServer) serveStartWebEgressJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1586 var err error 1587 ctx = ctxsetters.WithMethodName(ctx, "StartWebEgress") 1588 ctx, err = callRequestRouted(ctx, s.hooks) 1589 if err != nil { 1590 s.writeError(ctx, resp, err) 1591 return 1592 } 1593 1594 d := json.NewDecoder(req.Body) 1595 rawReqBody := json.RawMessage{} 1596 if err := d.Decode(&rawReqBody); err != nil { 1597 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1598 return 1599 } 1600 reqContent := new(WebEgressRequest) 1601 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 1602 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 1603 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1604 return 1605 } 1606 1607 handler := s.Egress.StartWebEgress 1608 if s.interceptor != nil { 1609 handler = func(ctx context.Context, req *WebEgressRequest) (*EgressInfo, error) { 1610 resp, err := s.interceptor( 1611 func(ctx context.Context, req interface{}) (interface{}, error) { 1612 typedReq, ok := req.(*WebEgressRequest) 1613 if !ok { 1614 return nil, twirp.InternalError("failed type assertion req.(*WebEgressRequest) when calling interceptor") 1615 } 1616 return s.Egress.StartWebEgress(ctx, typedReq) 1617 }, 1618 )(ctx, req) 1619 if resp != nil { 1620 typedResp, ok := resp.(*EgressInfo) 1621 if !ok { 1622 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1623 } 1624 return typedResp, err 1625 } 1626 return nil, err 1627 } 1628 } 1629 1630 // Call service method 1631 var respContent *EgressInfo 1632 func() { 1633 defer ensurePanicResponses(ctx, resp, s.hooks) 1634 respContent, err = handler(ctx, reqContent) 1635 }() 1636 1637 if err != nil { 1638 s.writeError(ctx, resp, err) 1639 return 1640 } 1641 if respContent == nil { 1642 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartWebEgress. nil responses are not supported")) 1643 return 1644 } 1645 1646 ctx = callResponsePrepared(ctx, s.hooks) 1647 1648 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 1649 respBytes, err := marshaler.Marshal(respContent) 1650 if err != nil { 1651 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 1652 return 1653 } 1654 1655 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1656 resp.Header().Set("Content-Type", "application/json") 1657 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1658 resp.WriteHeader(http.StatusOK) 1659 1660 if n, err := resp.Write(respBytes); err != nil { 1661 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1662 twerr := twirp.NewError(twirp.Unknown, msg) 1663 ctx = callError(ctx, s.hooks, twerr) 1664 } 1665 callResponseSent(ctx, s.hooks) 1666 } 1667 1668 func (s *egressServer) serveStartWebEgressProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1669 var err error 1670 ctx = ctxsetters.WithMethodName(ctx, "StartWebEgress") 1671 ctx, err = callRequestRouted(ctx, s.hooks) 1672 if err != nil { 1673 s.writeError(ctx, resp, err) 1674 return 1675 } 1676 1677 buf, err := io.ReadAll(req.Body) 1678 if err != nil { 1679 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 1680 return 1681 } 1682 reqContent := new(WebEgressRequest) 1683 if err = proto.Unmarshal(buf, reqContent); err != nil { 1684 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 1685 return 1686 } 1687 1688 handler := s.Egress.StartWebEgress 1689 if s.interceptor != nil { 1690 handler = func(ctx context.Context, req *WebEgressRequest) (*EgressInfo, error) { 1691 resp, err := s.interceptor( 1692 func(ctx context.Context, req interface{}) (interface{}, error) { 1693 typedReq, ok := req.(*WebEgressRequest) 1694 if !ok { 1695 return nil, twirp.InternalError("failed type assertion req.(*WebEgressRequest) when calling interceptor") 1696 } 1697 return s.Egress.StartWebEgress(ctx, typedReq) 1698 }, 1699 )(ctx, req) 1700 if resp != nil { 1701 typedResp, ok := resp.(*EgressInfo) 1702 if !ok { 1703 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1704 } 1705 return typedResp, err 1706 } 1707 return nil, err 1708 } 1709 } 1710 1711 // Call service method 1712 var respContent *EgressInfo 1713 func() { 1714 defer ensurePanicResponses(ctx, resp, s.hooks) 1715 respContent, err = handler(ctx, reqContent) 1716 }() 1717 1718 if err != nil { 1719 s.writeError(ctx, resp, err) 1720 return 1721 } 1722 if respContent == nil { 1723 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StartWebEgress. nil responses are not supported")) 1724 return 1725 } 1726 1727 ctx = callResponsePrepared(ctx, s.hooks) 1728 1729 respBytes, err := proto.Marshal(respContent) 1730 if err != nil { 1731 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 1732 return 1733 } 1734 1735 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1736 resp.Header().Set("Content-Type", "application/protobuf") 1737 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1738 resp.WriteHeader(http.StatusOK) 1739 if n, err := resp.Write(respBytes); err != nil { 1740 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1741 twerr := twirp.NewError(twirp.Unknown, msg) 1742 ctx = callError(ctx, s.hooks, twerr) 1743 } 1744 callResponseSent(ctx, s.hooks) 1745 } 1746 1747 func (s *egressServer) serveUpdateLayout(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1748 header := req.Header.Get("Content-Type") 1749 i := strings.Index(header, ";") 1750 if i == -1 { 1751 i = len(header) 1752 } 1753 switch strings.TrimSpace(strings.ToLower(header[:i])) { 1754 case "application/json": 1755 s.serveUpdateLayoutJSON(ctx, resp, req) 1756 case "application/protobuf": 1757 s.serveUpdateLayoutProtobuf(ctx, resp, req) 1758 default: 1759 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 1760 twerr := badRouteError(msg, req.Method, req.URL.Path) 1761 s.writeError(ctx, resp, twerr) 1762 } 1763 } 1764 1765 func (s *egressServer) serveUpdateLayoutJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1766 var err error 1767 ctx = ctxsetters.WithMethodName(ctx, "UpdateLayout") 1768 ctx, err = callRequestRouted(ctx, s.hooks) 1769 if err != nil { 1770 s.writeError(ctx, resp, err) 1771 return 1772 } 1773 1774 d := json.NewDecoder(req.Body) 1775 rawReqBody := json.RawMessage{} 1776 if err := d.Decode(&rawReqBody); err != nil { 1777 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1778 return 1779 } 1780 reqContent := new(UpdateLayoutRequest) 1781 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 1782 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 1783 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1784 return 1785 } 1786 1787 handler := s.Egress.UpdateLayout 1788 if s.interceptor != nil { 1789 handler = func(ctx context.Context, req *UpdateLayoutRequest) (*EgressInfo, error) { 1790 resp, err := s.interceptor( 1791 func(ctx context.Context, req interface{}) (interface{}, error) { 1792 typedReq, ok := req.(*UpdateLayoutRequest) 1793 if !ok { 1794 return nil, twirp.InternalError("failed type assertion req.(*UpdateLayoutRequest) when calling interceptor") 1795 } 1796 return s.Egress.UpdateLayout(ctx, typedReq) 1797 }, 1798 )(ctx, req) 1799 if resp != nil { 1800 typedResp, ok := resp.(*EgressInfo) 1801 if !ok { 1802 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1803 } 1804 return typedResp, err 1805 } 1806 return nil, err 1807 } 1808 } 1809 1810 // Call service method 1811 var respContent *EgressInfo 1812 func() { 1813 defer ensurePanicResponses(ctx, resp, s.hooks) 1814 respContent, err = handler(ctx, reqContent) 1815 }() 1816 1817 if err != nil { 1818 s.writeError(ctx, resp, err) 1819 return 1820 } 1821 if respContent == nil { 1822 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling UpdateLayout. nil responses are not supported")) 1823 return 1824 } 1825 1826 ctx = callResponsePrepared(ctx, s.hooks) 1827 1828 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 1829 respBytes, err := marshaler.Marshal(respContent) 1830 if err != nil { 1831 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 1832 return 1833 } 1834 1835 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1836 resp.Header().Set("Content-Type", "application/json") 1837 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1838 resp.WriteHeader(http.StatusOK) 1839 1840 if n, err := resp.Write(respBytes); err != nil { 1841 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1842 twerr := twirp.NewError(twirp.Unknown, msg) 1843 ctx = callError(ctx, s.hooks, twerr) 1844 } 1845 callResponseSent(ctx, s.hooks) 1846 } 1847 1848 func (s *egressServer) serveUpdateLayoutProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1849 var err error 1850 ctx = ctxsetters.WithMethodName(ctx, "UpdateLayout") 1851 ctx, err = callRequestRouted(ctx, s.hooks) 1852 if err != nil { 1853 s.writeError(ctx, resp, err) 1854 return 1855 } 1856 1857 buf, err := io.ReadAll(req.Body) 1858 if err != nil { 1859 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 1860 return 1861 } 1862 reqContent := new(UpdateLayoutRequest) 1863 if err = proto.Unmarshal(buf, reqContent); err != nil { 1864 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 1865 return 1866 } 1867 1868 handler := s.Egress.UpdateLayout 1869 if s.interceptor != nil { 1870 handler = func(ctx context.Context, req *UpdateLayoutRequest) (*EgressInfo, error) { 1871 resp, err := s.interceptor( 1872 func(ctx context.Context, req interface{}) (interface{}, error) { 1873 typedReq, ok := req.(*UpdateLayoutRequest) 1874 if !ok { 1875 return nil, twirp.InternalError("failed type assertion req.(*UpdateLayoutRequest) when calling interceptor") 1876 } 1877 return s.Egress.UpdateLayout(ctx, typedReq) 1878 }, 1879 )(ctx, req) 1880 if resp != nil { 1881 typedResp, ok := resp.(*EgressInfo) 1882 if !ok { 1883 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1884 } 1885 return typedResp, err 1886 } 1887 return nil, err 1888 } 1889 } 1890 1891 // Call service method 1892 var respContent *EgressInfo 1893 func() { 1894 defer ensurePanicResponses(ctx, resp, s.hooks) 1895 respContent, err = handler(ctx, reqContent) 1896 }() 1897 1898 if err != nil { 1899 s.writeError(ctx, resp, err) 1900 return 1901 } 1902 if respContent == nil { 1903 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling UpdateLayout. nil responses are not supported")) 1904 return 1905 } 1906 1907 ctx = callResponsePrepared(ctx, s.hooks) 1908 1909 respBytes, err := proto.Marshal(respContent) 1910 if err != nil { 1911 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 1912 return 1913 } 1914 1915 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1916 resp.Header().Set("Content-Type", "application/protobuf") 1917 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1918 resp.WriteHeader(http.StatusOK) 1919 if n, err := resp.Write(respBytes); err != nil { 1920 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1921 twerr := twirp.NewError(twirp.Unknown, msg) 1922 ctx = callError(ctx, s.hooks, twerr) 1923 } 1924 callResponseSent(ctx, s.hooks) 1925 } 1926 1927 func (s *egressServer) serveUpdateStream(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1928 header := req.Header.Get("Content-Type") 1929 i := strings.Index(header, ";") 1930 if i == -1 { 1931 i = len(header) 1932 } 1933 switch strings.TrimSpace(strings.ToLower(header[:i])) { 1934 case "application/json": 1935 s.serveUpdateStreamJSON(ctx, resp, req) 1936 case "application/protobuf": 1937 s.serveUpdateStreamProtobuf(ctx, resp, req) 1938 default: 1939 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 1940 twerr := badRouteError(msg, req.Method, req.URL.Path) 1941 s.writeError(ctx, resp, twerr) 1942 } 1943 } 1944 1945 func (s *egressServer) serveUpdateStreamJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1946 var err error 1947 ctx = ctxsetters.WithMethodName(ctx, "UpdateStream") 1948 ctx, err = callRequestRouted(ctx, s.hooks) 1949 if err != nil { 1950 s.writeError(ctx, resp, err) 1951 return 1952 } 1953 1954 d := json.NewDecoder(req.Body) 1955 rawReqBody := json.RawMessage{} 1956 if err := d.Decode(&rawReqBody); err != nil { 1957 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1958 return 1959 } 1960 reqContent := new(UpdateStreamRequest) 1961 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 1962 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 1963 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1964 return 1965 } 1966 1967 handler := s.Egress.UpdateStream 1968 if s.interceptor != nil { 1969 handler = func(ctx context.Context, req *UpdateStreamRequest) (*EgressInfo, error) { 1970 resp, err := s.interceptor( 1971 func(ctx context.Context, req interface{}) (interface{}, error) { 1972 typedReq, ok := req.(*UpdateStreamRequest) 1973 if !ok { 1974 return nil, twirp.InternalError("failed type assertion req.(*UpdateStreamRequest) when calling interceptor") 1975 } 1976 return s.Egress.UpdateStream(ctx, typedReq) 1977 }, 1978 )(ctx, req) 1979 if resp != nil { 1980 typedResp, ok := resp.(*EgressInfo) 1981 if !ok { 1982 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 1983 } 1984 return typedResp, err 1985 } 1986 return nil, err 1987 } 1988 } 1989 1990 // Call service method 1991 var respContent *EgressInfo 1992 func() { 1993 defer ensurePanicResponses(ctx, resp, s.hooks) 1994 respContent, err = handler(ctx, reqContent) 1995 }() 1996 1997 if err != nil { 1998 s.writeError(ctx, resp, err) 1999 return 2000 } 2001 if respContent == nil { 2002 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling UpdateStream. nil responses are not supported")) 2003 return 2004 } 2005 2006 ctx = callResponsePrepared(ctx, s.hooks) 2007 2008 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 2009 respBytes, err := marshaler.Marshal(respContent) 2010 if err != nil { 2011 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 2012 return 2013 } 2014 2015 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 2016 resp.Header().Set("Content-Type", "application/json") 2017 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 2018 resp.WriteHeader(http.StatusOK) 2019 2020 if n, err := resp.Write(respBytes); err != nil { 2021 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 2022 twerr := twirp.NewError(twirp.Unknown, msg) 2023 ctx = callError(ctx, s.hooks, twerr) 2024 } 2025 callResponseSent(ctx, s.hooks) 2026 } 2027 2028 func (s *egressServer) serveUpdateStreamProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 2029 var err error 2030 ctx = ctxsetters.WithMethodName(ctx, "UpdateStream") 2031 ctx, err = callRequestRouted(ctx, s.hooks) 2032 if err != nil { 2033 s.writeError(ctx, resp, err) 2034 return 2035 } 2036 2037 buf, err := io.ReadAll(req.Body) 2038 if err != nil { 2039 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 2040 return 2041 } 2042 reqContent := new(UpdateStreamRequest) 2043 if err = proto.Unmarshal(buf, reqContent); err != nil { 2044 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 2045 return 2046 } 2047 2048 handler := s.Egress.UpdateStream 2049 if s.interceptor != nil { 2050 handler = func(ctx context.Context, req *UpdateStreamRequest) (*EgressInfo, error) { 2051 resp, err := s.interceptor( 2052 func(ctx context.Context, req interface{}) (interface{}, error) { 2053 typedReq, ok := req.(*UpdateStreamRequest) 2054 if !ok { 2055 return nil, twirp.InternalError("failed type assertion req.(*UpdateStreamRequest) when calling interceptor") 2056 } 2057 return s.Egress.UpdateStream(ctx, typedReq) 2058 }, 2059 )(ctx, req) 2060 if resp != nil { 2061 typedResp, ok := resp.(*EgressInfo) 2062 if !ok { 2063 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 2064 } 2065 return typedResp, err 2066 } 2067 return nil, err 2068 } 2069 } 2070 2071 // Call service method 2072 var respContent *EgressInfo 2073 func() { 2074 defer ensurePanicResponses(ctx, resp, s.hooks) 2075 respContent, err = handler(ctx, reqContent) 2076 }() 2077 2078 if err != nil { 2079 s.writeError(ctx, resp, err) 2080 return 2081 } 2082 if respContent == nil { 2083 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling UpdateStream. nil responses are not supported")) 2084 return 2085 } 2086 2087 ctx = callResponsePrepared(ctx, s.hooks) 2088 2089 respBytes, err := proto.Marshal(respContent) 2090 if err != nil { 2091 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 2092 return 2093 } 2094 2095 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 2096 resp.Header().Set("Content-Type", "application/protobuf") 2097 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 2098 resp.WriteHeader(http.StatusOK) 2099 if n, err := resp.Write(respBytes); err != nil { 2100 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 2101 twerr := twirp.NewError(twirp.Unknown, msg) 2102 ctx = callError(ctx, s.hooks, twerr) 2103 } 2104 callResponseSent(ctx, s.hooks) 2105 } 2106 2107 func (s *egressServer) serveListEgress(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 2108 header := req.Header.Get("Content-Type") 2109 i := strings.Index(header, ";") 2110 if i == -1 { 2111 i = len(header) 2112 } 2113 switch strings.TrimSpace(strings.ToLower(header[:i])) { 2114 case "application/json": 2115 s.serveListEgressJSON(ctx, resp, req) 2116 case "application/protobuf": 2117 s.serveListEgressProtobuf(ctx, resp, req) 2118 default: 2119 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 2120 twerr := badRouteError(msg, req.Method, req.URL.Path) 2121 s.writeError(ctx, resp, twerr) 2122 } 2123 } 2124 2125 func (s *egressServer) serveListEgressJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 2126 var err error 2127 ctx = ctxsetters.WithMethodName(ctx, "ListEgress") 2128 ctx, err = callRequestRouted(ctx, s.hooks) 2129 if err != nil { 2130 s.writeError(ctx, resp, err) 2131 return 2132 } 2133 2134 d := json.NewDecoder(req.Body) 2135 rawReqBody := json.RawMessage{} 2136 if err := d.Decode(&rawReqBody); err != nil { 2137 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 2138 return 2139 } 2140 reqContent := new(ListEgressRequest) 2141 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 2142 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 2143 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 2144 return 2145 } 2146 2147 handler := s.Egress.ListEgress 2148 if s.interceptor != nil { 2149 handler = func(ctx context.Context, req *ListEgressRequest) (*ListEgressResponse, error) { 2150 resp, err := s.interceptor( 2151 func(ctx context.Context, req interface{}) (interface{}, error) { 2152 typedReq, ok := req.(*ListEgressRequest) 2153 if !ok { 2154 return nil, twirp.InternalError("failed type assertion req.(*ListEgressRequest) when calling interceptor") 2155 } 2156 return s.Egress.ListEgress(ctx, typedReq) 2157 }, 2158 )(ctx, req) 2159 if resp != nil { 2160 typedResp, ok := resp.(*ListEgressResponse) 2161 if !ok { 2162 return nil, twirp.InternalError("failed type assertion resp.(*ListEgressResponse) when calling interceptor") 2163 } 2164 return typedResp, err 2165 } 2166 return nil, err 2167 } 2168 } 2169 2170 // Call service method 2171 var respContent *ListEgressResponse 2172 func() { 2173 defer ensurePanicResponses(ctx, resp, s.hooks) 2174 respContent, err = handler(ctx, reqContent) 2175 }() 2176 2177 if err != nil { 2178 s.writeError(ctx, resp, err) 2179 return 2180 } 2181 if respContent == nil { 2182 s.writeError(ctx, resp, twirp.InternalError("received a nil *ListEgressResponse and nil error while calling ListEgress. nil responses are not supported")) 2183 return 2184 } 2185 2186 ctx = callResponsePrepared(ctx, s.hooks) 2187 2188 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 2189 respBytes, err := marshaler.Marshal(respContent) 2190 if err != nil { 2191 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 2192 return 2193 } 2194 2195 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 2196 resp.Header().Set("Content-Type", "application/json") 2197 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 2198 resp.WriteHeader(http.StatusOK) 2199 2200 if n, err := resp.Write(respBytes); err != nil { 2201 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 2202 twerr := twirp.NewError(twirp.Unknown, msg) 2203 ctx = callError(ctx, s.hooks, twerr) 2204 } 2205 callResponseSent(ctx, s.hooks) 2206 } 2207 2208 func (s *egressServer) serveListEgressProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 2209 var err error 2210 ctx = ctxsetters.WithMethodName(ctx, "ListEgress") 2211 ctx, err = callRequestRouted(ctx, s.hooks) 2212 if err != nil { 2213 s.writeError(ctx, resp, err) 2214 return 2215 } 2216 2217 buf, err := io.ReadAll(req.Body) 2218 if err != nil { 2219 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 2220 return 2221 } 2222 reqContent := new(ListEgressRequest) 2223 if err = proto.Unmarshal(buf, reqContent); err != nil { 2224 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 2225 return 2226 } 2227 2228 handler := s.Egress.ListEgress 2229 if s.interceptor != nil { 2230 handler = func(ctx context.Context, req *ListEgressRequest) (*ListEgressResponse, error) { 2231 resp, err := s.interceptor( 2232 func(ctx context.Context, req interface{}) (interface{}, error) { 2233 typedReq, ok := req.(*ListEgressRequest) 2234 if !ok { 2235 return nil, twirp.InternalError("failed type assertion req.(*ListEgressRequest) when calling interceptor") 2236 } 2237 return s.Egress.ListEgress(ctx, typedReq) 2238 }, 2239 )(ctx, req) 2240 if resp != nil { 2241 typedResp, ok := resp.(*ListEgressResponse) 2242 if !ok { 2243 return nil, twirp.InternalError("failed type assertion resp.(*ListEgressResponse) when calling interceptor") 2244 } 2245 return typedResp, err 2246 } 2247 return nil, err 2248 } 2249 } 2250 2251 // Call service method 2252 var respContent *ListEgressResponse 2253 func() { 2254 defer ensurePanicResponses(ctx, resp, s.hooks) 2255 respContent, err = handler(ctx, reqContent) 2256 }() 2257 2258 if err != nil { 2259 s.writeError(ctx, resp, err) 2260 return 2261 } 2262 if respContent == nil { 2263 s.writeError(ctx, resp, twirp.InternalError("received a nil *ListEgressResponse and nil error while calling ListEgress. nil responses are not supported")) 2264 return 2265 } 2266 2267 ctx = callResponsePrepared(ctx, s.hooks) 2268 2269 respBytes, err := proto.Marshal(respContent) 2270 if err != nil { 2271 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 2272 return 2273 } 2274 2275 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 2276 resp.Header().Set("Content-Type", "application/protobuf") 2277 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 2278 resp.WriteHeader(http.StatusOK) 2279 if n, err := resp.Write(respBytes); err != nil { 2280 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 2281 twerr := twirp.NewError(twirp.Unknown, msg) 2282 ctx = callError(ctx, s.hooks, twerr) 2283 } 2284 callResponseSent(ctx, s.hooks) 2285 } 2286 2287 func (s *egressServer) serveStopEgress(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 2288 header := req.Header.Get("Content-Type") 2289 i := strings.Index(header, ";") 2290 if i == -1 { 2291 i = len(header) 2292 } 2293 switch strings.TrimSpace(strings.ToLower(header[:i])) { 2294 case "application/json": 2295 s.serveStopEgressJSON(ctx, resp, req) 2296 case "application/protobuf": 2297 s.serveStopEgressProtobuf(ctx, resp, req) 2298 default: 2299 msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 2300 twerr := badRouteError(msg, req.Method, req.URL.Path) 2301 s.writeError(ctx, resp, twerr) 2302 } 2303 } 2304 2305 func (s *egressServer) serveStopEgressJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 2306 var err error 2307 ctx = ctxsetters.WithMethodName(ctx, "StopEgress") 2308 ctx, err = callRequestRouted(ctx, s.hooks) 2309 if err != nil { 2310 s.writeError(ctx, resp, err) 2311 return 2312 } 2313 2314 d := json.NewDecoder(req.Body) 2315 rawReqBody := json.RawMessage{} 2316 if err := d.Decode(&rawReqBody); err != nil { 2317 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 2318 return 2319 } 2320 reqContent := new(StopEgressRequest) 2321 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 2322 if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 2323 s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 2324 return 2325 } 2326 2327 handler := s.Egress.StopEgress 2328 if s.interceptor != nil { 2329 handler = func(ctx context.Context, req *StopEgressRequest) (*EgressInfo, error) { 2330 resp, err := s.interceptor( 2331 func(ctx context.Context, req interface{}) (interface{}, error) { 2332 typedReq, ok := req.(*StopEgressRequest) 2333 if !ok { 2334 return nil, twirp.InternalError("failed type assertion req.(*StopEgressRequest) when calling interceptor") 2335 } 2336 return s.Egress.StopEgress(ctx, typedReq) 2337 }, 2338 )(ctx, req) 2339 if resp != nil { 2340 typedResp, ok := resp.(*EgressInfo) 2341 if !ok { 2342 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 2343 } 2344 return typedResp, err 2345 } 2346 return nil, err 2347 } 2348 } 2349 2350 // Call service method 2351 var respContent *EgressInfo 2352 func() { 2353 defer ensurePanicResponses(ctx, resp, s.hooks) 2354 respContent, err = handler(ctx, reqContent) 2355 }() 2356 2357 if err != nil { 2358 s.writeError(ctx, resp, err) 2359 return 2360 } 2361 if respContent == nil { 2362 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StopEgress. nil responses are not supported")) 2363 return 2364 } 2365 2366 ctx = callResponsePrepared(ctx, s.hooks) 2367 2368 marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 2369 respBytes, err := marshaler.Marshal(respContent) 2370 if err != nil { 2371 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 2372 return 2373 } 2374 2375 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 2376 resp.Header().Set("Content-Type", "application/json") 2377 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 2378 resp.WriteHeader(http.StatusOK) 2379 2380 if n, err := resp.Write(respBytes); err != nil { 2381 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 2382 twerr := twirp.NewError(twirp.Unknown, msg) 2383 ctx = callError(ctx, s.hooks, twerr) 2384 } 2385 callResponseSent(ctx, s.hooks) 2386 } 2387 2388 func (s *egressServer) serveStopEgressProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 2389 var err error 2390 ctx = ctxsetters.WithMethodName(ctx, "StopEgress") 2391 ctx, err = callRequestRouted(ctx, s.hooks) 2392 if err != nil { 2393 s.writeError(ctx, resp, err) 2394 return 2395 } 2396 2397 buf, err := io.ReadAll(req.Body) 2398 if err != nil { 2399 s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 2400 return 2401 } 2402 reqContent := new(StopEgressRequest) 2403 if err = proto.Unmarshal(buf, reqContent); err != nil { 2404 s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 2405 return 2406 } 2407 2408 handler := s.Egress.StopEgress 2409 if s.interceptor != nil { 2410 handler = func(ctx context.Context, req *StopEgressRequest) (*EgressInfo, error) { 2411 resp, err := s.interceptor( 2412 func(ctx context.Context, req interface{}) (interface{}, error) { 2413 typedReq, ok := req.(*StopEgressRequest) 2414 if !ok { 2415 return nil, twirp.InternalError("failed type assertion req.(*StopEgressRequest) when calling interceptor") 2416 } 2417 return s.Egress.StopEgress(ctx, typedReq) 2418 }, 2419 )(ctx, req) 2420 if resp != nil { 2421 typedResp, ok := resp.(*EgressInfo) 2422 if !ok { 2423 return nil, twirp.InternalError("failed type assertion resp.(*EgressInfo) when calling interceptor") 2424 } 2425 return typedResp, err 2426 } 2427 return nil, err 2428 } 2429 } 2430 2431 // Call service method 2432 var respContent *EgressInfo 2433 func() { 2434 defer ensurePanicResponses(ctx, resp, s.hooks) 2435 respContent, err = handler(ctx, reqContent) 2436 }() 2437 2438 if err != nil { 2439 s.writeError(ctx, resp, err) 2440 return 2441 } 2442 if respContent == nil { 2443 s.writeError(ctx, resp, twirp.InternalError("received a nil *EgressInfo and nil error while calling StopEgress. nil responses are not supported")) 2444 return 2445 } 2446 2447 ctx = callResponsePrepared(ctx, s.hooks) 2448 2449 respBytes, err := proto.Marshal(respContent) 2450 if err != nil { 2451 s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 2452 return 2453 } 2454 2455 ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 2456 resp.Header().Set("Content-Type", "application/protobuf") 2457 resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 2458 resp.WriteHeader(http.StatusOK) 2459 if n, err := resp.Write(respBytes); err != nil { 2460 msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 2461 twerr := twirp.NewError(twirp.Unknown, msg) 2462 ctx = callError(ctx, s.hooks, twerr) 2463 } 2464 callResponseSent(ctx, s.hooks) 2465 } 2466 2467 func (s *egressServer) ServiceDescriptor() ([]byte, int) { 2468 return twirpFileDescriptor0, 0 2469 } 2470 2471 func (s *egressServer) ProtocGenTwirpVersion() string { 2472 return "v8.1.3" 2473 } 2474 2475 // PathPrefix returns the base service path, in the form: "/<prefix>/<package>.<Service>/" 2476 // that is everything in a Twirp route except for the <Method>. This can be used for routing, 2477 // for example to identify the requests that are targeted to this service in a mux. 2478 func (s *egressServer) PathPrefix() string { 2479 return baseServicePath(s.pathPrefix, "livekit", "Egress") 2480 } 2481 2482 // ===== 2483 // Utils 2484 // ===== 2485 2486 // HTTPClient is the interface used by generated clients to send HTTP requests. 2487 // It is fulfilled by *(net/http).Client, which is sufficient for most users. 2488 // Users can provide their own implementation for special retry policies. 2489 // 2490 // HTTPClient implementations should not follow redirects. Redirects are 2491 // automatically disabled if *(net/http).Client is passed to client 2492 // constructors. See the withoutRedirects function in this file for more 2493 // details. 2494 type HTTPClient interface { 2495 Do(req *http.Request) (*http.Response, error) 2496 } 2497 2498 // TwirpServer is the interface generated server structs will support: they're 2499 // HTTP handlers with additional methods for accessing metadata about the 2500 // service. Those accessors are a low-level API for building reflection tools. 2501 // Most people can think of TwirpServers as just http.Handlers. 2502 type TwirpServer interface { 2503 http.Handler 2504 2505 // ServiceDescriptor returns gzipped bytes describing the .proto file that 2506 // this service was generated from. Once unzipped, the bytes can be 2507 // unmarshalled as a 2508 // google.golang.org/protobuf/types/descriptorpb.FileDescriptorProto. 2509 // 2510 // The returned integer is the index of this particular service within that 2511 // FileDescriptorProto's 'Service' slice of ServiceDescriptorProtos. This is a 2512 // low-level field, expected to be used for reflection. 2513 ServiceDescriptor() ([]byte, int) 2514 2515 // ProtocGenTwirpVersion is the semantic version string of the version of 2516 // twirp used to generate this file. 2517 ProtocGenTwirpVersion() string 2518 2519 // PathPrefix returns the HTTP URL path prefix for all methods handled by this 2520 // service. This can be used with an HTTP mux to route Twirp requests. 2521 // The path prefix is in the form: "/<prefix>/<package>.<Service>/" 2522 // that is, everything in a Twirp route except for the <Method> at the end. 2523 PathPrefix() string 2524 } 2525 2526 func newServerOpts(opts []interface{}) *twirp.ServerOptions { 2527 serverOpts := &twirp.ServerOptions{} 2528 for _, opt := range opts { 2529 switch o := opt.(type) { 2530 case twirp.ServerOption: 2531 o(serverOpts) 2532 case *twirp.ServerHooks: // backwards compatibility, allow to specify hooks as an argument 2533 twirp.WithServerHooks(o)(serverOpts) 2534 case nil: // backwards compatibility, allow nil value for the argument 2535 continue 2536 default: 2537 panic(fmt.Sprintf("Invalid option type %T, please use a twirp.ServerOption", o)) 2538 } 2539 } 2540 return serverOpts 2541 } 2542 2543 // WriteError writes an HTTP response with a valid Twirp error format (code, msg, meta). 2544 // Useful outside of the Twirp server (e.g. http middleware), but does not trigger hooks. 2545 // If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err) 2546 func WriteError(resp http.ResponseWriter, err error) { 2547 writeError(context.Background(), resp, err, nil) 2548 } 2549 2550 // writeError writes Twirp errors in the response and triggers hooks. 2551 func writeError(ctx context.Context, resp http.ResponseWriter, err error, hooks *twirp.ServerHooks) { 2552 // Convert to a twirp.Error. Non-twirp errors are converted to internal errors. 2553 var twerr twirp.Error 2554 if !errors.As(err, &twerr) { 2555 twerr = twirp.InternalErrorWith(err) 2556 } 2557 2558 statusCode := twirp.ServerHTTPStatusFromErrorCode(twerr.Code()) 2559 ctx = ctxsetters.WithStatusCode(ctx, statusCode) 2560 ctx = callError(ctx, hooks, twerr) 2561 2562 respBody := marshalErrorToJSON(twerr) 2563 2564 resp.Header().Set("Content-Type", "application/json") // Error responses are always JSON 2565 resp.Header().Set("Content-Length", strconv.Itoa(len(respBody))) 2566 resp.WriteHeader(statusCode) // set HTTP status code and send response 2567 2568 _, writeErr := resp.Write(respBody) 2569 if writeErr != nil { 2570 // We have three options here. We could log the error, call the Error 2571 // hook, or just silently ignore the error. 2572 // 2573 // Logging is unacceptable because we don't have a user-controlled 2574 // logger; writing out to stderr without permission is too rude. 2575 // 2576 // Calling the Error hook would confuse users: it would mean the Error 2577 // hook got called twice for one request, which is likely to lead to 2578 // duplicated log messages and metrics, no matter how well we document 2579 // the behavior. 2580 // 2581 // Silently ignoring the error is our least-bad option. It's highly 2582 // likely that the connection is broken and the original 'err' says 2583 // so anyway. 2584 _ = writeErr 2585 } 2586 2587 callResponseSent(ctx, hooks) 2588 } 2589 2590 // sanitizeBaseURL parses the the baseURL, and adds the "http" scheme if needed. 2591 // If the URL is unparsable, the baseURL is returned unchanged. 2592 func sanitizeBaseURL(baseURL string) string { 2593 u, err := url.Parse(baseURL) 2594 if err != nil { 2595 return baseURL // invalid URL will fail later when making requests 2596 } 2597 if u.Scheme == "" { 2598 u.Scheme = "http" 2599 } 2600 return u.String() 2601 } 2602 2603 // baseServicePath composes the path prefix for the service (without <Method>). 2604 // e.g.: baseServicePath("/twirp", "my.pkg", "MyService") 2605 // 2606 // returns => "/twirp/my.pkg.MyService/" 2607 // 2608 // e.g.: baseServicePath("", "", "MyService") 2609 // 2610 // returns => "/MyService/" 2611 func baseServicePath(prefix, pkg, service string) string { 2612 fullServiceName := service 2613 if pkg != "" { 2614 fullServiceName = pkg + "." + service 2615 } 2616 return path.Join("/", prefix, fullServiceName) + "/" 2617 } 2618 2619 // parseTwirpPath extracts path components form a valid Twirp route. 2620 // Expected format: "[<prefix>]/<package>.<Service>/<Method>" 2621 // e.g.: prefix, pkgService, method := parseTwirpPath("/twirp/pkg.Svc/MakeHat") 2622 func parseTwirpPath(path string) (string, string, string) { 2623 parts := strings.Split(path, "/") 2624 if len(parts) < 2 { 2625 return "", "", "" 2626 } 2627 method := parts[len(parts)-1] 2628 pkgService := parts[len(parts)-2] 2629 prefix := strings.Join(parts[0:len(parts)-2], "/") 2630 return prefix, pkgService, method 2631 } 2632 2633 // getCustomHTTPReqHeaders retrieves a copy of any headers that are set in 2634 // a context through the twirp.WithHTTPRequestHeaders function. 2635 // If there are no headers set, or if they have the wrong type, nil is returned. 2636 func getCustomHTTPReqHeaders(ctx context.Context) http.Header { 2637 header, ok := twirp.HTTPRequestHeaders(ctx) 2638 if !ok || header == nil { 2639 return nil 2640 } 2641 copied := make(http.Header) 2642 for k, vv := range header { 2643 if vv == nil { 2644 copied[k] = nil 2645 continue 2646 } 2647 copied[k] = make([]string, len(vv)) 2648 copy(copied[k], vv) 2649 } 2650 return copied 2651 } 2652 2653 // newRequest makes an http.Request from a client, adding common headers. 2654 func newRequest(ctx context.Context, url string, reqBody io.Reader, contentType string) (*http.Request, error) { 2655 req, err := http.NewRequest("POST", url, reqBody) 2656 if err != nil { 2657 return nil, err 2658 } 2659 req = req.WithContext(ctx) 2660 if customHeader := getCustomHTTPReqHeaders(ctx); customHeader != nil { 2661 req.Header = customHeader 2662 } 2663 req.Header.Set("Accept", contentType) 2664 req.Header.Set("Content-Type", contentType) 2665 req.Header.Set("Twirp-Version", "v8.1.3") 2666 return req, nil 2667 } 2668 2669 // JSON serialization for errors 2670 type twerrJSON struct { 2671 Code string `json:"code"` 2672 Msg string `json:"msg"` 2673 Meta map[string]string `json:"meta,omitempty"` 2674 } 2675 2676 // marshalErrorToJSON returns JSON from a twirp.Error, that can be used as HTTP error response body. 2677 // If serialization fails, it will use a descriptive Internal error instead. 2678 func marshalErrorToJSON(twerr twirp.Error) []byte { 2679 // make sure that msg is not too large 2680 msg := twerr.Msg() 2681 if len(msg) > 1e6 { 2682 msg = msg[:1e6] 2683 } 2684 2685 tj := twerrJSON{ 2686 Code: string(twerr.Code()), 2687 Msg: msg, 2688 Meta: twerr.MetaMap(), 2689 } 2690 2691 buf, err := json.Marshal(&tj) 2692 if err != nil { 2693 buf = []byte("{\"type\": \"" + twirp.Internal + "\", \"msg\": \"There was an error but it could not be serialized into JSON\"}") // fallback 2694 } 2695 2696 return buf 2697 } 2698 2699 // errorFromResponse builds a twirp.Error from a non-200 HTTP response. 2700 // If the response has a valid serialized Twirp error, then it's returned. 2701 // If not, the response status code is used to generate a similar twirp 2702 // error. See twirpErrorFromIntermediary for more info on intermediary errors. 2703 func errorFromResponse(resp *http.Response) twirp.Error { 2704 statusCode := resp.StatusCode 2705 statusText := http.StatusText(statusCode) 2706 2707 if isHTTPRedirect(statusCode) { 2708 // Unexpected redirect: it must be an error from an intermediary. 2709 // Twirp clients don't follow redirects automatically, Twirp only handles 2710 // POST requests, redirects should only happen on GET and HEAD requests. 2711 location := resp.Header.Get("Location") 2712 msg := fmt.Sprintf("unexpected HTTP status code %d %q received, Location=%q", statusCode, statusText, location) 2713 return twirpErrorFromIntermediary(statusCode, msg, location) 2714 } 2715 2716 respBodyBytes, err := io.ReadAll(resp.Body) 2717 if err != nil { 2718 return wrapInternal(err, "failed to read server error response body") 2719 } 2720 2721 var tj twerrJSON 2722 dec := json.NewDecoder(bytes.NewReader(respBodyBytes)) 2723 dec.DisallowUnknownFields() 2724 if err := dec.Decode(&tj); err != nil || tj.Code == "" { 2725 // Invalid JSON response; it must be an error from an intermediary. 2726 msg := fmt.Sprintf("Error from intermediary with HTTP status code %d %q", statusCode, statusText) 2727 return twirpErrorFromIntermediary(statusCode, msg, string(respBodyBytes)) 2728 } 2729 2730 errorCode := twirp.ErrorCode(tj.Code) 2731 if !twirp.IsValidErrorCode(errorCode) { 2732 msg := "invalid type returned from server error response: " + tj.Code 2733 return twirp.InternalError(msg).WithMeta("body", string(respBodyBytes)) 2734 } 2735 2736 twerr := twirp.NewError(errorCode, tj.Msg) 2737 for k, v := range tj.Meta { 2738 twerr = twerr.WithMeta(k, v) 2739 } 2740 return twerr 2741 } 2742 2743 // twirpErrorFromIntermediary maps HTTP errors from non-twirp sources to twirp errors. 2744 // The mapping is similar to gRPC: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md. 2745 // Returned twirp Errors have some additional metadata for inspection. 2746 func twirpErrorFromIntermediary(status int, msg string, bodyOrLocation string) twirp.Error { 2747 var code twirp.ErrorCode 2748 if isHTTPRedirect(status) { // 3xx 2749 code = twirp.Internal 2750 } else { 2751 switch status { 2752 case 400: // Bad Request 2753 code = twirp.Internal 2754 case 401: // Unauthorized 2755 code = twirp.Unauthenticated 2756 case 403: // Forbidden 2757 code = twirp.PermissionDenied 2758 case 404: // Not Found 2759 code = twirp.BadRoute 2760 case 429: // Too Many Requests 2761 code = twirp.ResourceExhausted 2762 case 502, 503, 504: // Bad Gateway, Service Unavailable, Gateway Timeout 2763 code = twirp.Unavailable 2764 default: // All other codes 2765 code = twirp.Unknown 2766 } 2767 } 2768 2769 twerr := twirp.NewError(code, msg) 2770 twerr = twerr.WithMeta("http_error_from_intermediary", "true") // to easily know if this error was from intermediary 2771 twerr = twerr.WithMeta("status_code", strconv.Itoa(status)) 2772 if isHTTPRedirect(status) { 2773 twerr = twerr.WithMeta("location", bodyOrLocation) 2774 } else { 2775 twerr = twerr.WithMeta("body", bodyOrLocation) 2776 } 2777 return twerr 2778 } 2779 2780 func isHTTPRedirect(status int) bool { 2781 return status >= 300 && status <= 399 2782 } 2783 2784 // wrapInternal wraps an error with a prefix as an Internal error. 2785 // The original error cause is accessible by github.com/pkg/errors.Cause. 2786 func wrapInternal(err error, prefix string) twirp.Error { 2787 return twirp.InternalErrorWith(&wrappedError{prefix: prefix, cause: err}) 2788 } 2789 2790 type wrappedError struct { 2791 prefix string 2792 cause error 2793 } 2794 2795 func (e *wrappedError) Error() string { return e.prefix + ": " + e.cause.Error() } 2796 func (e *wrappedError) Unwrap() error { return e.cause } // for go1.13 + errors.Is/As 2797 func (e *wrappedError) Cause() error { return e.cause } // for github.com/pkg/errors 2798 2799 // ensurePanicResponses makes sure that rpc methods causing a panic still result in a Twirp Internal 2800 // error response (status 500), and error hooks are properly called with the panic wrapped as an error. 2801 // The panic is re-raised so it can be handled normally with middleware. 2802 func ensurePanicResponses(ctx context.Context, resp http.ResponseWriter, hooks *twirp.ServerHooks) { 2803 if r := recover(); r != nil { 2804 // Wrap the panic as an error so it can be passed to error hooks. 2805 // The original error is accessible from error hooks, but not visible in the response. 2806 err := errFromPanic(r) 2807 twerr := &internalWithCause{msg: "Internal service panic", cause: err} 2808 // Actually write the error 2809 writeError(ctx, resp, twerr, hooks) 2810 // If possible, flush the error to the wire. 2811 f, ok := resp.(http.Flusher) 2812 if ok { 2813 f.Flush() 2814 } 2815 2816 panic(r) 2817 } 2818 } 2819 2820 // errFromPanic returns the typed error if the recovered panic is an error, otherwise formats as error. 2821 func errFromPanic(p interface{}) error { 2822 if err, ok := p.(error); ok { 2823 return err 2824 } 2825 return fmt.Errorf("panic: %v", p) 2826 } 2827 2828 // internalWithCause is a Twirp Internal error wrapping an original error cause, 2829 // but the original error message is not exposed on Msg(). The original error 2830 // can be checked with go1.13+ errors.Is/As, and also by (github.com/pkg/errors).Unwrap 2831 type internalWithCause struct { 2832 msg string 2833 cause error 2834 } 2835 2836 func (e *internalWithCause) Unwrap() error { return e.cause } // for go1.13 + errors.Is/As 2837 func (e *internalWithCause) Cause() error { return e.cause } // for github.com/pkg/errors 2838 func (e *internalWithCause) Error() string { return e.msg + ": " + e.cause.Error() } 2839 func (e *internalWithCause) Code() twirp.ErrorCode { return twirp.Internal } 2840 func (e *internalWithCause) Msg() string { return e.msg } 2841 func (e *internalWithCause) Meta(key string) string { return "" } 2842 func (e *internalWithCause) MetaMap() map[string]string { return nil } 2843 func (e *internalWithCause) WithMeta(key string, val string) twirp.Error { return e } 2844 2845 // malformedRequestError is used when the twirp server cannot unmarshal a request 2846 func malformedRequestError(msg string) twirp.Error { 2847 return twirp.NewError(twirp.Malformed, msg) 2848 } 2849 2850 // badRouteError is used when the twirp server cannot route a request 2851 func badRouteError(msg string, method, url string) twirp.Error { 2852 err := twirp.NewError(twirp.BadRoute, msg) 2853 err = err.WithMeta("twirp_invalid_route", method+" "+url) 2854 return err 2855 } 2856 2857 // withoutRedirects makes sure that the POST request can not be redirected. 2858 // The standard library will, by default, redirect requests (including POSTs) if it gets a 302 or 2859 // 303 response, and also 301s in go1.8. It redirects by making a second request, changing the 2860 // method to GET and removing the body. This produces very confusing error messages, so instead we 2861 // set a redirect policy that always errors. This stops Go from executing the redirect. 2862 // 2863 // We have to be a little careful in case the user-provided http.Client has its own CheckRedirect 2864 // policy - if so, we'll run through that policy first. 2865 // 2866 // Because this requires modifying the http.Client, we make a new copy of the client and return it. 2867 func withoutRedirects(in *http.Client) *http.Client { 2868 copy := *in 2869 copy.CheckRedirect = func(req *http.Request, via []*http.Request) error { 2870 if in.CheckRedirect != nil { 2871 // Run the input's redirect if it exists, in case it has side effects, but ignore any error it 2872 // returns, since we want to use ErrUseLastResponse. 2873 err := in.CheckRedirect(req, via) 2874 _ = err // Silly, but this makes sure generated code passes errcheck -blank, which some people use. 2875 } 2876 return http.ErrUseLastResponse 2877 } 2878 return © 2879 } 2880 2881 // doProtobufRequest makes a Protobuf request to the remote Twirp service. 2882 func doProtobufRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) { 2883 reqBodyBytes, err := proto.Marshal(in) 2884 if err != nil { 2885 return ctx, wrapInternal(err, "failed to marshal proto request") 2886 } 2887 reqBody := bytes.NewBuffer(reqBodyBytes) 2888 if err = ctx.Err(); err != nil { 2889 return ctx, wrapInternal(err, "aborted because context was done") 2890 } 2891 2892 req, err := newRequest(ctx, url, reqBody, "application/protobuf") 2893 if err != nil { 2894 return ctx, wrapInternal(err, "could not build request") 2895 } 2896 ctx, err = callClientRequestPrepared(ctx, hooks, req) 2897 if err != nil { 2898 return ctx, err 2899 } 2900 2901 req = req.WithContext(ctx) 2902 resp, err := client.Do(req) 2903 if err != nil { 2904 return ctx, wrapInternal(err, "failed to do request") 2905 } 2906 defer func() { _ = resp.Body.Close() }() 2907 2908 if err = ctx.Err(); err != nil { 2909 return ctx, wrapInternal(err, "aborted because context was done") 2910 } 2911 2912 if resp.StatusCode != 200 { 2913 return ctx, errorFromResponse(resp) 2914 } 2915 2916 respBodyBytes, err := io.ReadAll(resp.Body) 2917 if err != nil { 2918 return ctx, wrapInternal(err, "failed to read response body") 2919 } 2920 if err = ctx.Err(); err != nil { 2921 return ctx, wrapInternal(err, "aborted because context was done") 2922 } 2923 2924 if err = proto.Unmarshal(respBodyBytes, out); err != nil { 2925 return ctx, wrapInternal(err, "failed to unmarshal proto response") 2926 } 2927 return ctx, nil 2928 } 2929 2930 // doJSONRequest makes a JSON request to the remote Twirp service. 2931 func doJSONRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) { 2932 marshaler := &protojson.MarshalOptions{UseProtoNames: true} 2933 reqBytes, err := marshaler.Marshal(in) 2934 if err != nil { 2935 return ctx, wrapInternal(err, "failed to marshal json request") 2936 } 2937 if err = ctx.Err(); err != nil { 2938 return ctx, wrapInternal(err, "aborted because context was done") 2939 } 2940 2941 req, err := newRequest(ctx, url, bytes.NewReader(reqBytes), "application/json") 2942 if err != nil { 2943 return ctx, wrapInternal(err, "could not build request") 2944 } 2945 ctx, err = callClientRequestPrepared(ctx, hooks, req) 2946 if err != nil { 2947 return ctx, err 2948 } 2949 2950 req = req.WithContext(ctx) 2951 resp, err := client.Do(req) 2952 if err != nil { 2953 return ctx, wrapInternal(err, "failed to do request") 2954 } 2955 2956 defer func() { 2957 cerr := resp.Body.Close() 2958 if err == nil && cerr != nil { 2959 err = wrapInternal(cerr, "failed to close response body") 2960 } 2961 }() 2962 2963 if err = ctx.Err(); err != nil { 2964 return ctx, wrapInternal(err, "aborted because context was done") 2965 } 2966 2967 if resp.StatusCode != 200 { 2968 return ctx, errorFromResponse(resp) 2969 } 2970 2971 d := json.NewDecoder(resp.Body) 2972 rawRespBody := json.RawMessage{} 2973 if err := d.Decode(&rawRespBody); err != nil { 2974 return ctx, wrapInternal(err, "failed to unmarshal json response") 2975 } 2976 unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 2977 if err = unmarshaler.Unmarshal(rawRespBody, out); err != nil { 2978 return ctx, wrapInternal(err, "failed to unmarshal json response") 2979 } 2980 if err = ctx.Err(); err != nil { 2981 return ctx, wrapInternal(err, "aborted because context was done") 2982 } 2983 return ctx, nil 2984 } 2985 2986 // Call twirp.ServerHooks.RequestReceived if the hook is available 2987 func callRequestReceived(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) { 2988 if h == nil || h.RequestReceived == nil { 2989 return ctx, nil 2990 } 2991 return h.RequestReceived(ctx) 2992 } 2993 2994 // Call twirp.ServerHooks.RequestRouted if the hook is available 2995 func callRequestRouted(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) { 2996 if h == nil || h.RequestRouted == nil { 2997 return ctx, nil 2998 } 2999 return h.RequestRouted(ctx) 3000 } 3001 3002 // Call twirp.ServerHooks.ResponsePrepared if the hook is available 3003 func callResponsePrepared(ctx context.Context, h *twirp.ServerHooks) context.Context { 3004 if h == nil || h.ResponsePrepared == nil { 3005 return ctx 3006 } 3007 return h.ResponsePrepared(ctx) 3008 } 3009 3010 // Call twirp.ServerHooks.ResponseSent if the hook is available 3011 func callResponseSent(ctx context.Context, h *twirp.ServerHooks) { 3012 if h == nil || h.ResponseSent == nil { 3013 return 3014 } 3015 h.ResponseSent(ctx) 3016 } 3017 3018 // Call twirp.ServerHooks.Error if the hook is available 3019 func callError(ctx context.Context, h *twirp.ServerHooks, err twirp.Error) context.Context { 3020 if h == nil || h.Error == nil { 3021 return ctx 3022 } 3023 return h.Error(ctx, err) 3024 } 3025 3026 func callClientResponseReceived(ctx context.Context, h *twirp.ClientHooks) { 3027 if h == nil || h.ResponseReceived == nil { 3028 return 3029 } 3030 h.ResponseReceived(ctx) 3031 } 3032 3033 func callClientRequestPrepared(ctx context.Context, h *twirp.ClientHooks, req *http.Request) (context.Context, error) { 3034 if h == nil || h.RequestPrepared == nil { 3035 return ctx, nil 3036 } 3037 return h.RequestPrepared(ctx, req) 3038 } 3039 3040 func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error) { 3041 if h == nil || h.Error == nil { 3042 return 3043 } 3044 h.Error(ctx, err) 3045 } 3046 3047 var twirpFileDescriptor0 = []byte{ 3048 // 2419 bytes of a gzipped FileDescriptorProto 3049 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xcd, 0x73, 0x23, 0x47, 3050 0x15, 0xf7, 0xe8, 0x5b, 0xcf, 0x92, 0x3c, 0xee, 0xdd, 0x4d, 0xb4, 0xde, 0x90, 0x18, 0x6d, 0x3e, 3051 0x9c, 0x0d, 0xf1, 0x1a, 0x7b, 0xe3, 0x04, 0x87, 0x0d, 0xc8, 0xf6, 0xd8, 0x16, 0x91, 0x2d, 0x55, 3052 0x4b, 0xde, 0x00, 0x97, 0xa9, 0xf1, 0x4c, 0xdb, 0x9e, 0xf2, 0x68, 0x46, 0xcc, 0xb4, 0xbc, 0x28, 3053 0xc5, 0x81, 0x23, 0x57, 0x8a, 0x3f, 0x80, 0x3b, 0x05, 0xfc, 0x17, 0x5c, 0xc8, 0x81, 0x2b, 0x57, 3054 0xae, 0x1c, 0xe0, 0xc6, 0x89, 0x03, 0xd5, 0x1f, 0xf3, 0xa1, 0x91, 0x6c, 0xec, 0x75, 0xaa, 0xa0, 3055 0x28, 0x6e, 0xd3, 0xef, 0x6b, 0x5e, 0xbf, 0xfe, 0xbd, 0xd7, 0xef, 0x35, 0xdc, 0x77, 0xec, 0x4b, 3056 0x72, 0x61, 0x53, 0x9d, 0x9c, 0xf9, 0x24, 0x08, 0x56, 0x87, 0xbe, 0x47, 0x3d, 0x54, 0x94, 0xd4, 3057 0xa5, 0x88, 0x3d, 0xf0, 0x2c, 0xe2, 0x48, 0x76, 0xe3, 0x77, 0x79, 0x58, 0xc2, 0x9e, 0x37, 0xd8, 3058 0xf1, 0x06, 0x43, 0x2f, 0xb0, 0x29, 0xd1, 0xb8, 0x32, 0x26, 0x3f, 0x19, 0x91, 0x80, 0xa2, 0x47, 3059 0x50, 0xf6, 0x3d, 0x6f, 0xa0, 0xbb, 0xc6, 0x80, 0xd4, 0x95, 0x65, 0x65, 0xa5, 0x8c, 0x4b, 0x8c, 3060 0x70, 0x64, 0x0c, 0x08, 0x7a, 0x0d, 0x0a, 0x8e, 0x31, 0xf6, 0x46, 0xb4, 0x9e, 0xe1, 0x1c, 0xb9, 3061 0x42, 0xdf, 0x00, 0x30, 0x46, 0x96, 0xed, 0xe9, 0x9e, 0xeb, 0x8c, 0xeb, 0xd9, 0x65, 0x65, 0xa5, 3062 0x84, 0xcb, 0x9c, 0xd2, 0x71, 0x9d, 0x31, 0x63, 0x5f, 0xda, 0x16, 0x91, 0xec, 0x9c, 0x60, 0x73, 3063 0x0a, 0x67, 0xbf, 0x0b, 0x0b, 0xe6, 0x28, 0xa0, 0xde, 0x40, 0x3f, 0x31, 0x02, 0xa2, 0x8f, 0x7c, 3064 0xa7, 0x9e, 0xe7, 0xe6, 0xab, 0x82, 0xbc, 0x6d, 0x04, 0xe4, 0xd8, 0x77, 0xd0, 0x33, 0xc8, 0x9d, 3065 0xda, 0x0e, 0xa9, 0x17, 0x96, 0x95, 0x95, 0xf9, 0xf5, 0xa5, 0x55, 0xb9, 0xbd, 0x55, 0xcd, 0x35, 3066 0x3d, 0x8b, 0x58, 0x7b, 0xb6, 0x43, 0x3a, 0x23, 0x3a, 0x1c, 0xd1, 0xed, 0x4c, 0x5d, 0x39, 0x98, 3067 0xc3, 0x5c, 0x1a, 0x6d, 0x40, 0x21, 0xa0, 0x3e, 0x31, 0x06, 0xf5, 0x22, 0xd7, 0x7b, 0x10, 0xe9, 3068 0xf5, 0x38, 0x79, 0x42, 0x45, 0x8a, 0xa2, 0xcf, 0xa0, 0x14, 0x90, 0xb3, 0x01, 0x71, 0x69, 0x50, 3069 0x07, 0xae, 0xf6, 0x46, 0xac, 0x26, 0x18, 0x33, 0x7e, 0x18, 0xe9, 0xa0, 0x4f, 0xa0, 0x30, 0xf4, 3070 0x49, 0x40, 0x68, 0xbd, 0xb4, 0xac, 0xac, 0xd4, 0xd6, 0xdf, 0x9c, 0x74, 0xd6, 0x76, 0xcf, 0x3a, 3071 0x43, 0x6a, 0x7b, 0x6e, 0xd0, 0xe5, 0x52, 0x07, 0x0a, 0x96, 0xf2, 0x68, 0x13, 0x4a, 0x86, 0x75, 3072 0x69, 0xb8, 0x26, 0xb1, 0xea, 0x65, 0xfe, 0xe7, 0xfa, 0x55, 0xba, 0x07, 0x0a, 0x8e, 0x64, 0xd1, 3073 0x73, 0xa8, 0xb0, 0xed, 0xea, 0x1e, 0x77, 0x28, 0xa8, 0xcf, 0x2f, 0x67, 0xaf, 0x0f, 0x12, 0x9e, 3074 0x3f, 0x8d, 0xbe, 0x03, 0xf4, 0x5d, 0xa8, 0x89, 0xad, 0x47, 0x06, 0x2a, 0xdc, 0xc0, 0xec, 0x68, 3075 0xe1, 0x6a, 0x90, 0x58, 0x05, 0x48, 0x83, 0x05, 0xb9, 0xf5, 0x48, 0xbd, 0xca, 0xd5, 0xaf, 0x8d, 3076 0x1a, 0xae, 0x49, 0x25, 0x69, 0x66, 0xbb, 0x04, 0x05, 0xa1, 0xbe, 0x5d, 0x86, 0xa2, 0x27, 0x36, 3077 0xd9, 0xf8, 0x73, 0x0e, 0xd4, 0x2f, 0xc8, 0xc9, 0x24, 0x4a, 0x55, 0xc8, 0x32, 0x98, 0x08, 0x7c, 3078 0xb2, 0xcf, 0x14, 0x04, 0x33, 0xd7, 0x43, 0x30, 0x9b, 0x86, 0x60, 0x08, 0xad, 0xdc, 0x2b, 0x42, 3079 0x2b, 0xff, 0x6a, 0xd0, 0x2a, 0xdc, 0x09, 0x5a, 0xc5, 0x3b, 0x40, 0xab, 0x74, 0x07, 0x68, 0x95, 3080 0xef, 0x0a, 0x2d, 0xb8, 0x1b, 0xb4, 0xe6, 0xbf, 0x2e, 0x68, 0xfd, 0x33, 0x07, 0x8f, 0xfa, 0xbe, 3081 0x61, 0x5e, 0xbc, 0x4a, 0x2d, 0x7c, 0x1b, 0x6a, 0x02, 0x70, 0x94, 0x59, 0xd0, 0x6d, 0x4b, 0xd6, 3082 0xc4, 0x0a, 0xa7, 0x72, 0xb3, 0x2d, 0x8b, 0x49, 0x09, 0xdc, 0x45, 0x52, 0x59, 0x21, 0xc5, 0xa9, 3083 0xa1, 0xd4, 0x7f, 0x08, 0x7e, 0xa5, 0x3b, 0xc1, 0xaf, 0x70, 0x07, 0xf8, 0x15, 0xff, 0x5f, 0xd9, 3084 0x82, 0xc6, 0xef, 0x15, 0x40, 0x1c, 0x01, 0xb7, 0x40, 0xdd, 0x43, 0x28, 0xa5, 0xf0, 0x56, 0xa4, 3085 0x12, 0x44, 0x4f, 0x25, 0x88, 0xb2, 0x3c, 0xb6, 0x0f, 0x23, 0xff, 0x76, 0x6d, 0x9f, 0x98, 0x34, 3086 0x76, 0x2e, 0xc2, 0xcf, 0x3b, 0x50, 0x7d, 0x49, 0x4e, 0x02, 0xcf, 0xbc, 0x20, 0x94, 0xdf, 0xba, 3087 0x0c, 0x7e, 0xe5, 0x83, 0x39, 0x5c, 0x89, 0xc8, 0xc7, 0xbe, 0x13, 0xfb, 0xde, 0xf8, 0x2a, 0x03, 3088 0x8b, 0x53, 0xd1, 0x46, 0x1f, 0x41, 0x99, 0x9f, 0x0f, 0x1d, 0x0f, 0x85, 0xbf, 0xb5, 0xf4, 0xc1, 3089 0x0a, 0xf1, 0xfe, 0x78, 0x48, 0x70, 0xe9, 0x54, 0x7e, 0xa1, 0x25, 0xe0, 0xdf, 0x43, 0x83, 0x9e, 3090 0xcb, 0x9d, 0x44, 0x6b, 0xf4, 0x3e, 0xa8, 0x96, 0x1d, 0x18, 0x27, 0x0e, 0xd1, 0x07, 0x86, 0x6b, 3091 0x9f, 0x92, 0x40, 0xc0, 0xad, 0x84, 0x17, 0x24, 0xfd, 0x50, 0x92, 0xd1, 0x63, 0xc8, 0x04, 0x1b, 3092 0x72, 0xcf, 0x8b, 0xf1, 0x99, 0x6c, 0x1c, 0x0f, 0x1d, 0xcf, 0xb0, 0x0e, 0xe6, 0x70, 0x26, 0xd8, 3093 0x40, 0xef, 0x42, 0xf6, 0xcc, 0x1c, 0xca, 0xf4, 0x42, 0x91, 0xd4, 0xfe, 0x4e, 0x37, 0x12, 0x63, 3094 0x02, 0x68, 0x0d, 0xf2, 0xc6, 0x97, 0x23, 0x9f, 0xc8, 0x84, 0x8a, 0xb7, 0xd1, 0x64, 0xd4, 0x6d, 3095 0xc7, 0x3b, 0x89, 0xe4, 0x85, 0x20, 0x7a, 0x0a, 0x05, 0xc3, 0xb1, 0x3b, 0xbd, 0xde, 0x54, 0x77, 3096 0xd1, 0xe4, 0xe4, 0x48, 0x5e, 0x8a, 0x25, 0xa2, 0xf9, 0x8f, 0x2c, 0xdc, 0x9b, 0x81, 0x1d, 0xb4, 3097 0x05, 0x25, 0xde, 0xa9, 0x99, 0x9e, 0x23, 0xc3, 0xf9, 0xe6, 0x6c, 0xac, 0x75, 0xa5, 0x14, 0x8e, 3098 0xe4, 0xd1, 0x7b, 0xb0, 0xc0, 0x82, 0xc8, 0xa0, 0xa3, 0x0f, 0x7d, 0x72, 0x6a, 0xff, 0x54, 0xc6, 3099 0xb6, 0x16, 0x92, 0xbb, 0x9c, 0x8a, 0x1e, 0x43, 0x75, 0xe8, 0x18, 0x63, 0xc7, 0x0e, 0xa8, 0x00, 3100 0x9a, 0x2c, 0x4b, 0x21, 0x91, 0x83, 0xed, 0x7d, 0x50, 0x43, 0xf0, 0x5b, 0x23, 0xdf, 0x60, 0xa8, 3101 0xe5, 0x31, 0xac, 0xe2, 0x30, 0x29, 0x76, 0x25, 0x99, 0xe5, 0x49, 0xf4, 0xe3, 0x60, 0x74, 0xca, 3102 0x7e, 0x0c, 0xdc, 0xf7, 0x2b, 0xf2, 0xa4, 0xc7, 0x65, 0x62, 0xb7, 0xc4, 0x7a, 0xe6, 0xc1, 0x97, 3103 0xae, 0x3b, 0xf8, 0xfc, 0x8d, 0x0e, 0xbe, 0x70, 0xe3, 0x83, 0x2f, 0xde, 0xfe, 0xe0, 0xcb, 0xb7, 3104 0x3d, 0xf8, 0x5f, 0x65, 0x40, 0x4d, 0x27, 0xe5, 0x44, 0x3a, 0x28, 0x37, 0x48, 0x87, 0xfc, 0x75, 3105 0x51, 0xc9, 0xdc, 0x28, 0x2a, 0xd9, 0x1b, 0x47, 0x25, 0x77, 0xfb, 0xa8, 0x14, 0x6e, 0x1b, 0x95, 3106 0xaf, 0x32, 0x50, 0x0a, 0xfd, 0xe4, 0xdd, 0x9c, 0x69, 0x92, 0x20, 0xd0, 0x2f, 0xc8, 0x58, 0xc6, 3107 0xa3, 0x2c, 0x28, 0x9f, 0x93, 0x31, 0x9b, 0x43, 0x02, 0x62, 0xfa, 0x24, 0x9a, 0x43, 0xc4, 0x8a, 3108 0xd1, 0x7d, 0x72, 0xc6, 0x60, 0x2a, 0xe0, 0x2c, 0x57, 0x2c, 0xb8, 0xc4, 0xb5, 0x86, 0x9e, 0xed, 3109 0x52, 0x51, 0xe4, 0x70, 0xb4, 0x66, 0x3a, 0x27, 0x23, 0x56, 0xeb, 0xe4, 0xd0, 0x21, 0x57, 0x68, 3110 0x05, 0xd4, 0x53, 0xcf, 0x37, 0x89, 0xce, 0x8e, 0x40, 0x0f, 0xe8, 0x58, 0x4e, 0x1e, 0x25, 0x5c, 3111 0xe3, 0xf4, 0xae, 0x41, 0xcf, 0x7b, 0x8c, 0x8a, 0x3e, 0x85, 0xd2, 0x80, 0x50, 0xc3, 0x32, 0xa8, 3112 0x51, 0x2f, 0xf2, 0xcb, 0xe1, 0xad, 0xa9, 0xc8, 0xaf, 0x1e, 0x4a, 0x09, 0xcd, 0xa5, 0xfe, 0x18, 3113 0x47, 0x0a, 0xa8, 0x0e, 0x45, 0x6a, 0x9c, 0x9d, 0xd9, 0xee, 0x19, 0x07, 0x3a, 0xab, 0xe7, 0x62, 3114 0xb9, 0xf4, 0x29, 0x54, 0x27, 0x94, 0x58, 0xd3, 0x1b, 0x47, 0x83, 0x7d, 0xa2, 0xfb, 0x90, 0xbf, 3115 0x34, 0x9c, 0x11, 0x91, 0x61, 0x10, 0x8b, 0xad, 0xcc, 0x27, 0x4a, 0x43, 0x83, 0x72, 0x74, 0x9c, 3116 0x68, 0x19, 0xe6, 0x4d, 0x9f, 0x58, 0xc4, 0xa5, 0xb6, 0xe1, 0x04, 0xd2, 0x40, 0x92, 0x94, 0x08, 3117 0x42, 0x26, 0x19, 0x84, 0xc6, 0xcf, 0x60, 0x21, 0x75, 0xd6, 0xe8, 0x9b, 0x50, 0x31, 0x4c, 0xd3, 3118 0x1b, 0xb9, 0x34, 0x79, 0x43, 0xcd, 0x4b, 0x1a, 0xaf, 0x1b, 0x6f, 0x41, 0xb8, 0xe4, 0xc7, 0x27, 3119 0x4c, 0x82, 0x24, 0xb1, 0xf3, 0x7b, 0x07, 0x6a, 0xa6, 0xe7, 0x52, 0xc3, 0x76, 0x89, 0x9f, 0x2c, 3120 0x3f, 0xd5, 0x88, 0xca, 0xec, 0x34, 0x7e, 0xa9, 0x40, 0x25, 0x89, 0x9b, 0xff, 0x02, 0x58, 0x34, 3121 0xbe, 0x80, 0x4a, 0xb2, 0x5f, 0x40, 0x1b, 0x53, 0xd5, 0xfa, 0xf5, 0x54, 0x63, 0x31, 0xa3, 0x4c, 3122 0x23, 0xc8, 0x8d, 0x7c, 0x27, 0xa8, 0x67, 0x96, 0xb3, 0x2b, 0x65, 0xcc, 0xbf, 0x1b, 0x3f, 0xcf, 3123 0xc2, 0x42, 0xaa, 0x0d, 0x62, 0xe7, 0xfb, 0xd2, 0xb6, 0x64, 0x45, 0xc8, 0x63, 0xb1, 0x60, 0xae, 3124 0x9d, 0x13, 0xfb, 0xec, 0x5c, 0x6c, 0x33, 0x8f, 0xe5, 0x8a, 0x49, 0x5b, 0x64, 0x48, 0xcf, 0xf9, 3125 0x2e, 0xf3, 0x58, 0x2c, 0xd0, 0x1b, 0x50, 0x3e, 0xf5, 0x8d, 0x01, 0xf1, 0x0d, 0x2a, 0x12, 0x39, 3126 0x8f, 0x63, 0x02, 0x7a, 0x06, 0xf3, 0xa2, 0x8b, 0x65, 0xd7, 0xb4, 0xc9, 0xf7, 0x5a, 0x5b, 0xbf, 3127 0x17, 0x67, 0x2d, 0xe3, 0xed, 0x30, 0x16, 0x16, 0xe3, 0x15, 0xff, 0x66, 0xb7, 0x87, 0xd0, 0x3a, 3128 0xb1, 0x29, 0xb7, 0x5b, 0xe0, 0x76, 0x45, 0xeb, 0xbb, 0x2d, 0x68, 0xec, 0x2e, 0x12, 0x42, 0xa7, 3129 0x3e, 0xeb, 0x6c, 0x5c, 0x73, 0xcc, 0xab, 0x6b, 0x1e, 0x8b, 0xbe, 0x79, 0x2f, 0xa4, 0x32, 0x1f, 3130 0x44, 0x8f, 0x2c, 0x7c, 0x28, 0xa5, 0x7c, 0x78, 0xc1, 0x78, 0xd2, 0x87, 0xcb, 0xe8, 0x9b, 0xf9, 3131 0x20, 0xb4, 0x42, 0x1f, 0xca, 0xc2, 0x07, 0x4e, 0x0c, 0x7d, 0xf8, 0x16, 0xa0, 0x0b, 0x32, 0xd6, 3132 0xf9, 0x7e, 0x75, 0xdb, 0xa5, 0xc4, 0xbf, 0x34, 0x1c, 0x7e, 0x33, 0x29, 0x58, 0xbd, 0x20, 0xe3, 3133 0x3d, 0xc6, 0x68, 0x49, 0x7a, 0xe3, 0x07, 0x70, 0xef, 0x78, 0x68, 0x19, 0x94, 0xb4, 0xf9, 0xb3, 3134 0x46, 0xa2, 0x21, 0x13, 0x0f, 0x2c, 0xac, 0xe9, 0x92, 0xb5, 0x59, 0x10, 0x5a, 0xd6, 0x55, 0x4f, 3135 0x22, 0x8d, 0x5f, 0x28, 0xa1, 0x31, 0x81, 0x82, 0x1b, 0x19, 0x7b, 0x17, 0x16, 0x0c, 0xcb, 0x92, 3136 0x9d, 0xa6, 0x9e, 0x80, 0x48, 0xd5, 0xb0, 0x2c, 0x01, 0xb8, 0x63, 0xdf, 0x09, 0xd8, 0xb6, 0x7c, 3137 0x32, 0xf0, 0x2e, 0xc9, 0x84, 0x68, 0x96, 0x8b, 0xaa, 0x82, 0x13, 0x4b, 0x37, 0x08, 0x2c, 0xb6, 3138 0xed, 0x80, 0xde, 0xa2, 0xcb, 0x9c, 0x70, 0x32, 0x33, 0xbd, 0x63, 0xc3, 0xa4, 0xf6, 0x25, 0x91, 3139 0x63, 0xb4, 0x5c, 0x35, 0xbe, 0x07, 0x28, 0xf9, 0x9b, 0x60, 0xe8, 0xb9, 0x01, 0xeb, 0x21, 0xf2, 3140 0x36, 0x25, 0x03, 0x56, 0x75, 0x58, 0x65, 0x8c, 0x8f, 0x55, 0xc8, 0xb5, 0xdc, 0x53, 0x0f, 0x0b, 3141 0x89, 0xc6, 0x1a, 0x2c, 0xf6, 0xa8, 0x37, 0x9c, 0xf2, 0xf3, 0xca, 0x78, 0x35, 0xfe, 0x50, 0x00, 3142 0x88, 0xed, 0x5c, 0x1f, 0xdb, 0xd7, 0xa1, 0xc8, 0x37, 0x1c, 0xed, 0xa8, 0xc0, 0x96, 0x2d, 0x6b, 3143 0x32, 0x12, 0xd5, 0x54, 0x24, 0x3e, 0x64, 0x33, 0x96, 0x41, 0x47, 0x01, 0xdf, 0x6c, 0x2d, 0x71, 3144 0xa1, 0x89, 0xff, 0xf6, 0x38, 0x13, 0x4b, 0x21, 0x56, 0xa0, 0x02, 0x6a, 0xf8, 0x94, 0x58, 0xba, 3145 0x41, 0x39, 0xce, 0xb2, 0xb8, 0x2c, 0x29, 0x4d, 0xca, 0xba, 0x77, 0xe2, 0x5a, 0x82, 0x39, 0xcf, 3146 0x99, 0x45, 0xbe, 0x6e, 0xf2, 0xe4, 0x25, 0xbe, 0xef, 0xf9, 0x1c, 0xc6, 0x65, 0x2c, 0x16, 0xa8, 3147 0x0d, 0x35, 0xee, 0x9b, 0x19, 0x0e, 0xa8, 0xf2, 0x2a, 0x7e, 0x1c, 0xb9, 0x71, 0xf5, 0x53, 0xde, 3148 0xc1, 0x1c, 0xae, 0xfa, 0x49, 0x2e, 0xea, 0xc0, 0x82, 0x18, 0x1e, 0x62, 0x73, 0xa2, 0x7f, 0x7a, 3149 0x3b, 0x32, 0x77, 0xcd, 0x38, 0x7c, 0x30, 0x87, 0x6b, 0x74, 0x82, 0x8d, 0x36, 0x20, 0xcf, 0x29, 3150 0xf2, 0xb6, 0x7f, 0x34, 0x69, 0x26, 0xad, 0x2d, 0x64, 0xd1, 0x87, 0x90, 0x7d, 0x49, 0x4e, 0xea, 3151 0xb5, 0xd4, 0x98, 0x92, 0x7e, 0xe3, 0x61, 0x4d, 0xc8, 0x4b, 0x72, 0x82, 0x3e, 0x4a, 0xbd, 0xdf, 3152 0xa5, 0xcb, 0x2b, 0x3b, 0x79, 0x86, 0x3b, 0x3e, 0xa9, 0x2a, 0xd1, 0x9c, 0xfb, 0x81, 0x9c, 0x86, 3153 0x4a, 0xa9, 0x56, 0x88, 0xb5, 0x5c, 0x4c, 0x45, 0x8a, 0x8b, 0x49, 0xe8, 0xe3, 0xc4, 0x50, 0x5c, 3154 0x49, 0xcf, 0xd2, 0x92, 0x91, 0x50, 0x8a, 0xa7, 0xe1, 0xad, 0x68, 0xb8, 0xf4, 0x49, 0x30, 0x72, 3155 0x68, 0x50, 0x5f, 0x48, 0xc1, 0x3c, 0x76, 0x32, 0x1c, 0x2d, 0xb1, 0x90, 0x44, 0xcf, 0xe4, 0x5c, 3156 0x1b, 0x6a, 0xaa, 0x5c, 0x73, 0xda, 0x53, 0x31, 0xce, 0x86, 0x5a, 0x9f, 0xc5, 0x03, 0x69, 0xa8, 3157 0xb8, 0x98, 0x9e, 0x67, 0x13, 0x1e, 0x47, 0x93, 0xa8, 0xd4, 0x67, 0xf3, 0xa7, 0x2f, 0x02, 0xcc, 3158 0x7a, 0x2f, 0x61, 0xa2, 0xf1, 0x1c, 0x6a, 0x93, 0xc1, 0x44, 0xef, 0x41, 0xce, 0x76, 0x4f, 0xbd, 3159 0xa9, 0xac, 0x4d, 0x6c, 0x87, 0x0b, 0x6c, 0x65, 0xea, 0x4a, 0xe3, 0x6f, 0x0a, 0x40, 0xcc, 0x98, 3160 0xfd, 0x38, 0x97, 0x48, 0x8b, 0xcc, 0x75, 0x69, 0x91, 0x9d, 0x4c, 0x8b, 0x25, 0x28, 0x4d, 0x8c, 3161 0x1e, 0x59, 0x1c, 0xad, 0xd1, 0x7a, 0x94, 0x9b, 0xe2, 0xda, 0x5a, 0x9a, 0xe1, 0xe5, 0x6a, 0x2a, 3162 0x41, 0xa3, 0x34, 0x2b, 0x24, 0xd2, 0xac, 0xb1, 0x0a, 0x05, 0x21, 0x87, 0x00, 0x0a, 0xcd, 0x9d, 3163 0x7e, 0xeb, 0x85, 0xa6, 0xce, 0xa1, 0x0a, 0x94, 0xf6, 0x5a, 0x47, 0xad, 0xde, 0x81, 0xb6, 0xab, 3164 0x2a, 0x8c, 0xb3, 0xd7, 0x6c, 0xb5, 0xb5, 0x5d, 0x35, 0xd3, 0xf8, 0xad, 0x02, 0xa5, 0xf0, 0x78, 3165 0xc2, 0xce, 0x3d, 0x59, 0x48, 0xc3, 0xf5, 0xd7, 0xb4, 0xf1, 0x42, 0x6a, 0xe3, 0x08, 0x72, 0x81, 3166 0xfd, 0x25, 0x91, 0x01, 0xe1, 0xdf, 0x4c, 0xde, 0xf1, 0x4c, 0x21, 0x2f, 0x3a, 0x96, 0x68, 0xdd, 3167 0xf8, 0xbb, 0x02, 0x95, 0x24, 0x28, 0xa6, 0xa7, 0x3f, 0x65, 0xc6, 0xf4, 0x97, 0xf4, 0x20, 0x73, 3168 0x85, 0x07, 0xd9, 0x84, 0x07, 0x1f, 0xc0, 0x62, 0x64, 0x34, 0x72, 0x45, 0xb4, 0x55, 0x6a, 0xc8, 3169 0x68, 0x4b, 0x3a, 0xf3, 0x20, 0x84, 0x31, 0xef, 0x0a, 0xb9, 0xcf, 0x59, 0x5c, 0x91, 0xc4, 0x1d, 3170 0x46, 0x4b, 0x45, 0xaf, 0x70, 0x5d, 0xf4, 0x8a, 0x13, 0xd1, 0x6b, 0xfc, 0x45, 0x81, 0x85, 0xe6, 3171 0x88, 0x7a, 0x89, 0x3a, 0xf4, 0xbf, 0x31, 0x61, 0xc5, 0x03, 0xd3, 0x93, 0xef, 0xc8, 0x7e, 0x31, 3172 0x7e, 0x5d, 0x41, 0xf7, 0x41, 0xdd, 0xd5, 0xf6, 0x9a, 0xc7, 0xed, 0xbe, 0xbe, 0xd7, 0x6a, 0x6b, 3173 0xfd, 0x1f, 0x75, 0x19, 0x8e, 0x8b, 0x90, 0x3d, 0xec, 0x3e, 0x53, 0x15, 0xf6, 0xd1, 0xd9, 0xdf, 3174 0x57, 0x33, 0x4f, 0x8e, 0xe0, 0xc1, 0xcc, 0x97, 0x04, 0xf4, 0x18, 0xde, 0x0a, 0x0d, 0xf4, 0xb4, 3175 0xfd, 0x43, 0xed, 0xa8, 0xaf, 0xed, 0x72, 0x53, 0x7a, 0x17, 0x77, 0xfa, 0x9d, 0x9d, 0x4e, 0x5b, 3176 0x9d, 0x43, 0x2a, 0x54, 0x0e, 0xda, 0xbd, 0x98, 0xa2, 0x3c, 0x79, 0x9a, 0x7a, 0xc9, 0x90, 0xd3, 3177 0x7c, 0x19, 0xf2, 0xad, 0xa3, 0x5d, 0xed, 0x87, 0xea, 0x1c, 0xaa, 0x42, 0xb9, 0xdf, 0x3a, 0xd4, 3178 0x7a, 0xfd, 0xe6, 0x61, 0x57, 0x55, 0x9e, 0xac, 0x85, 0x05, 0x27, 0xfa, 0x73, 0xc2, 0xf5, 0xc4, 3179 0xaf, 0x4a, 0x90, 0xc3, 0x7d, 0xae, 0xf1, 0x27, 0x05, 0x1e, 0xcc, 0x7c, 0x61, 0xe4, 0xee, 0xac, 3180 0x6f, 0x3e, 0xd3, 0x3f, 0x5e, 0x5f, 0xeb, 0xea, 0x1b, 0x6b, 0xd2, 0xc1, 0x88, 0xb2, 0xb9, 0xa6, 3181 0x2a, 0x68, 0x11, 0xaa, 0x9c, 0xf2, 0xed, 0xb5, 0x4f, 0x84, 0x50, 0x26, 0x45, 0xda, 0x5c, 0x53, 3182 0xb3, 0xe8, 0x21, 0x3c, 0xe8, 0x76, 0x70, 0x1f, 0x37, 0x5b, 0x7d, 0x7d, 0xc2, 0x64, 0xee, 0x0a, 3183 0xd6, 0xe6, 0x9a, 0x9a, 0x47, 0x4b, 0xf0, 0xda, 0x24, 0x2b, 0xfa, 0x49, 0xe1, 0x2a, 0xde, 0xe6, 3184 0x9a, 0x5a, 0x7c, 0xf2, 0x6b, 0x05, 0x2a, 0xc9, 0x26, 0x02, 0xdd, 0x83, 0x05, 0x6d, 0x1f, 0x6b, 3185 0xbd, 0x9e, 0xde, 0xeb, 0x37, 0x71, 0xbf, 0x75, 0xb4, 0xaf, 0xce, 0x31, 0x37, 0x25, 0x51, 0xd6, 3186 0x25, 0x25, 0x41, 0xd2, 0x8e, 0x76, 0x99, 0x54, 0x26, 0xa1, 0xba, 0xd3, 0x39, 0xec, 0xb6, 0xb5, 3187 0xbe, 0xa6, 0x66, 0x13, 0x72, 0xb2, 0x70, 0xe5, 0x10, 0x82, 0x5a, 0x68, 0x6d, 0xbb, 0x83, 0xfb, 3188 0xda, 0xae, 0x9a, 0x47, 0x75, 0xb8, 0x2f, 0x69, 0xed, 0xd6, 0x61, 0xab, 0xaf, 0x63, 0xad, 0xb9, 3189 0xc3, 0x4a, 0x5e, 0x61, 0xfd, 0x8f, 0x39, 0x28, 0xc8, 0xe4, 0xe9, 0x43, 0xbd, 0xc7, 0x12, 0x6f, 3190 0x46, 0xbb, 0x81, 0x6e, 0xd2, 0x8c, 0x2c, 0xcd, 0x6a, 0xfc, 0xd0, 0x0b, 0x78, 0xc8, 0xad, 0xce, 3191 0xea, 0x3a, 0xd0, 0x8d, 0x9a, 0x92, 0xd9, 0x76, 0x77, 0x41, 0x8d, 0xed, 0x4a, 0x73, 0xd7, 0x35, 3192 0x27, 0xb3, 0xad, 0x7c, 0x9f, 0x81, 0xd4, 0xf0, 0x69, 0xd4, 0x99, 0xa0, 0xab, 0xbb, 0x95, 0xd9, 3193 0x16, 0x9a, 0x50, 0x49, 0x0e, 0x14, 0x28, 0x7e, 0x0c, 0x9b, 0x31, 0x67, 0xfc, 0x1b, 0x13, 0x22, 3194 0x5f, 0xa6, 0x4c, 0x4c, 0x4c, 0x17, 0xb3, 0x4d, 0x68, 0x00, 0x71, 0x63, 0x8e, 0xe2, 0x5b, 0x72, 3195 0x6a, 0x28, 0x58, 0x7a, 0x34, 0x93, 0x27, 0x3b, 0xf9, 0xe7, 0xec, 0x92, 0x0f, 0xdb, 0x73, 0x94, 3196 0xbc, 0x6c, 0x53, 0x3d, 0xfb, 0x4c, 0x2f, 0xb6, 0xf7, 0x7e, 0xfc, 0xf8, 0xcc, 0xa6, 0xe7, 0xa3, 3197 0x93, 0x55, 0xd3, 0x1b, 0x3c, 0x95, 0x02, 0x4f, 0xc3, 0x91, 0x38, 0x24, 0xfc, 0x26, 0x53, 0x6d, 3198 0xdb, 0x97, 0xe4, 0x73, 0x9b, 0xae, 0xf2, 0xd2, 0xf0, 0xd7, 0x4c, 0x4d, 0xae, 0xb7, 0xb6, 0x38, 3199 0xe1, 0xa4, 0xc0, 0x55, 0x36, 0xfe, 0x15, 0x00, 0x00, 0xff, 0xff, 0x4d, 0xbf, 0x6c, 0xf6, 0xfd, 3200 0x1e, 0x00, 0x00, 3201 }