Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
113 lines
2.4 KiB
Go
113 lines
2.4 KiB
Go
package openai
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/textproto"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
type FormBuilder interface {
|
|
CreateFormFile(fieldname string, file *os.File) error
|
|
CreateFormFileReader(fieldname string, r io.Reader, filename string) error
|
|
WriteField(fieldname, value string) error
|
|
Close() error
|
|
FormDataContentType() string
|
|
}
|
|
|
|
type DefaultFormBuilder struct {
|
|
writer *multipart.Writer
|
|
}
|
|
|
|
func NewFormBuilder(body io.Writer) *DefaultFormBuilder {
|
|
return &DefaultFormBuilder{
|
|
writer: multipart.NewWriter(body),
|
|
}
|
|
}
|
|
|
|
func (fb *DefaultFormBuilder) CreateFormFile(fieldname string, file *os.File) error {
|
|
return fb.createFormFile(fieldname, file, file.Name())
|
|
}
|
|
|
|
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
|
|
|
|
func escapeQuotes(s string) string {
|
|
return quoteEscaper.Replace(s)
|
|
}
|
|
|
|
// CreateFormFileReader creates a form field with a file reader.
|
|
// The filename in Content-Disposition is required.
|
|
func (fb *DefaultFormBuilder) CreateFormFileReader(fieldname string, r io.Reader, filename string) error {
|
|
if filename == "" {
|
|
if f, ok := r.(interface{ Name() string }); ok {
|
|
filename = f.Name()
|
|
}
|
|
}
|
|
var contentType string
|
|
if f, ok := r.(interface{ ContentType() string }); ok {
|
|
contentType = f.ContentType()
|
|
}
|
|
|
|
h := make(textproto.MIMEHeader)
|
|
h.Set(
|
|
"Content-Disposition",
|
|
fmt.Sprintf(
|
|
`form-data; name="%s"; filename="%s"`,
|
|
escapeQuotes(fieldname),
|
|
escapeQuotes(filepath.Base(filename)),
|
|
),
|
|
)
|
|
// content type is optional, but it can be set
|
|
if contentType != "" {
|
|
h.Set("Content-Type", contentType)
|
|
}
|
|
|
|
fieldWriter, err := fb.writer.CreatePart(h)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = io.Copy(fieldWriter, r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (fb *DefaultFormBuilder) createFormFile(fieldname string, r io.Reader, filename string) error {
|
|
if filename == "" {
|
|
return fmt.Errorf("filename cannot be empty")
|
|
}
|
|
|
|
fieldWriter, err := fb.writer.CreateFormFile(fieldname, filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = io.Copy(fieldWriter, r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (fb *DefaultFormBuilder) WriteField(fieldname, value string) error {
|
|
if fieldname == "" {
|
|
return fmt.Errorf("fieldname cannot be empty")
|
|
}
|
|
return fb.writer.WriteField(fieldname, value)
|
|
}
|
|
|
|
func (fb *DefaultFormBuilder) Close() error {
|
|
return fb.writer.Close()
|
|
}
|
|
|
|
func (fb *DefaultFormBuilder) FormDataContentType() string {
|
|
return fb.writer.FormDataContentType()
|
|
}
|