mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-08-10 13:20:33 +02:00
all: change send log to use x-www-form-urlencoded
This commit is contained in:
@@ -2,8 +2,9 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -215,17 +216,23 @@ func (p *prog) registerControlServerHandler() {
|
|||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
}))
|
}))
|
||||||
p.cs.register(viewLogsPath, http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
|
p.cs.register(viewLogsPath, http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) {
|
||||||
data, err := p.logContent()
|
lr, err := p.logReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(data) == 0 {
|
if lr.size == 0 {
|
||||||
w.WriteHeader(http.StatusMovedPermanently)
|
w.WriteHeader(http.StatusMovedPermanently)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
data, err := io.ReadAll(lr.r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, fmt.Sprintf("could not read log: %v", err), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
if err := json.NewEncoder(w).Encode(&logViewResponse{Data: string(data)}); err != nil {
|
if err := json.NewEncoder(w).Encode(&logViewResponse{Data: string(data)}); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
http.Error(w, fmt.Sprintf("could not marshal log data: %v", err), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -234,22 +241,21 @@ func (p *prog) registerControlServerHandler() {
|
|||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data, err := p.logContent()
|
r, err := p.logReader()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(data) == 0 {
|
if r.size == 0 {
|
||||||
w.WriteHeader(http.StatusMovedPermanently)
|
w.WriteHeader(http.StatusMovedPermanently)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logFile := base64.StdEncoding.EncodeToString(data)
|
|
||||||
req := &controld.LogsRequest{
|
req := &controld.LogsRequest{
|
||||||
UID: cdUID,
|
UID: cdUID,
|
||||||
LogFile: logFile,
|
Data: r.r,
|
||||||
}
|
}
|
||||||
mainLog.Load().Debug().Msg("sending log file to ControlD server")
|
mainLog.Load().Debug().Msg("sending log file to ControlD server")
|
||||||
resp := logSentResponse{Size: len(data)}
|
resp := logSentResponse{Size: r.size}
|
||||||
if err := controld.SendLogs(req, cdDev); err != nil {
|
if err := controld.SendLogs(req, cdDev); err != nil {
|
||||||
mainLog.Load().Error().Msgf("could not send log file to ControlD server: %v", err)
|
mainLog.Load().Error().Msgf("could not send log file to ControlD server: %v", err)
|
||||||
resp.Error = err.Error()
|
resp.Error = err.Error()
|
||||||
|
|||||||
+29
-18
@@ -3,6 +3,7 @@ package cli
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -25,10 +26,15 @@ type logViewResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type logSentResponse struct {
|
type logSentResponse struct {
|
||||||
Size int `json:"size"`
|
Size int64 `json:"size"`
|
||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type logReader struct {
|
||||||
|
r io.ReadCloser
|
||||||
|
size int64
|
||||||
|
}
|
||||||
|
|
||||||
// logWriter is an internal buffer to keep track of runtime log when no logging is enabled.
|
// logWriter is an internal buffer to keep track of runtime log when no logging is enabled.
|
||||||
type logWriter struct {
|
type logWriter struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -111,8 +117,7 @@ func (p *prog) needInternalLogging() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *prog) logContent() ([]byte, error) {
|
func (p *prog) logReader() (*logReader, error) {
|
||||||
var data []byte
|
|
||||||
if p.needInternalLogging() {
|
if p.needInternalLogging() {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
lw := p.internalLogWriter
|
lw := p.internalLogWriter
|
||||||
@@ -121,23 +126,29 @@ func (p *prog) logContent() ([]byte, error) {
|
|||||||
return nil, errors.New("nil internal log writer")
|
return nil, errors.New("nil internal log writer")
|
||||||
}
|
}
|
||||||
lw.mu.Lock()
|
lw.mu.Lock()
|
||||||
data = lw.buf.Bytes()
|
lr := &logReader{r: io.NopCloser(bytes.NewReader(lw.buf.Bytes()))}
|
||||||
|
lr.size = int64(lw.buf.Len())
|
||||||
lw.mu.Unlock()
|
lw.mu.Unlock()
|
||||||
if len(data) == 0 {
|
if lr.size == 0 {
|
||||||
return nil, errors.New("internal log is empty")
|
return nil, errors.New("internal log is empty")
|
||||||
}
|
}
|
||||||
} else {
|
return lr, nil
|
||||||
if p.cfg.Service.LogPath == "" {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
buf, err := os.ReadFile(normalizeLogFilePath(p.cfg.Service.LogPath))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
data = buf
|
|
||||||
if len(data) == 0 {
|
|
||||||
return nil, errors.New("log file is empty")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return data, nil
|
if p.cfg.Service.LogPath == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
f, err := os.Open(normalizeLogFilePath(p.cfg.Service.LogPath))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lr := &logReader{r: f}
|
||||||
|
if st, err := f.Stat(); err == nil {
|
||||||
|
lr.size = st.Size()
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("f.Stat: %w", err)
|
||||||
|
}
|
||||||
|
if lr.size == 0 {
|
||||||
|
return nil, errors.New("log file is empty")
|
||||||
|
}
|
||||||
|
return lr, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -77,8 +77,8 @@ type UtilityOrgRequest struct {
|
|||||||
|
|
||||||
// LogsRequest contains request data for sending runtime logs to API.
|
// LogsRequest contains request data for sending runtime logs to API.
|
||||||
type LogsRequest struct {
|
type LogsRequest struct {
|
||||||
UID string `json:"uid"`
|
UID string `json:"uid"`
|
||||||
LogFile string `json:"log_file"`
|
Data io.ReadCloser `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchResolverConfig fetch Control D config for given uid.
|
// FetchResolverConfig fetch Control D config for given uid.
|
||||||
@@ -160,20 +160,20 @@ func postUtilityAPI(version string, cdDev, lastUpdatedFailed bool, body io.Reade
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendLogs sends runtime log to ControlD API.
|
// SendLogs sends runtime log to ControlD API.
|
||||||
func SendLogs(req *LogsRequest, cdDev bool) error {
|
func SendLogs(lr *LogsRequest, cdDev bool) error {
|
||||||
body, _ := json.Marshal(req)
|
defer lr.Data.Close()
|
||||||
return postLogAPI(cdDev, bytes.NewReader(body))
|
|
||||||
}
|
|
||||||
|
|
||||||
func postLogAPI(cdDev bool, body io.Reader) error {
|
|
||||||
apiUrl := logURLCom
|
apiUrl := logURLCom
|
||||||
if cdDev {
|
if cdDev {
|
||||||
apiUrl = logURLDev
|
apiUrl = logURLDev
|
||||||
}
|
}
|
||||||
req, err := http.NewRequest("POST", apiUrl, body)
|
req, err := http.NewRequest("POST", apiUrl, lr.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("http.NewRequest: %w", err)
|
return fmt.Errorf("http.NewRequest: %w", err)
|
||||||
}
|
}
|
||||||
|
q := req.URL.Query()
|
||||||
|
q.Set("uid", lr.UID)
|
||||||
|
req.URL.RawQuery = q.Encode()
|
||||||
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
transport := apiTransport(cdDev)
|
transport := apiTransport(cdDev)
|
||||||
client := http.Client{
|
client := http.Client{
|
||||||
Timeout: 10 * time.Second,
|
Timeout: 10 * time.Second,
|
||||||
@@ -181,7 +181,7 @@ func postLogAPI(cdDev bool, body io.Reader) error {
|
|||||||
}
|
}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("postLogAPI client.Do: %w", err)
|
return fmt.Errorf("SendLogs client.Do: %w", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
d := json.NewDecoder(resp.Body)
|
d := json.NewDecoder(resp.Body)
|
||||||
|
|||||||
Reference in New Issue
Block a user