forked from Botanical/BotanJS
108 lines
2.1 KiB
Go
108 lines
2.1 KiB
Go
package closure
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
type Client struct {
|
|
endpoint string
|
|
http *http.Client
|
|
}
|
|
|
|
func NewClientFromEnv() *Client {
|
|
endpoint := os.Getenv("CLOSURE_ENDPOINT")
|
|
if endpoint == "" {
|
|
endpoint = "http://closure-svc:8080/compile"
|
|
}
|
|
|
|
return &Client{
|
|
endpoint: endpoint,
|
|
http: &http.Client{
|
|
Timeout: 70 * time.Second,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (c *Client) Compile(ctx context.Context, reqBody CompileRequest) ([]byte, error) {
|
|
body, err := json.Marshal(reqBody)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(
|
|
ctx,
|
|
http.MethodPost,
|
|
c.endpoint,
|
|
bytes.NewReader(body),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
resp, err := c.http.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode/100 != 2 {
|
|
body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
|
|
return nil, fmt.Errorf("closure failed: %s: %s", resp.Status, body)
|
|
}
|
|
|
|
return io.ReadAll(resp.Body)
|
|
}
|
|
|
|
func (c *Client) DebugPrintCurl(ctx context.Context, reqBody CompileRequest) {
|
|
if os.Getenv("CLOSURE_DEBUG_CURL") == "" {
|
|
return
|
|
}
|
|
|
|
body, err := json.MarshalIndent(reqBody, "", " ")
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "closure debug: marshal payload failed: %v\n", err)
|
|
return
|
|
}
|
|
|
|
tmpDir := os.Getenv("CLOSURE_DEBUG_DIR")
|
|
if tmpDir == "" {
|
|
tmpDir = os.TempDir()
|
|
}
|
|
|
|
path := filepath.Join(
|
|
tmpDir,
|
|
fmt.Sprintf("closure-request-%d.json", time.Now().UnixNano()),
|
|
)
|
|
|
|
if err := os.WriteFile(path, body, 0o600); err != nil {
|
|
fmt.Fprintf(os.Stderr, "closure debug: write payload failed: %v\n", err)
|
|
return
|
|
}
|
|
|
|
fmt.Fprintf(
|
|
os.Stderr,
|
|
"closure debug curl:\n curl -v -X POST %s -H 'Content-Type: application/json' --data-binary @%s\n",
|
|
shellQuote(c.endpoint),
|
|
shellQuote(path),
|
|
)
|
|
|
|
if deadline, ok := ctx.Deadline(); ok {
|
|
fmt.Fprintf(os.Stderr, "closure debug deadline: %s\n", deadline.Format(time.RFC3339Nano))
|
|
}
|
|
}
|
|
|
|
func shellQuote(s string) string {
|
|
return strconv.Quote(s)
|
|
}
|