Index: openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl,v diff -u -r1.44 -r1.45 --- openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl 14 Feb 2013 18:28:16 -0000 1.44 +++ openacs-4/packages/xotcl-core/tcl/bgdelivery-procs.tcl 17 Feb 2013 11:48:06 -0000 1.45 @@ -296,7 +296,7 @@ if {[catch { if {[$s mode] eq "scripted"} { set smsg "chunk\n" + parent.getData(data);\n" set smsg [format %x [string length $smsg]]\r\n$smsg\r\n } else { set smsg $msg @@ -330,7 +330,11 @@ set body "
[string repeat { } 1024]\r\n" set body [format %x [string length $body]]\r\n$body\r\n } else { - set content_type text/plain + #set content_type text/plain + # Chrome refuses to expose partial response to ajax unless we + # set content_type to octet stream. Drawback is we now need to + # treat special characters on the client side. + set content_type "application/octet-stream" set encoding "" set body "" } @@ -504,11 +508,8 @@ if {$::xo::naviserver && !$use_writerThread} { ns_conn keepalive 0 } - set range [ns_set iget [ns_conn headers] range] - if {$range ne ""} { - ns_log notice "Range: '$range' (raw header field)" - } + set range [ns_set iget [ns_conn headers] range] if {[regexp {bytes=(.*)$} $range _ range]} { set ranges [list] set bytes 0 @@ -539,10 +540,13 @@ # For the time being, we write the headers in a simplified version # directly in the spooling thread to avoid the overhead of double # h264opens. + # if {!$use_h264} { + # + # Add content-range header for range requests. + # if {[llength $ranges] == 1 && $status_code == 200} { - set first_range [lindex $ranges 0] - foreach {from to .} $first_range break + lassign [lindex $ranges 0] from to ns_set put [ns_conn outputheaders] Content-Range "bytes $from-$to/$size" ns_log notice "added header-field Content-Range: bytes $from-$to/$size // $ranges" set status_code 206 Index: openacs-4/packages/xowiki/tcl/chat-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/chat-procs.tcl,v diff -u -r1.15 -r1.16 --- openacs-4/packages/xowiki/tcl/chat-procs.tcl 13 Sep 2012 16:05:26 -0000 1.15 +++ openacs-4/packages/xowiki/tcl/chat-procs.tcl 17 Feb 2013 11:48:06 -0000 1.16 @@ -34,37 +34,70 @@ Chat proc initialize_nsvs {} {;} ;# noop Chat proc login {-chat_id -package_id -mode} { - my log "--" + #my log "--chat" auth::require_login if {![info exists package_id]} {set package_id [ad_conn package_id] } if {![info exists chat_id]} {set chat_id $package_id } set context id=$chat_id&s=[ad_conn session_id].[clock seconds] set path [lindex [site_node::get_url_from_object_id -object_id $package_id] 0] if {![info exists mode]} { + # + # The parameter "mode" was not specified, we try to guess the + # "best" mode known to work for the currently used browser. + # + # The most conservative mode is + # - "polling" (which requires for every connected client polling + # requests), followed by + # - "scripted-streaming" (which opens and "infinitely long" HTML + # files with embedded script tags; very portable, but this + # causes the loading indicator to spin), followed by + # - "streaming" (true streaming, but this requires + # an HTTP stack supporting partial reads). + # + # NOTICE 1: The guessing is based on current versions of the + # browsers. Older versions of the browser might behave + # differently. + # + # NOTICE 2: "streaming" (and to a lesser extend + # "scripted-streaming" - which used chunked encoding) might be + # influenced by the buffering behavior of a reverse proxy, which + # might have to be configured appropriately. + # + # To be independet of the guessing mode, instantiate the chat + # object with "mode" specified. + # set mode polling + # + # Check, whether we have the tcllibthread and a sufficiently new + # aolserver/naviserver supporting bgdelivery transfers. + # if {[info command ::thread::mutex] ne "" && ![catch {ns_conn contentsentlength}]} { - # we seem to have libthread installed, and the patch for obtaining the tcl-stream - # from a connection thread, so we can use the background delivery thread; + # # scripted streaming should work everywhere + # set mode scripted-streaming - if {[regexp (firefox) [string tolower [ns_set get [ns_conn headers] User-Agent]]]} { - # for firefox, we could use the nice mode without the spinning load indicator - # currently, streaming mode seems broken with current firefox... - #set mode streaming - } + if {![regexp msie|opera [string tolower [ns_set get [ns_conn headers] User-Agent]]]} { + # Explorer doesn't expose partial response until request state != 4, while Opera fires + # onreadystateevent only once. For this reason, for every broser except them, we could + # use the nice mode without the spinning load indicator. + # + set mode streaming + } } my log "--chat mode $mode" } + # small javascript library to obtain a portable ajax request object + ::xo::Page requireJS "/resources/xowiki/get-http-object.js" + switch $mode { polling { - ::xo::Page requireJS "/resources/xowiki/get-http-object.js" set jspath packages/xowiki/www/ajax/chat.js - set login_url ${path}ajax/chat?m=login&$context - set get_update "chatSendCmd(\"$path/ajax/chat?m=get_new&$context\",chatReceiver)" - set get_all "chatSendCmd(\"$path/ajax/chat?m=get_all&$context\",chatReceiver)" + set login_url ${path}ajax/chat?m=login&$context + set get_update "chatSendCmd(\"$path/ajax/chat?m=get_new&$context\",chatReceiver)" + set get_all "chatSendCmd(\"$path/ajax/chat?m=get_all&$context\",chatReceiver)" } streaming { set jspath packages/xowiki/www/ajax/streaming-chat.js @@ -117,7 +150,8 @@ overflow:auto; '> " } Index: openacs-4/packages/xowiki/www/ajax/chat.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/chat.js,v diff -u -r1.6 -r1.7 --- openacs-4/packages/xowiki/www/ajax/chat.js 13 Sep 2012 16:05:33 -0000 1.6 +++ openacs-4/packages/xowiki/www/ajax/chat.js 17 Feb 2013 11:48:06 -0000 1.7 @@ -2,14 +2,7 @@ // $Id$ // -gustaf neumann April 2006 -function receiver1() { - if (http.readyState == 4) { - // alert('status code =' + http.status); - if (http.status != 200) { - alert('Something wrong in HTTP request, status code = ' + http.status); - } - } -} +var http = getHttpObject(); function chatReceiver() { if (http.readyState == 4) { Index: openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/scripted-streaming-chat.js,v diff -u -r1.3 -r1.4 --- openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js 13 Sep 2012 16:05:34 -0000 1.3 +++ openacs-4/packages/xowiki/www/ajax/scripted-streaming-chat.js 17 Feb 2013 11:48:06 -0000 1.4 @@ -2,25 +2,7 @@ // $Id$ // -gustaf neumann April 2006 -function getHttpObject() { - var http_request = false; - if (window.XMLHttpRequest) { // Mozilla, Safari,... - http_request = new XMLHttpRequest(); - } else if (window.ActiveXObject) { // IE - try { - http_request = new ActiveXObject('Msxml2.XMLHTTP'); - } catch (e) { - try { - http_request = new ActiveXObject('Microsoft.XMLHTTP'); - } catch (e) {} - } - } - - if (!http_request) { - alert('Cannot create and instance of XMLHTTP'); - } - return http_request; -} +var http_send = getHttpObject(); function getData(data) { var messages = document.getElementById('messages'); @@ -38,7 +20,7 @@ p.appendChild(span); span = document.createElement('span'); - span.innerHTML = data.messages[i].msg; + span.innerHTML = decodeURI(unescape(data.messages[i].msg)); span.className = 'message'; p.appendChild(span); @@ -47,15 +29,10 @@ } } -var http_send = getHttpObject(); - function chatSendMsg() { var msg = document.getElementById('chatMsg').value; - if (msg == '') { - return; - } - //alert(send_url + encodeURIComponent(msg)); - http_send.open('GET', send_url + encodeURIComponent(msg), true); + if (msg == '') { return; } + http_send.open('GET', send_url + encodeURIComponent(escape(msg)), true); http_send.onreadystatechange = function() { if (http_send.readyState == 4) { if (http_send.status != 200) { @@ -65,9 +42,4 @@ }; http_send.send(null); document.getElementById('chatMsg').value = ''; -} - -function tell(msg) { - document.monitor.window.value = msg; -} - +} \ No newline at end of file Index: openacs-4/packages/xowiki/www/ajax/streaming-chat.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/ajax/Attic/streaming-chat.js,v diff -u -r1.6 -r1.7 --- openacs-4/packages/xowiki/www/ajax/streaming-chat.js 13 Sep 2012 16:05:34 -0000 1.6 +++ openacs-4/packages/xowiki/www/ajax/streaming-chat.js 17 Feb 2013 11:48:06 -0000 1.7 @@ -2,30 +2,13 @@ // $Id$ // -gustaf neumann April 2006 -function getHttpObject() { - var http_request = false; - if (window.XMLHttpRequest) { // Mozilla, Safari,... - http_request = new XMLHttpRequest(); - } else if (window.ActiveXObject) { // IE - try { - http_request = new ActiveXObject('Msxml2.XMLHTTP'); - } catch (e) { - try { - http_request = new ActiveXObject('Microsoft.XMLHTTP'); - } catch (e) {} - } - } - - if (!http_request) { - alert('Cannot create and instance of XMLHTTP'); - } - return http_request; -} +var http = getHttpObject(); +var http_last = 0; +var http_send = getHttpObject(); function getData() { //alert('access responseText'); // hmm, IE does not allow us to access responstext in state == 3 :( var response = http.responseText.substring(http_last); - //alert('access responseText done'); // we recognize a complete message by a trailing }\n if (response.match(/\}[\n ]+$/)) { var messages = document.getElementById('messages'); @@ -44,7 +27,7 @@ p.appendChild(span); span = document.createElement('span'); - span.innerHTML = data.messages[i].msg; + span.innerHTML = decodeURI(unescape(data.messages[i].msg)); span.className = 'message'; p.appendChild(span); @@ -55,17 +38,12 @@ } } -var http = getHttpObject(); -var http_last = 0; -var http_send = getHttpObject(); - function chatSendMsg() { var msg = document.getElementById('chatMsg').value; if (msg == '') { return; } - //alert(send_url + encodeURIComponent(msg)); - http_send.open('GET', send_url + encodeURIComponent(msg), true); + http_send.open('GET', send_url + encodeURIComponent(escape(msg)), true); http_send.onreadystatechange = function() { if (http_send.readyState == 4) { if (http_send.status != 200) { @@ -84,18 +62,15 @@ getData(); } else if (http.readyState == 4) { // alert('status code =' + http.status); - if (http.status == 200) { + var status = http.status; + if (status == 200 || status == 0) { document.getElementById('chatMsg').value = 'logout'; chatSendMsg(); } else { - alert('Something wrong in HTTP request, status code = ' + http.status); + alert('Something wrong in HTTP request, status code = ' + status); } } }; http.send(null); http_last = 0; -} -function tell(msg) { - document.monitor.window.value = msg; -} - +} \ No newline at end of file