mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-02 04:20:50 +08:00
141 lines
4.3 KiB
Go
141 lines
4.3 KiB
Go
// Package main demonstrates how to use coreauth.Manager.HttpRequest/NewHttpRequest
|
|
// to execute arbitrary HTTP requests with provider credentials injected.
|
|
//
|
|
// This example registers a minimal custom executor that injects an Authorization
|
|
// header from auth.Attributes["api_key"], then performs two requests against
|
|
// httpbin.org to show the injected headers.
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
|
|
clipexec "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/executor"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const providerKey = "echo"
|
|
|
|
// EchoExecutor is a minimal provider implementation for demonstration purposes.
|
|
type EchoExecutor struct{}
|
|
|
|
func (EchoExecutor) Identifier() string { return providerKey }
|
|
|
|
func (EchoExecutor) PrepareRequest(req *http.Request, auth *coreauth.Auth) error {
|
|
if req == nil || auth == nil {
|
|
return nil
|
|
}
|
|
if auth.Attributes != nil {
|
|
if apiKey := strings.TrimSpace(auth.Attributes["api_key"]); apiKey != "" {
|
|
req.Header.Set("Authorization", "Bearer "+apiKey)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (EchoExecutor) HttpRequest(ctx context.Context, auth *coreauth.Auth, req *http.Request) (*http.Response, error) {
|
|
if req == nil {
|
|
return nil, fmt.Errorf("echo executor: request is nil")
|
|
}
|
|
if ctx == nil {
|
|
ctx = req.Context()
|
|
}
|
|
httpReq := req.WithContext(ctx)
|
|
if errPrep := (EchoExecutor{}).PrepareRequest(httpReq, auth); errPrep != nil {
|
|
return nil, errPrep
|
|
}
|
|
return http.DefaultClient.Do(httpReq)
|
|
}
|
|
|
|
func (EchoExecutor) Execute(context.Context, *coreauth.Auth, clipexec.Request, clipexec.Options) (clipexec.Response, error) {
|
|
return clipexec.Response{}, errors.New("echo executor: Execute not implemented")
|
|
}
|
|
|
|
func (EchoExecutor) ExecuteStream(context.Context, *coreauth.Auth, clipexec.Request, clipexec.Options) (<-chan clipexec.StreamChunk, error) {
|
|
return nil, errors.New("echo executor: ExecuteStream not implemented")
|
|
}
|
|
|
|
func (EchoExecutor) Refresh(context.Context, *coreauth.Auth) (*coreauth.Auth, error) {
|
|
return nil, errors.New("echo executor: Refresh not implemented")
|
|
}
|
|
|
|
func (EchoExecutor) CountTokens(context.Context, *coreauth.Auth, clipexec.Request, clipexec.Options) (clipexec.Response, error) {
|
|
return clipexec.Response{}, errors.New("echo executor: CountTokens not implemented")
|
|
}
|
|
|
|
func main() {
|
|
log.SetLevel(log.InfoLevel)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
core := coreauth.NewManager(nil, nil, nil)
|
|
core.RegisterExecutor(EchoExecutor{})
|
|
|
|
auth := &coreauth.Auth{
|
|
ID: "demo-echo",
|
|
Provider: providerKey,
|
|
Attributes: map[string]string{
|
|
"api_key": "demo-api-key",
|
|
},
|
|
}
|
|
|
|
// Example 1: Build a prepared request and execute it using your own http.Client.
|
|
reqPrepared, errReqPrepared := core.NewHttpRequest(
|
|
ctx,
|
|
auth,
|
|
http.MethodGet,
|
|
"https://httpbin.org/anything",
|
|
nil,
|
|
http.Header{"X-Example": []string{"prepared"}},
|
|
)
|
|
if errReqPrepared != nil {
|
|
panic(errReqPrepared)
|
|
}
|
|
respPrepared, errDoPrepared := http.DefaultClient.Do(reqPrepared)
|
|
if errDoPrepared != nil {
|
|
panic(errDoPrepared)
|
|
}
|
|
defer func() {
|
|
if errClose := respPrepared.Body.Close(); errClose != nil {
|
|
log.Errorf("close response body error: %v", errClose)
|
|
}
|
|
}()
|
|
bodyPrepared, errReadPrepared := io.ReadAll(respPrepared.Body)
|
|
if errReadPrepared != nil {
|
|
panic(errReadPrepared)
|
|
}
|
|
fmt.Printf("Prepared request status: %d\n%s\n\n", respPrepared.StatusCode, bodyPrepared)
|
|
|
|
// Example 2: Execute a raw request via core.HttpRequest (auto inject + do).
|
|
rawBody := []byte(`{"hello":"world"}`)
|
|
rawReq, errRawReq := http.NewRequestWithContext(ctx, http.MethodPost, "https://httpbin.org/anything", bytes.NewReader(rawBody))
|
|
if errRawReq != nil {
|
|
panic(errRawReq)
|
|
}
|
|
rawReq.Header.Set("Content-Type", "application/json")
|
|
rawReq.Header.Set("X-Example", "executed")
|
|
|
|
respExec, errDoExec := core.HttpRequest(ctx, auth, rawReq)
|
|
if errDoExec != nil {
|
|
panic(errDoExec)
|
|
}
|
|
defer func() {
|
|
if errClose := respExec.Body.Close(); errClose != nil {
|
|
log.Errorf("close response body error: %v", errClose)
|
|
}
|
|
}()
|
|
bodyExec, errReadExec := io.ReadAll(respExec.Body)
|
|
if errReadExec != nil {
|
|
panic(errReadExec)
|
|
}
|
|
fmt.Printf("Manager HttpRequest status: %d\n%s\n", respExec.StatusCode, bodyExec)
|
|
}
|