fix: date fixes; go middleware refactors; regex fixes; etc (#368)

fix: format of date when MR was closed or merged (#367)
refactor: Add Payload Validators + Middleware In Go Code (#366)
fix: Add better checks for leaving comments (#369)
fix: regex support for http credentials embedded in remote url (#372)
fix: Comment on single line selects two lines (#371)

This is a #PATCH release.
This commit is contained in:
Harrison (Harry) Cramer
2024-09-14 16:53:00 -04:00
committed by GitHub
parent f1faf603b0
commit 22bfd0c83e
61 changed files with 1527 additions and 1284 deletions

96
cmd/app/logging.go Normal file
View File

@@ -0,0 +1,96 @@
package app
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
"net/http/httputil"
"os"
)
// LoggingServer is a wrapper around an http.Handler to log incoming requests and outgoing responses.
type LoggingServer struct {
handler http.Handler
}
type LoggingResponseWriter struct {
statusCode int
body *bytes.Buffer
http.ResponseWriter
}
func (l *LoggingResponseWriter) WriteHeader(statusCode int) {
l.statusCode = statusCode
}
func (l *LoggingResponseWriter) Write(b []byte) (int, error) {
l.body.Write(b)
return l.ResponseWriter.Write(b)
}
// Logs the request, calls the original handler on the ServeMux, then logs the response
func (l LoggingServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if pluginOptions.Debug.Request {
logRequest("REQUEST TO GO SERVER", r)
}
lrw := &LoggingResponseWriter{ResponseWriter: w, body: &bytes.Buffer{}}
l.handler.ServeHTTP(lrw, r)
resp := &http.Response{
Status: http.StatusText(lrw.statusCode),
StatusCode: lrw.statusCode,
Body: io.NopCloser(bytes.NewBuffer(lrw.body.Bytes())), // Use the captured body
ContentLength: int64(lrw.body.Len()),
Header: lrw.Header(),
Request: r,
}
if pluginOptions.Debug.Response {
logResponse("RESPONSE FROM GO SERVER", resp)
}
}
func logRequest(prefix string, r *http.Request) {
file := openLogFile()
defer file.Close()
token := r.Header.Get("Private-Token")
r.Header.Set("Private-Token", "REDACTED")
res, err := httputil.DumpRequest(r, true)
if err != nil {
log.Fatalf("Error dumping request: %v", err)
os.Exit(1)
}
r.Header.Set("Private-Token", token)
_, err = file.Write([]byte(fmt.Sprintf("\n-- %s --\n%s\n", prefix, res))) //nolint:all
}
func logResponse(prefix string, r *http.Response) {
file := openLogFile()
defer file.Close()
res, err := httputil.DumpResponse(r, true)
if err != nil {
log.Fatalf("Error dumping response: %v", err)
os.Exit(1)
}
_, err = file.Write([]byte(fmt.Sprintf("\n-- %s --\n%s\n", prefix, res))) //nolint:all
}
func openLogFile() *os.File {
file, err := os.OpenFile(pluginOptions.LogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
if os.IsNotExist(err) {
log.Printf("Log file %s does not exist", pluginOptions.LogPath)
} else if os.IsPermission(err) {
log.Printf("Permission denied for log file %s", pluginOptions.LogPath)
} else {
log.Printf("Error opening log file %s: %v", pluginOptions.LogPath, err)
}
os.Exit(1)
}
return file
}