mirror of
https://github.com/netbirdio/netbird.git
synced 2026-03-31 06:24:18 -04:00
101 lines
2.7 KiB
Go
101 lines
2.7 KiB
Go
//go:build js
|
|
|
|
package http
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
log "github.com/sirupsen/logrus"
|
|
"net/http"
|
|
"strings"
|
|
"syscall/js"
|
|
"time"
|
|
|
|
netbird "github.com/netbirdio/netbird/client/embed"
|
|
)
|
|
|
|
const (
|
|
httpTimeout = 30 * time.Second
|
|
maxResponseSize = 1024 * 1024 // 1MB
|
|
)
|
|
|
|
// performRequest executes an HTTP request through NetBird and returns the response and body
|
|
func performRequest(nbClient *netbird.Client, method, url string, headers map[string]string, body []byte) (*http.Response, []byte, error) {
|
|
httpClient := nbClient.NewHTTPClient()
|
|
httpClient.Timeout = httpTimeout
|
|
|
|
req, err := http.NewRequest(method, url, strings.NewReader(string(body)))
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("create request: %w", err)
|
|
}
|
|
|
|
for key, value := range headers {
|
|
req.Header.Set(key, value)
|
|
}
|
|
|
|
resp, err := httpClient.Do(req)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("request failed: %w", err)
|
|
}
|
|
defer func() {
|
|
if err := resp.Body.Close(); err != nil {
|
|
log.Errorf("failed to close response body: %v", err)
|
|
}
|
|
}()
|
|
|
|
respBody, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseSize))
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("read response: %w", err)
|
|
}
|
|
|
|
return resp, respBody, nil
|
|
}
|
|
|
|
// ProxyRequest performs a proxied HTTP request through NetBird and returns a JavaScript object
|
|
func ProxyRequest(nbClient *netbird.Client, request js.Value) (js.Value, error) {
|
|
url := request.Get("url").String()
|
|
if url == "" {
|
|
return js.Undefined(), fmt.Errorf("URL is required")
|
|
}
|
|
|
|
method := "GET"
|
|
if methodVal := request.Get("method"); !methodVal.IsNull() && !methodVal.IsUndefined() {
|
|
method = strings.ToUpper(methodVal.String())
|
|
}
|
|
|
|
var requestBody []byte
|
|
if bodyVal := request.Get("body"); !bodyVal.IsNull() && !bodyVal.IsUndefined() {
|
|
requestBody = []byte(bodyVal.String())
|
|
}
|
|
|
|
requestHeaders := make(map[string]string)
|
|
if headersVal := request.Get("headers"); !headersVal.IsNull() && !headersVal.IsUndefined() && headersVal.Type() == js.TypeObject {
|
|
headerKeys := js.Global().Get("Object").Call("keys", headersVal)
|
|
for i := 0; i < headerKeys.Length(); i++ {
|
|
key := headerKeys.Index(i).String()
|
|
value := headersVal.Get(key).String()
|
|
requestHeaders[key] = value
|
|
}
|
|
}
|
|
|
|
resp, body, err := performRequest(nbClient, method, url, requestHeaders, requestBody)
|
|
if err != nil {
|
|
return js.Undefined(), err
|
|
}
|
|
|
|
result := js.Global().Get("Object").New()
|
|
result.Set("status", resp.StatusCode)
|
|
result.Set("statusText", resp.Status)
|
|
result.Set("body", string(body))
|
|
|
|
headers := js.Global().Get("Object").New()
|
|
for key, values := range resp.Header {
|
|
if len(values) > 0 {
|
|
headers.Set(strings.ToLower(key), values[0])
|
|
}
|
|
}
|
|
result.Set("headers", headers)
|
|
|
|
return result, nil
|
|
}
|