Files
AstroJS/resolver-go/internal/closure/client.go
T

116 lines
2.3 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()
respBody, err := io.ReadAll(io.LimitReader(resp.Body, 64<<20))
if err != nil {
return nil, err
}
if resp.StatusCode/100 != 2 {
return nil, fmt.Errorf("closure failed: %s: %s", resp.Status, respBody)
}
var cr CompileResponse
if err := json.Unmarshal(respBody, &cr); err != nil {
return nil, fmt.Errorf("closure returned invalid json: %w: %s", err, respBody)
}
if !cr.OK {
return nil, fmt.Errorf("closure compile failed: errors=%q warnings=%q", len(cr.Errors), len(cr.Warnings))
}
return []byte(cr.JS), nil
}
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
}
path := filepath.Join(
os.TempDir(),
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 %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)
}