mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
package proxy
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func newRequestContext(req *http.Request) (*RequestContext, error) {
|
|
var hostname string
|
|
// Extract hostname - for MITM'd requests, URL might be relative
|
|
// so we need to check the Host header
|
|
if req.URL != nil {
|
|
hostname = req.URL.Hostname()
|
|
}
|
|
|
|
if hostname == "" && req.Host != "" {
|
|
// For MITM requests, the URL is relative but Host header contains the hostname
|
|
hostname = req.Host
|
|
if host, _, err := net.SplitHostPort(req.Host); err == nil {
|
|
hostname = host
|
|
}
|
|
}
|
|
|
|
requestID, err := generateRequestID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate request ID: %w", err)
|
|
}
|
|
|
|
return &RequestContext{
|
|
URL: req.URL,
|
|
Method: req.Method,
|
|
Headers: req.Header,
|
|
Hostname: hostname,
|
|
RequestID: requestID,
|
|
StartTime: time.Now(),
|
|
Data: make(map[string]interface{}),
|
|
}, nil
|
|
}
|
|
|
|
func newRequestContextFromURL(urlStr string, method string) (*RequestContext, error) {
|
|
// For CONNECT requests, we receive "hostname:port" (e.g., "registry.npmjs.org:443")
|
|
// url.Parse treats this as "scheme:path", so we need to add "//" to parse correctly
|
|
if !strings.Contains(urlStr, "://") {
|
|
urlStr = "//" + urlStr
|
|
}
|
|
|
|
parsedURL, err := url.Parse(urlStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse URL: %w", err)
|
|
}
|
|
|
|
// If URL doesn't have a scheme, add https (typical for CONNECT)
|
|
if parsedURL.Scheme == "" {
|
|
parsedURL.Scheme = "https"
|
|
}
|
|
|
|
requestID, err := generateRequestID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate request ID: %w", err)
|
|
}
|
|
|
|
return &RequestContext{
|
|
URL: parsedURL,
|
|
Method: method,
|
|
Headers: make(http.Header),
|
|
Hostname: parsedURL.Hostname(),
|
|
RequestID: requestID,
|
|
StartTime: time.Now(),
|
|
Data: make(map[string]interface{}),
|
|
}, nil
|
|
}
|
|
|
|
func generateRequestID() (string, error) {
|
|
bytes := make([]byte, 8)
|
|
if _, err := rand.Read(bytes); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return hex.EncodeToString(bytes), nil
|
|
}
|