Comments 10
Из своего админского опыта:

Есть вот такие переменные:
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param SERVER_PORT $server_port;


И обычно всё работает.
Сложности возникают, если используется reverse proxy, в котором обслуживается HTTPS спереди того nginx в котором хостится сам сайт.
Например у меня было несколько сайтов, — каждый в своём Докер-контейнере по HTTP. А в Интернет это публиковалось с помощью прокси jwilder/nginx-proxy + letsencrypt-nginx-proxy-companion

Угадайте, что будет в fastcgi_param HTTPS? И в fastcgi_param SERVER_PORT?
Там будет HTTP и порт 80.
И Wordpress будет вам отдавать кривые redirect ссылки что-то типа HTTPS://web.site:80.

Я это решал тем, что прописывал порт прямо в конфиге, и убирая fastcgi_param HTTPS:

#fastcgi_param HTTPS $https if_not_empty;
fastcgi_param SERVER_PORT 443;

(X-)Forwarded-Proto и т. п. обычно решают это.


А вообще мощный механизм fascgi_param в этом плане, хоть разные параметры подключения к Бд передавай в зависимости от разных факторов из запроса

Посмотрел из интереса её реализацию
php-7.4.12/sapi/cgi/cgi_main.c
PHP_FUNCTION(apache_request_headers) /* {{{ */
{
	if (zend_parse_parameters_none()) {
		return;
	}
	array_init(return_value);
	if (fcgi_is_fastcgi()) {
		fcgi_request *request = (fcgi_request*) SG(server_context);

		fcgi_loadenv(request, sapi_add_request_header, return_value);
	} else {
		char buf[128];
		char **env, *p, *q, *var, *val, *t = buf;
		size_t alloc_size = sizeof(buf);
		zend_ulong var_len;

		for (env = environ; env != NULL && *env != NULL; env++) {
			val = strchr(*env, '=');
			if (!val) {				/* malformed entry? */
				continue;
			}
			var_len = val - *env;
			if (var_len >= alloc_size) {
				alloc_size = var_len + 64;
				t = (t == buf ? emalloc(alloc_size): erealloc(t, alloc_size));
			}
			var = *env;
			if (var_len > 5 &&
			    var[0] == 'H' &&
			    var[1] == 'T' &&
			    var[2] == 'T' &&
			    var[3] == 'P' &&
			    var[4] == '_') {

				var_len -= 5;

				if (var_len >= alloc_size) {
					alloc_size = var_len + 64;
					t = (t == buf ? emalloc(alloc_size): erealloc(t, alloc_size));
				}
				p = var + 5;

				var = q = t;
				/* First char keep uppercase */
				*q++ = *p++;
				while (*p) {
					if (*p == '=') {
						/* End of name */
						break;
					} else if (*p == '_') {
						*q++ = '-';
						p++;
						/* First char after - keep uppercase */
						if (*p && *p!='=') {
							*q++ = *p++;
						}
					} else if (*p >= 'A' && *p <= 'Z') {
						/* lowercase */
						*q++ = (*p++ - 'A' + 'a');
					} else {
						*q++ = *p++;
					}
				}
				*q = 0;
			} else if (var_len == sizeof("CONTENT_TYPE")-1 &&
			           memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) {
				var = "Content-Type";
			} else if (var_len == sizeof("CONTENT_LENGTH")-1 &&
			           memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) {
				var = "Content-Length";
			} else {
				continue;
			}
			val++;
			add_assoc_string_ex(return_value, var, var_len, val);
		}
		if (t != buf && t != NULL) {
			efree(t);
		}
	}
}
/* }}} */


Логика как и описано выше: взять заголовки HTTP_* и добавить к ним CONTENT_TYPE/CONTENT_LENGTH. То есть под капотом у всех одно и тоже.

Готовых решений очень много:
Ну а откуда другой реализации взяться? Кроме как из CGI их никак не достать.

Полифилы и прочие пакеты нужны были для древних версий пыха, начиная с 7.3 эта функция идет в стандартной поставке.
Only those users with full accounts are able to leave comments. Log in, please.