1

I am running PHP 7.2 fpm with lighttpd/1.4.53 on Raspbian. My goal is to upload image files through HTTP POST - But whatever I post to the script, the $_POST, $_FILES, $_REQUEST superglobals are just empty arrays. $_SERVER, however, returns a properly filled array. So is $_GET if any parameters are added to the URL.

This is what I use for testing:

<?php
$outhandle = fopen("logfile.txt", "a");
fputs($outhandle, print_r($_FILES, true) . "\n");
fputs($outhandle, print_r($_REQUEST, true) . "\n");
fputs($outhandle, print_r($_GET, true) . "\n");
fputs($outhandle, print_r($_POST, true) . "\n");
fputs($outhandle, print_r($_SERVER, true) . "\n");

and this is the result:

Array
(
)
Array
(
)
Array
(
)
Array
(
)
Array
(
    [USER] => www-data
    [HOME] => /var/www
    [CONTENT_TYPE] => image/jpeg
    [HTTP_CONTENT_LENGTH] => 2879609
    [HTTP_CONNECTION] => keep-alive
    [HTTP_ACCEPT_ENCODING] => gzip, deflate, br
    [HTTP_HOST] => 192.168.10.2
    [HTTP_POSTMAN_TOKEN] => dfeea482-03cf-4b87-b088-3e727d9ed537
    [HTTP_ACCEPT] => */*
    [HTTP_USER_AGENT] => PostmanRuntime/7.26.1
    [REMOTE_PORT] => 54820
    [REMOTE_ADDR] => 192.168.10.162
    [SERVER_NAME] => 192.168.10.2
    [SERVER_ADDR] => 192.168.10.2
    [SERVER_PORT] => 80
    [REQUEST_SCHEME] => http
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_SOFTWARE] => lighttpd/1.4.53
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => POST
    [DOCUMENT_ROOT] => /var/www/html
    [SCRIPT_FILENAME] => /var/www/html/upload.php
    [SCRIPT_NAME] => /upload.php
    [REDIRECT_STATUS] => 200
    [REQUEST_URI] => /upload.php
    [QUERY_STRING] =>
    [CONTENT_LENGTH] => 2879609
    [FCGI_ROLE] => RESPONDER
    [PHP_SELF] => /upload.php
    [REQUEST_TIME_FLOAT] => 1593803808.1838
    [REQUEST_TIME] => 1593803808
)

Note that the CONTENT_LENGTH is about 2.8M (also tried much smaller files, same result), this is a POST request I sent through Postman. I have found a few suggestions online, all of them referring to settings in the php.ini file, but none resolved the issue:

upload_max_filesize = 8M
max_file_uploads = 20
request_order = "GP"
variables_order = "GPCS"

I assume there is some kind of misconfiguration, but I have no idea what I missed? Here is the lighttpd config file as well:

server.modules = (
        "mod_indexfile",
        "mod_access",
        "mod_alias",
        "mod_redirect",
)

server.document-root        = "/var/www/html"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 80

# strict parsing and normalization of URL for consistency and security
# https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails
# (might need to explicitly set "url-path-2f-decode" = "disable"
#  if a specific application is encoding URLs inside url-path)
server.http-parseopts = (
  "header-strict"           => "enable",# default
  "host-strict"             => "enable",# default
  "host-normalize"          => "enable",# default
  "url-normalize-unreserved"=> "enable",# recommended highly
  "url-normalize-required"  => "enable",# recommended
  "url-ctrls-reject"        => "enable",# recommended
  "url-path-2f-decode"      => "enable",# recommended highly (unless breaks app)
 #"url-path-2f-reject"      => "enable",
  "url-path-dotseg-remove"  => "enable",# recommended highly (unless breaks app)
 #"url-path-dotseg-reject"  => "enable",
 #"url-query-20-plus"       => "enable",# consistency in query string
)

index-file.names            = ( "index.php", "index.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.conf.pl"
include "/etc/lighttpd/conf-enabled/*.conf"

#server.compat-module-load   = "disable"
server.modules += (
        "mod_compress",
        "mod_dirlisting",
        "mod_staticfile",
)
Aileron79
  • 259
  • 1
  • 7

1 Answers1

0

I realized this is not an issue with lighttpd. In fact, these superglobal variables are only populated when the POST request is submitted through a web form. To get posted files from other request, one has to read the contents from php://input like here:

file_put_contents($path_to_destination_file, file_get_contents('php://input'));

I don't know how this is supposed to work with multiple files though - but this is not a problem I have right now.

Aileron79
  • 259
  • 1
  • 7