Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"io"
"mime"
Expand Down Expand Up @@ -47,6 +48,10 @@ type Client struct {

type ClientOpt func(*Client) error

// Callback for json stream events, return an error if you want to stop streaming
// with an error and io.EOF if you want to stop streaming and return success
type JsonStreamCallback func(v any) error

///////////////////////////////////////////////////////////////////////////////
// GLOBALS

Expand Down Expand Up @@ -302,8 +307,20 @@ func do(client *http.Client, req *http.Request, accept string, strict bool, out
// Decode the body
switch mimetype {
case ContentTypeJson:
if err := json.NewDecoder(response.Body).Decode(out); err != nil {
return err
// JSON decode is streamable
dec := json.NewDecoder(response.Body)
for {
if err := dec.Decode(out); err == io.EOF {
break
} else if err != nil {
return err
} else if reqopts.jsonStreamCallback != nil {
if err := reqopts.jsonStreamCallback(out); errors.Is(err, io.EOF) {
break
} else if err != nil {
return err
}
}
}
case ContentTypeTextStream:
if err := NewTextStream().Decode(response.Body, reqopts.textStreamCallback); err != nil {
Expand Down
90 changes: 90 additions & 0 deletions cmd/api/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package main

import (
"context"
"time"

// Packages
tablewriter "github.com/djthorpe/go-tablewriter"
client "github.com/mutablelogic/go-client"
auth "github.com/mutablelogic/go-server/pkg/handler/auth/client"
)

var (
authClient *auth.Client
authName = "tokenauth"
authDuration time.Duration
)

func authRegister(flags *Flags) {
// Register flags
flags.String(authName, "tokenauth-endpoint", "${TOKENAUTH_ENDPOINT}", "tokenauth endpoint (ie, http://host/api/auth/)")
flags.String(authName, "tokenauth-token", "${TOKENAUTH_TOKEN}", "tokenauth token")
flags.Duration(authName, "expiry", 0, "token expiry duration")

// Register commands
flags.Register(Cmd{
Name: authName,
Description: "Manage token authentication",
Parse: authParse,
Fn: []Fn{
// Default caller
{Call: authList, Description: "List authentication tokens"},
{Name: "list", Call: authList, Description: "List authentication tokens"},
{Name: "create", Call: authCreate, Description: "Create a token", MinArgs: 1},
{Name: "delete", Call: authDelete, Description: "Delete a token", MinArgs: 1, MaxArgs: 1},
},
})
}

func authParse(flags *Flags, opts ...client.ClientOpt) error {
endpoint := flags.GetString("tokenauth-endpoint")
if token := flags.GetString("tokenauth-token"); token != "" {
opts = append(opts, client.OptReqToken(client.Token{
Scheme: "Bearer",
Value: token,
}))
}

if duration := flags.GetString("expiry"); duration != "" {
if d, err := time.ParseDuration(duration); err != nil {
return err
} else {
authDuration = d
}
}

if client, err := auth.New(endpoint, opts...); err != nil {
return err
} else {
authClient = client
}
return nil
}

func authList(_ context.Context, w *tablewriter.Writer, _ []string) error {
tokens, err := authClient.List()
if err != nil {
return err
}
return w.Write(tokens)
}

func authCreate(_ context.Context, w *tablewriter.Writer, params []string) error {
name := params[0]
scopes := params[1:]
token, err := authClient.Create(name, authDuration, scopes...)
if err != nil {
return err
}
return w.Write(token)
}

func authDelete(ctx context.Context, w *tablewriter.Writer, params []string) error {
name := params[0]
err := authClient.Delete(name)
if err != nil {
return err
}
return authList(ctx, w, nil)
}
1 change: 1 addition & 0 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func main() {

// Register commands
anthropicRegister(flags)
authRegister(flags)
bwRegister(flags)
elRegister(flags)
haRegister(flags)
Expand Down
48 changes: 48 additions & 0 deletions cmd/api/nginx.go_old
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package main

import (
"context"

// Packages
tablewriter "github.com/djthorpe/go-tablewriter"
client "github.com/mutablelogic/go-client"
nginx "github.com/mutablelogic/go-server/pkg/handler/nginx/client"
)

var (
nginxClient *nginx.Client
nginxName = "nginx"
nginxEndpoint string
)

func nginxRegister(flags *Flags) {
flags.Register(Cmd{
Name: nginxName,
Description: "Manage nginx instances",
Parse: nginxParse,
Fn: []Fn{
// Default caller
{Call: nginxGetVersion, Description: "Get the nginx version that is running"},
},
})
}

func nginxParse(flags *Flags, opts ...client.ClientOpt) error {
// Register flags
flags.String(nginxName, "nginx-endpoint", "${NGINX_ENDPOINT}", "nginx endpoint")

if client, err := nginx.New(nginxEndpoint, opts...); err != nil {
return err
} else {
nginxClient = client
}
return nil
}

func nginxGetVersion(_ context.Context, w *tablewriter.Writer, _ []string) error {
version, _, err := nginxClient.Health()
if err != nil {
return err
}
return w.Write(version)
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ toolchain go1.22.3
require (
github.com/andreburgaud/crypt2go v1.5.0
github.com/djthorpe/go-errors v1.0.3
github.com/djthorpe/go-tablewriter v0.0.6
github.com/djthorpe/go-tablewriter v0.0.7
github.com/go-audio/audio v1.0.0
github.com/go-audio/wav v1.1.0
github.com/mutablelogic/go-server v1.4.7
github.com/stretchr/testify v1.9.0
github.com/xdg-go/pbkdf2 v1.0.0
golang.org/x/crypto v0.23.0
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/djthorpe/go-errors v1.0.3 h1:GZeMPkC1mx2vteXLI/gvxZS0Ee9zxzwD1mcYyKU5jD0=
github.com/djthorpe/go-errors v1.0.3/go.mod h1:HtfrZnMd6HsX75Mtbv9Qcnn0BqOrrFArvCaj3RMnZhY=
github.com/djthorpe/go-tablewriter v0.0.6 h1:iGi1eln0KEknJUH9AtPeTeOUcioilDRs7QruyRcmtWM=
github.com/djthorpe/go-tablewriter v0.0.6/go.mod h1:LL+Dxaepm8Q0qUVD9EB6+d0xr7I7OgQYEfrugI8fBUA=
github.com/djthorpe/go-tablewriter v0.0.7 h1:jnNsJDjjLLCt0OAqB5DzGZN7V3beT1IpNMQ8GcOwZDU=
github.com/djthorpe/go-tablewriter v0.0.7/go.mod h1:NVBvytpL+6fHfCKn0+3lSi15/G3A1HWf2cLNeHg6YBg=
github.com/go-audio/audio v1.0.0 h1:zS9vebldgbQqktK4H0lUqWrG8P0NxCJVqcj7ZpNnwd4=
github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs=
github.com/go-audio/riff v1.0.0 h1:d8iCGbDvox9BfLagY94fBynxSPHO80LmZCaOsmKxokA=
Expand All @@ -14,6 +14,8 @@ github.com/go-audio/wav v1.1.0 h1:jQgLtbqBzY7G+BM8fXF7AHUk1uHUviWS4X39d5rsL2g=
github.com/go-audio/wav v1.1.0/go.mod h1:mpe9qfwbScEbkd8uybLuIpTgHyrISw/OTuvjUW2iGtE=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mutablelogic/go-server v1.4.7 h1:NpzG30f/D50Xbwr96dA6uiapyr4QHBziSanc/q/LR7k=
github.com/mutablelogic/go-server v1.4.7/go.mod h1:wrrDg863hlv5/DUpSG/Pb4k9LiSYO7VxRgLPiMhrE6M=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
Expand Down
2 changes: 1 addition & 1 deletion pkg/multipart/multipart.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func NewMultipartEncoder(w io.Writer) *Encoder {
}
}

// NewFormEncoder creates a new encoder object, whichwrites
// NewFormEncoder creates a new encoder object, which writes
// application/x-www-form-urlencoded to the io.Writer
func NewFormEncoder(w io.Writer) *Encoder {
return &Encoder{
Expand Down
9 changes: 9 additions & 0 deletions requestopts.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type requestOpts struct {
*http.Request
noTimeout bool // OptNoTimeout
textStreamCallback TextStreamCallback // OptTextStreamCallback
jsonStreamCallback JsonStreamCallback // OptJsonStreamCallback
}

type RequestOpt func(*requestOpts) error
Expand Down Expand Up @@ -103,3 +104,11 @@ func OptTextStreamCallback(fn TextStreamCallback) RequestOpt {
return nil
}
}

// OptJsonStreamCallback is called for each decoded JSON event
func OptJsonStreamCallback(fn JsonStreamCallback) RequestOpt {
return func(r *requestOpts) error {
r.jsonStreamCallback = fn
return nil
}
}