diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm index 3cf4d0c5c..15c2f0901 100755 --- a/fhem/FHEM/01_FHEMWEB.pm +++ b/fhem/FHEM/01_FHEMWEB.pm @@ -77,6 +77,7 @@ use vars qw(@FW_fhemwebjs);# List of fhemweb*js scripts to load my $FW_zlib_checked; my $FW_use_zlib = 1; my $FW_activateInform = 0; +my $FW_formmethod = "post"; ######################### # As we are _not_ multithreaded, it is safe to use global variables. @@ -243,10 +244,19 @@ FW_Read($) } $hash->{BUF} .= $buf; - return if($hash->{BUF} !~ m/\n\n$/ && $hash->{BUF} !~ m/\r\n\r\n$/); - - @FW_httpheader = split("[\r\n]", $hash->{BUF}); - + if(!$hash->{HDR}) { + return if($hash->{BUF} !~ m/^(.*)(\n\n|\r\n\r\n)(.*)$/s); + $hash->{HDR} = $1; + $hash->{BUF} = $3; + if($hash->{HDR} =~ m/Content-Length: ([^\r\n]*)/s) { + $hash->{CONTENT_LENGTH} = $1; + } + } + return if($hash->{CONTENT_LENGTH} && + length($hash->{BUF})<$hash->{CONTENT_LENGTH}); + + @FW_httpheader = split("[\r\n]", $hash->{HDR}); + delete($hash->{HDR}); my @origin = grep /Origin/, @FW_httpheader; $FW_headercors = (AttrVal($FW_wname, "CORS", 0) ? @@ -262,8 +272,9 @@ FW_Read($) my $basicAuth = AttrVal($FW_wname, "basicAuth", undef); my @headerOptions = grep /OPTIONS/, @FW_httpheader; if($basicAuth) { - $hash->{BUF} =~ m/Authorization: Basic ([^\r\n]*)/s; - my $secret = $1; + my @authLine = grep /Authorization: Basic/, @FW_httpheader; + my $secret = $authLine[0]; + $secret =~ s/^Authorization: Basic // if($secret); my $pwok = ($secret && $secret eq $basicAuth); if($secret && $basicAuth =~ m/^{.*}$/ || $headerOptions[0]) { eval "use MIME::Base64"; @@ -280,7 +291,8 @@ FW_Read($) print $c "HTTP/1.1 200 OK\r\n", $FW_headercors, "Content-Length: 0\r\n\r\n"; - $hash->{BUF}=""; + delete $hash->{CONTENT_LENGTH}; + delete $hash->{BUF}; return; exit(1); }; @@ -290,7 +302,8 @@ FW_Read($) "WWW-Authenticate: Basic realm=\"$msg\"\r\n", $FW_headercors, "Content-Length: 0\r\n\r\n"; - $hash->{BUF}=""; + delete $hash->{CONTENT_LENGTH}; + delete $hash->{BUF}; return; }; } @@ -298,8 +311,10 @@ FW_Read($) my $now = time(); @FW_enc = grep /Accept-Encoding/, @FW_httpheader; - my ($mode, $arg, $method) = split(" ", $FW_httpheader[0]); - $hash->{BUF} = ""; + my ($method, $arg, $httpvers) = split(" ", $FW_httpheader[0], 3); + $arg .= "&".$hash->{BUF} if($hash->{CONTENT_LENGTH}); + delete $hash->{CONTENT_LENGTH}; + delete $hash->{BUF}; $hash->{LASTACCESS} = $now; $arg = "" if(!defined($arg)); @@ -480,7 +495,8 @@ FW_answerCall($) $FW_cmdret = $docmd ? FW_fC($cmd, $cmddev) : ""; # Redirect after a command, to clean the browser URL window - if($docmd && !$FW_cmdret && AttrVal($FW_wname, "redirectCmds", 1)) { + if($docmd && !$FW_cmdret && $FW_formmethod eq "get" && + AttrVal($FW_wname, "redirectCmds", 1)) { my $tgt = $FW_ME; if($FW_detail) { $tgt .= "?detail=$FW_detail" } elsif($FW_room) { $tgt .= "?room=$FW_room" } @@ -621,6 +637,7 @@ FW_digestCgi($) #Remove (nongreedy) everything including the first '?' $arg =~ s,^.*?[?],,; foreach my $pv (split("&", $arg)) { + next if($pv eq ""); # happens when post forgot to set FW_ME $pv =~ s/\+/ /g; $pv =~ s/%([\dA-F][\dA-F])/chr(hex($1))/ige; my ($p,$v) = split("=",$pv, 2); @@ -776,7 +793,7 @@ FW_makeSelect($$$$) $selEl = $1 if($list =~ m/([^ ]*):slider,/); # promote a slider if available $selEl = "room" if($list =~ m/room:/); - FW_pO "