Skip to content

Commit

Permalink
perf: remove some useless string pinning (#1295)
Browse files Browse the repository at this point in the history
* Removes pinning.

* trigger build

* Cleans up function params.

---------

Co-authored-by: Alliballibaba <[email protected]>
  • Loading branch information
AlliBalliBaba and Alliballibaba2 authored Jan 5, 2025
1 parent 43c1de2 commit 045ce00
Showing 1 changed file with 45 additions and 39 deletions.
84 changes: 45 additions & 39 deletions cgi.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"path/filepath"
"strings"
"unsafe"
)

var knownServerKeys = map[string]struct{}{
Expand Down Expand Up @@ -62,56 +63,56 @@ func addKnownVariablesToServer(thread *phpThread, request *http.Request, fc *Fra

ra, raOK := fc.env["REMOTE_ADDR\x00"]
if raOK {
registerTrustedVar(keys["REMOTE_ADDR\x00"], ra, trackVarsArray, thread)
registerTrustedVar(keys["REMOTE_ADDR\x00"], ra, trackVarsArray)
} else {
registerTrustedVar(keys["REMOTE_ADDR\x00"], ip, trackVarsArray, thread)
registerTrustedVar(keys["REMOTE_ADDR\x00"], ip, trackVarsArray)
}

if rh, ok := fc.env["REMOTE_HOST\x00"]; ok {
registerTrustedVar(keys["REMOTE_HOST\x00"], rh, trackVarsArray, thread) // For speed, remote host lookups disabled
registerTrustedVar(keys["REMOTE_HOST\x00"], rh, trackVarsArray) // For speed, remote host lookups disabled
} else {
if raOK {
registerTrustedVar(keys["REMOTE_HOST\x00"], ra, trackVarsArray, thread)
registerTrustedVar(keys["REMOTE_HOST\x00"], ra, trackVarsArray)
} else {
registerTrustedVar(keys["REMOTE_HOST\x00"], ip, trackVarsArray, thread)
registerTrustedVar(keys["REMOTE_HOST\x00"], ip, trackVarsArray)
}
}

registerTrustedVar(keys["REMOTE_PORT\x00"], port, trackVarsArray, thread)
registerTrustedVar(keys["DOCUMENT_ROOT\x00"], fc.documentRoot, trackVarsArray, thread)
registerTrustedVar(keys["PATH_INFO\x00"], fc.pathInfo, trackVarsArray, thread)
registerTrustedVar(keys["PHP_SELF\x00"], request.URL.Path, trackVarsArray, thread)
registerTrustedVar(keys["DOCUMENT_URI\x00"], fc.docURI, trackVarsArray, thread)
registerTrustedVar(keys["SCRIPT_FILENAME\x00"], fc.scriptFilename, trackVarsArray, thread)
registerTrustedVar(keys["SCRIPT_NAME\x00"], fc.scriptName, trackVarsArray, thread)
registerTrustedVar(keys["REMOTE_PORT\x00"], port, trackVarsArray)
registerTrustedVar(keys["DOCUMENT_ROOT\x00"], fc.documentRoot, trackVarsArray)
registerTrustedVar(keys["PATH_INFO\x00"], fc.pathInfo, trackVarsArray)
registerTrustedVar(keys["PHP_SELF\x00"], request.URL.Path, trackVarsArray)
registerTrustedVar(keys["DOCUMENT_URI\x00"], fc.docURI, trackVarsArray)
registerTrustedVar(keys["SCRIPT_FILENAME\x00"], fc.scriptFilename, trackVarsArray)
registerTrustedVar(keys["SCRIPT_NAME\x00"], fc.scriptName, trackVarsArray)

var rs string
if request.TLS == nil {
rs = "http"
registerTrustedVar(keys["HTTPS\x00"], "", trackVarsArray, thread)
registerTrustedVar(keys["SSL_PROTOCOL\x00"], "", trackVarsArray, thread)
registerTrustedVar(keys["HTTPS\x00"], "", trackVarsArray)
registerTrustedVar(keys["SSL_PROTOCOL\x00"], "", trackVarsArray)
} else {
rs = "https"
if h, ok := fc.env["HTTPS\x00"]; ok {
registerTrustedVar(keys["HTTPS\x00"], h, trackVarsArray, thread)
registerTrustedVar(keys["HTTPS\x00"], h, trackVarsArray)
} else {
registerTrustedVar(keys["HTTPS\x00"], "on", trackVarsArray, thread)
registerTrustedVar(keys["HTTPS\x00"], "on", trackVarsArray)
}

// and pass the protocol details in a manner compatible with apache's mod_ssl
// (which is why these have an SSL_ prefix and not TLS_).
if pr, ok := fc.env["SSL_PROTOCOL\x00"]; ok {
registerTrustedVar(keys["SSL_PROTOCOL\x00"], pr, trackVarsArray, thread)
registerTrustedVar(keys["SSL_PROTOCOL\x00"], pr, trackVarsArray)
} else {
if v, ok := tlsProtocolStrings[request.TLS.Version]; ok {
registerTrustedVar(keys["SSL_PROTOCOL\x00"], v, trackVarsArray, thread)
registerTrustedVar(keys["SSL_PROTOCOL\x00"], v, trackVarsArray)
} else {
registerTrustedVar(keys["SSL_PROTOCOL\x00"], "", trackVarsArray, thread)
registerTrustedVar(keys["SSL_PROTOCOL\x00"], "", trackVarsArray)
}
}
}

registerTrustedVar(keys["REQUEST_SCHEME\x00"], rs, trackVarsArray, thread)
registerTrustedVar(keys["REQUEST_SCHEME\x00"], rs, trackVarsArray)
reqHost, reqPort, _ := net.SplitHostPort(request.Host)

if reqHost == "" {
Expand All @@ -132,27 +133,27 @@ func addKnownVariablesToServer(thread *phpThread, request *http.Request, fc *Fra
}
}

registerTrustedVar(keys["SERVER_NAME\x00"], reqHost, trackVarsArray, thread)
registerTrustedVar(keys["SERVER_NAME\x00"], reqHost, trackVarsArray)
if reqPort != "" {
registerTrustedVar(keys["SERVER_PORT\x00"], reqPort, trackVarsArray, thread)
registerTrustedVar(keys["SERVER_PORT\x00"], reqPort, trackVarsArray)
} else {
registerTrustedVar(keys["SERVER_PORT\x00"], "", trackVarsArray, thread)
registerTrustedVar(keys["SERVER_PORT\x00"], "", trackVarsArray)
}

// Variables defined in CGI 1.1 spec
// Some variables are unused but cleared explicitly to prevent
// the parent environment from interfering.

// These values can not be overridden
registerTrustedVar(keys["CONTENT_LENGTH\x00"], request.Header.Get("Content-Length"), trackVarsArray, thread)
registerTrustedVar(keys["GATEWAY_INTERFACE\x00"], "CGI/1.1", trackVarsArray, thread)
registerTrustedVar(keys["SERVER_PROTOCOL\x00"], request.Proto, trackVarsArray, thread)
registerTrustedVar(keys["SERVER_SOFTWARE\x00"], "FrankenPHP", trackVarsArray, thread)
registerTrustedVar(keys["HTTP_HOST\x00"], request.Host, trackVarsArray, thread) // added here, since not always part of headers
registerTrustedVar(keys["CONTENT_LENGTH\x00"], request.Header.Get("Content-Length"), trackVarsArray)
registerTrustedVar(keys["GATEWAY_INTERFACE\x00"], "CGI/1.1", trackVarsArray)
registerTrustedVar(keys["SERVER_PROTOCOL\x00"], request.Proto, trackVarsArray)
registerTrustedVar(keys["SERVER_SOFTWARE\x00"], "FrankenPHP", trackVarsArray)
registerTrustedVar(keys["HTTP_HOST\x00"], request.Host, trackVarsArray) // added here, since not always part of headers

// These values are always empty but must be defined:
registerTrustedVar(keys["AUTH_TYPE\x00"], "", trackVarsArray, thread)
registerTrustedVar(keys["REMOTE_IDENT\x00"], "", trackVarsArray, thread)
registerTrustedVar(keys["AUTH_TYPE\x00"], "", trackVarsArray)
registerTrustedVar(keys["REMOTE_IDENT\x00"], "", trackVarsArray)

// These values are already present in the SG(request_info), so we'll register them from there
C.frankenphp_register_variables_from_request_info(
Expand All @@ -166,11 +167,11 @@ func addKnownVariablesToServer(thread *phpThread, request *http.Request, fc *Fra
)
}

func registerTrustedVar(key *C.zend_string, value string, trackVarsArray *C.zval, thread *phpThread) {
C.frankenphp_register_trusted_var(key, thread.pinString(value), C.int(len(value)), trackVarsArray)
func registerTrustedVar(key *C.zend_string, value string, trackVarsArray *C.zval) {
C.frankenphp_register_trusted_var(key, toUnsafeChar(value), C.int(len(value)), trackVarsArray)
}

func addHeadersToServer(thread *phpThread, request *http.Request, fc *FrankenPHPContext, trackVarsArray *C.zval) {
func addHeadersToServer(request *http.Request, fc *FrankenPHPContext, trackVarsArray *C.zval) {
for field, val := range request.Header {
k, ok := headerKeyCache.Get(field)
if !ok {
Expand All @@ -183,13 +184,13 @@ func addHeadersToServer(thread *phpThread, request *http.Request, fc *FrankenPHP
}

v := strings.Join(val, ", ")
C.frankenphp_register_variable_safe(thread.pinString(k), thread.pinString(v), C.size_t(len(v)), trackVarsArray)
C.frankenphp_register_variable_safe(toUnsafeChar(k), toUnsafeChar(v), C.size_t(len(v)), trackVarsArray)
}
}

func addPreparedEnvToServer(thread *phpThread, fc *FrankenPHPContext, trackVarsArray *C.zval) {
func addPreparedEnvToServer(fc *FrankenPHPContext, trackVarsArray *C.zval) {
for k, v := range fc.env {
C.frankenphp_register_variable_safe(thread.pinString(k), thread.pinString(v), C.size_t(len(v)), trackVarsArray)
C.frankenphp_register_variable_safe(toUnsafeChar(k), toUnsafeChar(v), C.size_t(len(v)), trackVarsArray)
}
fc.env = nil
}
Expand All @@ -201,7 +202,7 @@ func getKnownVariableKeys(thread *phpThread) map[string]*C.zend_string {
threadServerKeys := make(map[string]*C.zend_string)
for k := range knownServerKeys {
keyWithoutNull := strings.Replace(k, "\x00", "", -1)
threadServerKeys[k] = C.frankenphp_init_persistent_string(thread.pinString(keyWithoutNull), C.size_t(len(keyWithoutNull)))
threadServerKeys[k] = C.frankenphp_init_persistent_string(toUnsafeChar(keyWithoutNull), C.size_t(len(keyWithoutNull)))
}
thread.knownVariableKeys = threadServerKeys
return threadServerKeys
Expand All @@ -214,8 +215,8 @@ func go_register_variables(threadIndex C.uintptr_t, trackVarsArray *C.zval) {
fc := r.Context().Value(contextKey).(*FrankenPHPContext)

addKnownVariablesToServer(thread, r, fc, trackVarsArray)
addHeadersToServer(thread, r, fc, trackVarsArray)
addPreparedEnvToServer(thread, fc, trackVarsArray)
addHeadersToServer(r, fc, trackVarsArray)
addPreparedEnvToServer(fc, trackVarsArray)
}

//export go_frankenphp_release_known_variable_keys
Expand Down Expand Up @@ -289,3 +290,8 @@ func sanitizedPathJoin(root, reqPath string) string {
}

const separator = string(filepath.Separator)

func toUnsafeChar(s string) *C.char {
sData := unsafe.StringData(s)
return (*C.char)(unsafe.Pointer(sData))
}

0 comments on commit 045ce00

Please sign in to comment.