mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
feat: Add Support for Proxy with Interceptor (#77)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user