diff --git a/config/httpd.conf.template b/config/httpd.conf.template index c0eddb9..f407124 100644 --- a/config/httpd.conf.template +++ b/config/httpd.conf.template @@ -1,9 +1,15 @@ Define SRVROOT "{{SRVROOT}}" +ServerRoot "${SRVROOT}" Listen {{LISTEN_ADDRESS}}:{{PORT}} +# Temel Modüller LoadModule authz_core_module modules/mod_authz_core.so LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authn_file_module modules/mod_authn_file.so LoadModule dir_module modules/mod_dir.so LoadModule mime_module modules/mod_mime.so LoadModule alias_module modules/mod_alias.so @@ -11,6 +17,17 @@ LoadModule log_config_module modules/mod_log_config.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so +LoadModule autoindex_module modules/mod_autoindex.so +LoadModule negotiation_module modules/mod_negotiation.so +LoadModule setenvif_module modules/mod_setenvif.so +# Önerilen Ek Modüller +LoadModule headers_module modules/mod_headers.so +LoadModule env_module modules/mod_env.so +LoadModule deflate_module modules/mod_deflate.so + +# Windows optimizations +AcceptFilter http none +AcceptFilter https none # Required for PHP-FPM on Windows to avoid "No input file specified" @@ -20,6 +37,15 @@ LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so ServerAdmin admin@localhost ServerName localhost:{{PORT}} +# MIME Types (Kritik) +TypesConfig conf/mime.types + +# Ana Güvenlik Kuralı (Tüm disk erişimini kapat) + + AllowOverride none + Require all denied + + DocumentRoot "{{ROOT}}" Options Indexes FollowSymLinks @@ -58,6 +84,7 @@ Alias /phpmyadmin "{{PHPMYADMIN_DIR}}" # Global PHP handler SetHandler "proxy:fcgi://127.0.0.1:{{PHP_PORT}}/" + CGIPassAuth On # Project configurations diff --git a/config/php.ini.template b/config/php.ini.template index c735f02..c3be093 100644 --- a/config/php.ini.template +++ b/config/php.ini.template @@ -45,6 +45,8 @@ session.save_path = "{{SESSION_DIR}}" upload_tmp_dir = "{{TEMP_DIR}}" sys_temp_dir = "{{TEMP_DIR}}" extension_dir = "{{EXT_DIR}}" +cgi.force_redirect = 0 +cgi.fix_pathinfo = 1 [ExtensionList] {{EXTENSIONS}} diff --git a/settings.json b/settings.json index c034736..c2f19d3 100644 --- a/settings.json +++ b/settings.json @@ -5,7 +5,7 @@ "phpPort": "9001", "mariaDbPort": "3306", "mariaDbPorts": {}, - "allowRemoteAccess": true, + "allowRemoteAccess": false, "language": "tr", "mysqlPort": "3306", "mysqlPorts": {} diff --git a/src/main/ipc/index.ts b/src/main/ipc/index.ts index facfc9b..eda60d3 100644 --- a/src/main/ipc/index.ts +++ b/src/main/ipc/index.ts @@ -161,12 +161,13 @@ async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ bi const configPath = path.join(configService.getBasePath(), 'generated_configs', 'httpd.conf') - // Check if manual edit exists + // Check if manual edit exists for global config + let skipGlobal = false if (fs.existsSync(configPath) && !forceProjects) { const content = fs.readFileSync(configPath, 'utf8') if (content.includes('# MANUAL_EDIT')) { - console.log('Skipping Apache config generation (Manual Edit detected)') - return { binPath, apacheDir, configPath } + console.log('Skipping Apache global config generation (Manual Edit detected)') + skipGlobal = true } } @@ -181,6 +182,14 @@ async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ bi const projectConfPath = path.join(projectsConfDir, `${p.host}.conf`) let shouldGenerate = forceProjects || !fs.existsSync(projectConfPath) + // If file exists, check if it was manually edited (though we don't have a UI for this yet, good for future) + if (!shouldGenerate && fs.existsSync(projectConfPath)) { + const currentContent = fs.readFileSync(projectConfPath, 'utf8') + if (!currentContent.includes('# MANUAL_EDIT')) { + shouldGenerate = true + } + } + if (shouldGenerate) { const phpPort = portMappingService.getPhpPort(p.phpVersion) let normalizedPath = p.path.replace(/\\/g, '/') @@ -194,20 +203,22 @@ async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ bi } } - const projectsInclusion = projects.length > 0 - ? `Include "${projectsConfDir.replace(/\\/g, '/')}/*.conf"` - : '' + if (!skipGlobal) { + const projectsInclusion = projects.length > 0 + ? `Include "${projectsConfDir.replace(/\\/g, '/')}/*.conf"` + : '' - await configService.generateConfig('httpd.conf.template', 'httpd.conf', { - PORT: settings.apachePort || '8080', - LISTEN_ADDRESS: settings.allowRemoteAccess ? '0.0.0.0' : '127.0.0.1', - PHP_PORT: settings.phpPort, - ROOT: rootPath.replace(/\\/g, '/'), - SRVROOT: apacheRoot.replace(/\\/g, '/'), - LOG_DIR: logDir.replace(/\\/g, '/'), - PHPMYADMIN_DIR: phpMyAdminService.getPath().replace(/\\/g, '/'), - PROJECTS: projectsInclusion - }) + await configService.generateConfig('httpd.conf.template', 'httpd.conf', { + PORT: settings.apachePort || '8080', + LISTEN_ADDRESS: settings.allowRemoteAccess ? '0.0.0.0' : '127.0.0.1', + PHP_PORT: settings.phpPort, + ROOT: rootPath.replace(/\\/g, '/'), + SRVROOT: apacheRoot.replace(/\\/g, '/'), + LOG_DIR: logDir.replace(/\\/g, '/'), + PHPMYADMIN_DIR: phpMyAdminService.getPath().replace(/\\/g, '/'), + PROJECTS: projectsInclusion + }) + } return { binPath, apacheDir, configPath } } diff --git a/src/main/services/PhpManagerService.ts b/src/main/services/PhpManagerService.ts index 1500f97..a5eca3c 100644 --- a/src/main/services/PhpManagerService.ts +++ b/src/main/services/PhpManagerService.ts @@ -259,8 +259,40 @@ export class PhpManagerService { } fs.writeFileSync(iniPath, finalLines.join('\n'), 'utf8') + await this.ensureFcgiSettings(version) return { success: true, message: `Extension ${extName} ${enabled ? 'enabled' : 'disabled'}` } } + + async ensureFcgiSettings(version: string): Promise { + const phpDir = path.join(this.binDir, `php-${version}`) + const iniPath = path.join(phpDir, 'php.ini') + if (!fs.existsSync(iniPath)) return false + + let content = fs.readFileSync(iniPath, 'utf8') + const lines = content.split(/\r?\n/) + + let forceRedirectSet = false + let fixPathinfoSet = false + + const newLines = lines.map(line => { + const trimmed = line.trim() + if (trimmed.startsWith('cgi.force_redirect') || trimmed.startsWith(';cgi.force_redirect')) { + forceRedirectSet = true + return 'cgi.force_redirect = 0' + } + if (trimmed.startsWith('cgi.fix_pathinfo') || trimmed.startsWith(';cgi.fix_pathinfo')) { + fixPathinfoSet = true + return 'cgi.fix_pathinfo = 1' + } + return line + }) + + if (!forceRedirectSet) newLines.push('cgi.force_redirect = 0') + if (!fixPathinfoSet) newLines.push('cgi.fix_pathinfo = 1') + + fs.writeFileSync(iniPath, newLines.join('\n'), 'utf8') + return true + } } export const phpManagerService = new PhpManagerService()