From 9fcf5778d74933017c2c99f956b1e113b07a154f Mon Sep 17 00:00:00 2001 From: rudolfkoenig Date: Thu, 24 Apr 2014 10:05:01 +0000 Subject: [PATCH] FHEMWEB/fhem.pl: Fix HTTPS short write for answer > 64k. Forum #22568 git-svn-id: svn://svn.code.sf.net/p/fhem/code/trunk@5625 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/01_FHEMWEB.pm | 31 +++++++++++++++++++------------ fhem/fhem.pl | 29 ++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm index 14dcf5c45..6cca4ba82 100755 --- a/fhem/FHEM/01_FHEMWEB.pm +++ b/fhem/FHEM/01_FHEMWEB.pm @@ -69,9 +69,9 @@ use vars qw($FW_plotmode);# Global plot mode (WEB attribute), used by SVG use vars qw($FW_plotsize);# Global plot size (WEB attribute), used by SVG use vars qw(%FW_webArgs); # all arguments specified in the GET use vars qw(@FW_fhemwebjs);# List of fhemweb*js scripts to load -use vars qw($FW_detail); # currently selected device for detail view -use vars qw($FW_cmdret); # Returned data by the fhem call -use vars qw($FW_room); # currently selected room +use vars qw($FW_detail); # currently selected device for detail view +use vars qw($FW_cmdret); # Returned data by the fhem call +use vars qw($FW_room); # currently selected room use vars qw($FW_formmethod); use vars qw(%FW_visibleDeviceHash); @@ -380,19 +380,25 @@ FW_Read($) my $expires = ($cacheable? ("Expires: ".localtime($now+900)." GMT\r\n") : ""); Log3 $FW_wname, 4, "$arg / RL:$length / $FW_RETTYPE / $compressed / $expires"; - print $c "HTTP/1.1 200 OK\r\n", - "Content-Length: $length\r\n", - $expires, $compressed, $FW_headercors, - "Content-Type: $FW_RETTYPE\r\n\r\n", - $FW_RET; + $hash->{pid} = $pid if(defined($pid)); + addToWritebuffer($hash, + "HTTP/1.1 200 OK\r\n" . + "Content-Length: $length\r\n" . + $expires . $compressed . $FW_headercors . + "Content-Type: $FW_RETTYPE\r\n\r\n" . + $FW_RET, "FW_closeConn"); +} +sub +FW_closeConn($) +{ + my ($hash) = @_; # Needed for slow server+iPad/iPhone. Forum #20294 - if(AttrVal($FW_wname, "closeConn", undef)) { + if(AttrVal($hash->{SNAME}, "closeConn", undef)) { TcpServer_Close($hash); delete($defs{$hash->{NAME}}); } - - exit if(defined($pid)); + exit if(defined($hash->{pid})); } ########################### @@ -926,7 +932,8 @@ FW_doDetail($) FW_makeTable("Readings", $d, $h->{READINGS}); my $attrList = getAllAttr($d); - my $roomList = "multiple,".join(",", sort map { $_ =~ s/ /#/g ;$_} keys %FW_rooms); + my $roomList = "multiple,".join(",", + sort map { $_ =~ s/ /#/g ;$_} keys %FW_rooms); $attrList =~ s/room /room:$roomList /; FW_makeSelect($d, "attr", $attrList,"attr"); diff --git a/fhem/fhem.pl b/fhem/fhem.pl index 3a03cd2cd..526e46b53 100755 --- a/fhem/fhem.pl +++ b/fhem/fhem.pl @@ -90,7 +90,7 @@ sub WriteStatefile(); sub XmlEscape($); sub addEvent($$); sub addToAttrList($); -sub addToWritebuffer($$); +sub addToWritebuffer($$@); sub attrSplit($); sub computeClientArray($$); sub concatc($$$); @@ -600,10 +600,17 @@ while (1) { my $ret = syswrite($hash->{CD}, $wb); if(!$ret || $ret < 0) { Log 4, "Write error to $p, deleting $hash->{NAME}"; + TcpServer_Close($hash); CommandDelete(undef, $hash->{NAME}); } else { if($ret == length($wb)) { delete($hash->{$wbName}); + if($hash->{WBCallback}) { + no strict "refs"; + my $ret = &{$hash->{WBCallback}}($hash); + use strict "refs"; + delete $hash->{WBCallback}; + } } else { $hash->{$wbName} = substr($wb, $ret); } @@ -3827,10 +3834,26 @@ Debug($) { } sub -addToWritebuffer($$) +addToWritebuffer($$@) { - my ($hash, $txt) = @_; + my ($hash, $txt, $callback) = @_; + if(defined($hash->{pid})) { # Wont go to the main select in a forked process + my ($off, $len) = (0, length($txt)); + while($off < $len) { + my $ret = syswrite($hash->{CD}, $txt, $len-$off, $off); + last if(!$ret || $ret <= 0); + $off += $ret; + } + if($callback) { + no strict "refs"; + my $ret = &{$callback}($hash); + use strict "refs"; + } + return; + } + + $hash->{WBCallback} = $callback; if(!$hash->{$wbName}) { $hash->{$wbName} = $txt; } elsif(length($hash->{$wbName}) < 102400) {