[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-1-9' - 93 commits - loleaflet/dist loleaflet/Makefile loleaflet/po loleaflet/README loleaflet/reference.html loleaflet/src loolwsd/ChildSession.cpp loolwsd/ChildSession.hpp loolwsd/ClientSession.cpp loolwsd/ClientSession.hpp loolwsd/configure.ac loolwsd/discovery.xml loolwsd/DocumentBroker.cpp loolwsd/DocumentBroker.hpp loolwsd/.gitignore loolwsd/lint-discovery.py loolwsd/LOOLForKit.cpp loolwsd/LOOLKit.cpp loolwsd/LOOLKit.hpp loolwsd/LOOLProtocol.cpp loolwsd/LOOLProtocol.hpp loolwsd/LOOLSession.hpp loolwsd/LOOLStress.cpp loolwsd/LOOLWSD.cpp loolwsd/MessageQueue.cpp loolwsd/MessageQueue.hpp loolwsd/PrisonerSession.cpp loolwsd/protocol.txt loolwsd/Storage.cpp loolwsd/test loolwsd/TileCache.cpp loolwsd/TileDesc.hpp loolwsd/Unit.cpp loolwsd/UserMessages.hpp loolwsd/Util.cpp loolwsd/Util.hpp
Andras Timar
andras.timar at collabora.com
Tue Oct 11 11:55:20 UTC 2016
loleaflet/Makefile | 2
loleaflet/README | 4
loleaflet/dist/toolbar/toolbar.js | 6
loleaflet/po/help-da.po | 6
loleaflet/po/help-gd.po | 1023 ++++++++++++--------------
loleaflet/po/help-gl.po | 787 +++++++++-----------
loleaflet/po/help-kab.po | 14
loleaflet/po/help-lt.po | 6
loleaflet/po/help-oc.po | 675 ++++++++---------
loleaflet/po/help-ro.po | 10
loleaflet/po/help-ta.po | 833 ++++++++++-----------
loleaflet/po/help-uz.po | 114 +-
loleaflet/po/help-vec.po | 8
loleaflet/po/templates/loleaflet-help.pot | 2
loleaflet/po/templates/loleaflet-ui.pot | 666 ++++++++++------
loleaflet/po/ui-ca.po | 76 -
loleaflet/po/ui-da.po | 64 -
loleaflet/po/ui-fi.po | 68 -
loleaflet/po/ui-gd.po | 149 +--
loleaflet/po/ui-gl.po | 195 +---
loleaflet/po/ui-lt.po | 6
loleaflet/po/ui-nl.po | 16
loleaflet/po/ui-nn.po | 43 -
loleaflet/po/ui-oc.po | 211 +----
loleaflet/po/ui-sk.po | 64 -
loleaflet/po/ui-ta.po | 505 +++++-------
loleaflet/po/ui-th.po | 263 ++----
loleaflet/po/ui-vec.po | 8
loleaflet/reference.html | 21
loleaflet/src/control/Control.ColumnHeader.js | 4
loleaflet/src/control/Control.Menubar.js | 8
loleaflet/src/control/Control.RowHeader.js | 4
loleaflet/src/core/LOUtil.js | 8
loleaflet/src/core/Socket.js | 7
loleaflet/src/layer/tile/TileLayer.js | 109 +-
loleaflet/src/map/Map.js | 19
loolwsd/.gitignore | 1
loolwsd/ChildSession.cpp | 48 -
loolwsd/ChildSession.hpp | 19
loolwsd/ClientSession.cpp | 20
loolwsd/ClientSession.hpp | 16
loolwsd/DocumentBroker.cpp | 114 ++
loolwsd/DocumentBroker.hpp | 23
loolwsd/LOOLForKit.cpp | 12
loolwsd/LOOLKit.cpp | 411 ++++------
loolwsd/LOOLKit.hpp | 3
loolwsd/LOOLProtocol.cpp | 43 -
loolwsd/LOOLProtocol.hpp | 56 +
loolwsd/LOOLSession.hpp | 2
loolwsd/LOOLStress.cpp | 5
loolwsd/LOOLWSD.cpp | 165 ++--
loolwsd/MessageQueue.cpp | 52 +
loolwsd/MessageQueue.hpp | 7
loolwsd/PrisonerSession.cpp | 33
loolwsd/Storage.cpp | 26
loolwsd/TileCache.cpp | 19
loolwsd/TileDesc.hpp | 1
loolwsd/Unit.cpp | 1
loolwsd/UserMessages.hpp | 2
loolwsd/Util.cpp | 2
loolwsd/Util.hpp | 38
loolwsd/configure.ac | 3
loolwsd/discovery.xml | 130 ++-
loolwsd/lint-discovery.py | 246 ++++++
loolwsd/protocol.txt | 51 -
loolwsd/test/Makefile.am | 16
loolwsd/test/TileCacheTests.cpp | 150 ++-
loolwsd/test/TileQueueTests.cpp | 83 +-
loolwsd/test/UnitFonts.cpp | 4
loolwsd/test/UnitPrefork.cpp | 86 +-
loolwsd/test/UnitTileCache.cpp | 13
loolwsd/test/WhiteBoxTests.cpp | 7
loolwsd/test/countloolkits.hpp | 15
loolwsd/test/helpers.hpp | 187 ----
loolwsd/test/httpcrashtest.cpp | 2
loolwsd/test/httpwserror.cpp | 2
loolwsd/test/httpwstest.cpp | 720 ++++++++----------
loolwsd/test/integration-http-server.cpp | 1
loolwsd/test/test.cpp | 1
loolwsd/test/testlokit.cpp | 107 ++
80 files changed, 4645 insertions(+), 4302 deletions(-)
New commits:
commit a66db5303ee4df8481705be03ebfb5e36d1c9363
Author: Andras Timar <andras.timar at collabora.com>
Date: Tue Oct 11 13:54:54 2016 +0200
Bump version to 1.9.4
diff --git a/loleaflet/Makefile b/loleaflet/Makefile
index 487fcb0..0a8cb52 100644
--- a/loleaflet/Makefile
+++ b/loleaflet/Makefile
@@ -3,7 +3,7 @@
# ("micro") part: Between releases odd, even for releases (no other
# changes inbetween).
-VERSION=1.9.3
+VERSION=1.9.4
# Version number of the bundled 'draw' thing
DRAW_VERSION=0.2.4
diff --git a/loolwsd/configure.ac b/loolwsd/configure.ac
index ec27a97..adf548a 100644
--- a/loolwsd/configure.ac
+++ b/loolwsd/configure.ac
@@ -3,7 +3,7 @@
AC_PREREQ([2.69])
-AC_INIT([loolwsd], [1.9.3], [libreoffice at lists.freedesktop.org])
+AC_INIT([loolwsd], [1.9.4], [libreoffice at lists.freedesktop.org])
LT_INIT([shared, disable-static, dlopen])
AM_INIT_AUTOMAKE([1.11 silent-rules subdir-objects])
commit 4676f609dfdc77d1a28edbc261d5ed900caa4014
Author: Andras Timar <andras.timar at collabora.com>
Date: Tue Oct 11 12:13:23 2016 +0200
update pot files
(cherry picked from commit 7ecf78a18e8ea9a7b809a89e2dec748aa64715b5)
diff --git a/loleaflet/po/templates/loleaflet-help.pot b/loleaflet/po/templates/loleaflet-help.pot
index 4226c27..b05eab5 100644
--- a/loleaflet/po/templates/loleaflet-help.pot
+++ b/loleaflet/po/templates/loleaflet-help.pot
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-08-09 07:00+0000\n"
+"POT-Creation-Date: 2016-10-11 12:11+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
diff --git a/loleaflet/po/templates/loleaflet-ui.pot b/loleaflet/po/templates/loleaflet-ui.pot
index a5bb598..307e66f 100644
--- a/loleaflet/po/templates/loleaflet-ui.pot
+++ b/loleaflet/po/templates/loleaflet-ui.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-08-09 07:00+0000\n"
+"POT-Creation-Date: 2016-10-11 12:11+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -17,6 +17,92 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
+#: admin.strings.js:5
+msgid "Admin console"
+msgstr ""
+
+#: admin.strings.js:6
+msgid "Toggle navigation"
+msgstr ""
+
+#: admin.strings.js:7
+msgid "Settings"
+msgstr ""
+
+#: admin.strings.js:8
+msgid "Overview"
+msgstr ""
+
+#: admin.strings.js:9
+msgid "(current)"
+msgstr ""
+
+#: admin.strings.js:10
+msgid "Analytics"
+msgstr ""
+
+#: admin.strings.js:11
+msgid "Dashboard"
+msgstr ""
+
+#: admin.strings.js:12
+msgid "Users online"
+msgstr ""
+
+#: admin.strings.js:13
+msgid "Documents opened"
+msgstr ""
+
+#: admin.strings.js:14
+msgid "Memory consumed"
+msgstr ""
+
+#: admin.strings.js:15
+msgid "PID"
+msgstr ""
+
+#: admin.strings.js:16
+msgid "Document"
+msgstr ""
+
+#: admin.strings.js:17
+msgid "Number of views"
+msgstr ""
+
+#: admin.strings.js:18
+msgid "Elapsed time"
+msgstr ""
+
+#: admin.strings.js:19
+msgid "Kill"
+msgstr ""
+
+#: admin.strings.js:20
+msgid "Graphs"
+msgstr ""
+
+#: admin.strings.js:21 dist/toolbar/toolbar.js:337
+#: src/control/Control.Menubar.js:10 src/control/Control.Menubar.js:63
+#: src/control/Control.Menubar.js:109
+msgid "Save"
+msgstr ""
+
+#: admin.strings.js:22
+msgid "Cache size of memory statistics"
+msgstr ""
+
+#: admin.strings.js:23
+msgid "Time interval of memory statistics (in ms)"
+msgstr ""
+
+#: admin.strings.js:24
+msgid "Cache size of CPU statistics"
+msgstr ""
+
+#: admin.strings.js:25
+msgid "Time interval of CPU statistics (in ms)"
+msgstr ""
+
#: evol.colorpicker.strings.js:2
msgid "Theme Colors"
msgstr ""
@@ -85,6 +171,30 @@ msgstr ""
msgid "Unformatted Text"
msgstr ""
+#: unocommands.js:12
+msgid "No Wrap"
+msgstr ""
+
+#: unocommands.js:13
+msgid "Wrap Before"
+msgstr ""
+
+#: unocommands.js:14
+msgid "Wrap After"
+msgstr ""
+
+#: unocommands.js:15
+msgid "Enable Contour"
+msgstr ""
+
+#: unocommands.js:16
+msgid "Update Index or Table of Contents"
+msgstr ""
+
+#: unocommands.js:17
+msgid "Delete Index or Table of Contents"
+msgstr ""
+
#: dist/errormessages.js:1
msgid ""
"Wrong WOPISrc, usage: WOPISrc=valid encoded URI, or file_path, usage: "
@@ -97,347 +207,387 @@ msgid ""
"contact the administrator."
msgstr ""
-#: dist/toolbar/toolbar.js:154
+#: dist/errormessages.js:3
+msgid ""
+"No disk space left on server, please contact the server administrator to "
+"continue."
+msgstr ""
+
+#: dist/errormessages.js:4
+msgid ""
+"This development build is limited to %0 documents, and %1 connections - to "
+"avoid the impression that it is suitable for deployment in large "
+"enterprises. To find out more about deploying and scaling %2 checkout: <br/"
+"><a href=\"%3\">%3</a>."
+msgstr ""
+
+#: dist/toolbar/toolbar.js:150
msgid "Are you sure you want to delete this page?"
msgstr ""
-#: dist/toolbar/toolbar.js:329 src/admin/AdminStrings.js:20
-#: src/control/Control.Menubar.js:10 src/control/Control.Menubar.js:56
-#: src/control/Control.Menubar.js:102
-msgid "Save"
+#: dist/toolbar/toolbar.js:328
+msgid "Textwrap"
msgstr ""
-#: dist/toolbar/toolbar.js:331 src/control/Control.Menubar.js:18
-#: src/control/Control.Menubar.js:64 src/control/Control.Menubar.js:110
+#: dist/toolbar/toolbar.js:329
+msgid "No wrap"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:330
+msgid "Page wrap"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:331
+msgid "Wrap anchor only"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:332
+msgid "Ideal wrap"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:333
+msgid "Left wrap"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:334
+msgid "Right wrap"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:335
+msgid "Wrap through"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:339 src/control/Control.Menubar.js:19
+#: src/control/Control.Menubar.js:71 src/control/Control.Menubar.js:117
msgid "Undo"
msgstr ""
-#: dist/toolbar/toolbar.js:332 src/control/Control.Menubar.js:19
-#: src/control/Control.Menubar.js:65 src/control/Control.Menubar.js:111
+#: dist/toolbar/toolbar.js:340 src/control/Control.Menubar.js:20
+#: src/control/Control.Menubar.js:72 src/control/Control.Menubar.js:118
msgid "Redo"
msgstr ""
-#: dist/toolbar/toolbar.js:338
+#: dist/toolbar/toolbar.js:341
+msgid "Document repair"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:347
msgid "Bold"
msgstr ""
-#: dist/toolbar/toolbar.js:339
+#: dist/toolbar/toolbar.js:348
msgid "Italic"
msgstr ""
-#: dist/toolbar/toolbar.js:340
+#: dist/toolbar/toolbar.js:349
msgid "Underline"
msgstr ""
-#: dist/toolbar/toolbar.js:341
+#: dist/toolbar/toolbar.js:350
msgid "Strikeout"
msgstr ""
-#: dist/toolbar/toolbar.js:344
+#: dist/toolbar/toolbar.js:352
+msgid "Insert Footnote"
+msgstr ""
+
+#: dist/toolbar/toolbar.js:355
msgid "Font color"
msgstr ""
-#: dist/toolbar/toolbar.js:346
+#: dist/toolbar/toolbar.js:357
msgid "Highlighting"
msgstr ""
-#: dist/toolbar/toolbar.js:348
+#: dist/toolbar/toolbar.js:359
msgid "Align left"
msgstr ""
-#: dist/toolbar/toolbar.js:349
+#: dist/toolbar/toolbar.js:360
msgid "Center horizontally"
msgstr ""
-#: dist/toolbar/toolbar.js:350
+#: dist/toolbar/toolbar.js:361
msgid "Align right"
msgstr ""
-#: dist/toolbar/toolbar.js:351
+#: dist/toolbar/toolbar.js:362
msgid "Justified"
msgstr ""
-#: dist/toolbar/toolbar.js:353
+#: dist/toolbar/toolbar.js:364
msgid "Bullets on/off"
msgstr ""
-#: dist/toolbar/toolbar.js:354
+#: dist/toolbar/toolbar.js:365
msgid "Numbering on/off"
msgstr ""
-#: dist/toolbar/toolbar.js:356
+#: dist/toolbar/toolbar.js:367
msgid "Increase indent"
msgstr ""
-#: dist/toolbar/toolbar.js:357
+#: dist/toolbar/toolbar.js:368
msgid "Decrease indent"
msgstr ""
-#: dist/toolbar/toolbar.js:360
+#: dist/toolbar/toolbar.js:371
msgid "Insert table"
msgstr ""
-#: dist/toolbar/toolbar.js:361
+#: dist/toolbar/toolbar.js:372
msgid "Insert comment"
msgstr ""
-#: dist/toolbar/toolbar.js:362
+#: dist/toolbar/toolbar.js:373
msgid "Insert graphic"
msgstr ""
-#: dist/toolbar/toolbar.js:364
+#: dist/toolbar/toolbar.js:375
msgid "More"
msgstr ""
-#: dist/toolbar/toolbar.js:365
+#: dist/toolbar/toolbar.js:376
msgid "Close document"
msgstr ""
-#: dist/toolbar/toolbar.js:395 dist/toolbar/toolbar.js:758
+#: dist/toolbar/toolbar.js:406 dist/toolbar/toolbar.js:776
msgid "Sum"
msgstr ""
-#: dist/toolbar/toolbar.js:396
+#: dist/toolbar/toolbar.js:407
msgid "Function"
msgstr ""
-#: dist/toolbar/toolbar.js:397
+#: dist/toolbar/toolbar.js:408
msgid "Cancel"
msgstr ""
-#: dist/toolbar/toolbar.js:398
+#: dist/toolbar/toolbar.js:409
msgid "Accept"
msgstr ""
-#: dist/toolbar/toolbar.js:409
+#: dist/toolbar/toolbar.js:420
msgid "First sheet"
msgstr ""
-#: dist/toolbar/toolbar.js:410
+#: dist/toolbar/toolbar.js:421
msgid "Previous sheet"
msgstr ""
-#: dist/toolbar/toolbar.js:411
+#: dist/toolbar/toolbar.js:422
msgid "Next sheet"
msgstr ""
-#: dist/toolbar/toolbar.js:412
+#: dist/toolbar/toolbar.js:423
msgid "Last sheet"
msgstr ""
-#: dist/toolbar/toolbar.js:422 src/control/Control.Menubar.js:94
+#: dist/toolbar/toolbar.js:433 src/control/Control.Menubar.js:101
msgid "Fullscreen presentation"
msgstr ""
-#: dist/toolbar/toolbar.js:424
+#: dist/toolbar/toolbar.js:435
msgid "Insert slide"
msgstr ""
-#: dist/toolbar/toolbar.js:425 src/control/Control.Menubar.js:91
+#: dist/toolbar/toolbar.js:436 src/control/Control.Menubar.js:98
msgid "Duplicate slide"
msgstr ""
-#: dist/toolbar/toolbar.js:426 src/control/Control.Menubar.js:92
+#: dist/toolbar/toolbar.js:437 src/control/Control.Menubar.js:99
msgid "Delete slide"
msgstr ""
-#: dist/toolbar/toolbar.js:438
+#: dist/toolbar/toolbar.js:450
msgid "Search:"
msgstr ""
-#: dist/toolbar/toolbar.js:443
+#: dist/toolbar/toolbar.js:455
msgid "Search backwards"
msgstr ""
-#: dist/toolbar/toolbar.js:444
+#: dist/toolbar/toolbar.js:456
msgid "Search forward"
msgstr ""
-#: dist/toolbar/toolbar.js:445
+#: dist/toolbar/toolbar.js:457
msgid "Cancel the search"
msgstr ""
-#: dist/toolbar/toolbar.js:450 dist/toolbar/toolbar.js:1196
-msgid "Take edit lock (others can only view)"
-msgstr ""
-
-#: dist/toolbar/toolbar.js:450 dist/toolbar/toolbar.js:1196
-msgid "VIEWING"
+#: dist/toolbar/toolbar.js:462 dist/toolbar/toolbar.js:1328
+msgid "No users"
msgstr ""
-#: dist/toolbar/toolbar.js:452
+#: dist/toolbar/toolbar.js:464
msgid "Previous page"
msgstr ""
-#: dist/toolbar/toolbar.js:453
+#: dist/toolbar/toolbar.js:465
msgid "Next page"
msgstr ""
-#: dist/toolbar/toolbar.js:455 src/control/Control.Menubar.js:34
-#: src/control/Control.Menubar.js:79 src/control/Control.Menubar.js:128
+#: dist/toolbar/toolbar.js:467 src/control/Control.Menubar.js:41
+#: src/control/Control.Menubar.js:86 src/control/Control.Menubar.js:135
msgid "Reset zoom"
msgstr ""
-#: dist/toolbar/toolbar.js:456 src/control/Control.Menubar.js:33
-#: src/control/Control.Menubar.js:78 src/control/Control.Menubar.js:127
+#: dist/toolbar/toolbar.js:468 src/control/Control.Menubar.js:40
+#: src/control/Control.Menubar.js:85 src/control/Control.Menubar.js:134
msgid "Zoom out"
msgstr ""
-#: dist/toolbar/toolbar.js:458 src/control/Control.Menubar.js:32
-#: src/control/Control.Menubar.js:77 src/control/Control.Menubar.js:126
+#: dist/toolbar/toolbar.js:470 src/control/Control.Menubar.js:39
+#: src/control/Control.Menubar.js:84 src/control/Control.Menubar.js:133
msgid "Zoom in"
msgstr ""
-#: dist/toolbar/toolbar.js:476
-msgid "You are viewing now."
+#: dist/toolbar/toolbar.js:494
+msgid "%user has joined"
msgstr ""
-#: dist/toolbar/toolbar.js:476
-msgid "Click here to take edit."
+#: dist/toolbar/toolbar.js:495
+msgid "%user has left"
msgstr ""
-#: dist/toolbar/toolbar.js:607 dist/toolbar/toolbar.js:1094
+#: dist/toolbar/toolbar.js:625 dist/toolbar/toolbar.js:1117
msgid "Size"
msgstr ""
-#: dist/toolbar/toolbar.js:739
+#: dist/toolbar/toolbar.js:757
msgid "Number of Sheets"
msgstr ""
-#: dist/toolbar/toolbar.js:742
+#: dist/toolbar/toolbar.js:760
msgid "Selected range of cells"
msgstr ""
-#: dist/toolbar/toolbar.js:745 dist/toolbar/toolbar.js:791
+#: dist/toolbar/toolbar.js:763 dist/toolbar/toolbar.js:809
msgid "Entering text mode"
msgstr ""
-#: dist/toolbar/toolbar.js:748 dist/toolbar/toolbar.js:794
+#: dist/toolbar/toolbar.js:766 dist/toolbar/toolbar.js:812
msgid "Selection Mode"
msgstr ""
-#: dist/toolbar/toolbar.js:751
+#: dist/toolbar/toolbar.js:769
msgid "Choice of functions"
msgstr ""
-#: dist/toolbar/toolbar.js:753
+#: dist/toolbar/toolbar.js:771
msgid "Average"
msgstr ""
-#: dist/toolbar/toolbar.js:754
+#: dist/toolbar/toolbar.js:772
msgid "CountA"
msgstr ""
-#: dist/toolbar/toolbar.js:755
+#: dist/toolbar/toolbar.js:773
msgid "Count"
msgstr ""
-#: dist/toolbar/toolbar.js:756
+#: dist/toolbar/toolbar.js:774
msgid "Maximum"
msgstr ""
-#: dist/toolbar/toolbar.js:757
+#: dist/toolbar/toolbar.js:775
msgid "Minimum"
msgstr ""
-#: dist/toolbar/toolbar.js:759
+#: dist/toolbar/toolbar.js:777
msgid "Selection count"
msgstr ""
-#: dist/toolbar/toolbar.js:760
+#: dist/toolbar/toolbar.js:778
msgid "None"
msgstr ""
-#: dist/toolbar/toolbar.js:765
+#: dist/toolbar/toolbar.js:783
msgid "Wrap Text"
msgstr ""
-#: dist/toolbar/toolbar.js:766
+#: dist/toolbar/toolbar.js:784
msgid "Merge and Center Cells"
msgstr ""
-#: dist/toolbar/toolbar.js:768
+#: dist/toolbar/toolbar.js:786
msgid "Format as Currency"
msgstr ""
-#: dist/toolbar/toolbar.js:769
+#: dist/toolbar/toolbar.js:787
msgid "Format as Percent"
msgstr ""
-#: dist/toolbar/toolbar.js:770
+#: dist/toolbar/toolbar.js:788
msgid "Format as Number"
msgstr ""
-#: dist/toolbar/toolbar.js:771
+#: dist/toolbar/toolbar.js:789
msgid "Format as Date"
msgstr ""
-#: dist/toolbar/toolbar.js:772
+#: dist/toolbar/toolbar.js:790
msgid "Add Decimal Place"
msgstr ""
-#: dist/toolbar/toolbar.js:773
+#: dist/toolbar/toolbar.js:791
msgid "Delete Decimal Place"
msgstr ""
-#: dist/toolbar/toolbar.js:775
+#: dist/toolbar/toolbar.js:793
msgid "Sort Ascending"
msgstr ""
-#: dist/toolbar/toolbar.js:776
+#: dist/toolbar/toolbar.js:794
msgid "Sort Descending"
msgstr ""
-#: dist/toolbar/toolbar.js:785
+#: dist/toolbar/toolbar.js:803
msgid "Number of Pages"
msgstr ""
-#: dist/toolbar/toolbar.js:788
+#: dist/toolbar/toolbar.js:806
msgid "Word Counter"
msgstr ""
-#: dist/toolbar/toolbar.js:802
+#: dist/toolbar/toolbar.js:820
msgid "Number of Slides"
msgstr ""
-#: dist/toolbar/toolbar.js:919
+#: dist/toolbar/toolbar.js:941
msgid "Document saved"
msgstr ""
-#: dist/toolbar/toolbar.js:1077
+#: dist/toolbar/toolbar.js:1100
msgid "Style"
msgstr ""
-#: dist/toolbar/toolbar.js:1089
+#: dist/toolbar/toolbar.js:1112
msgid "Font"
msgstr ""
-#: dist/toolbar/toolbar.js:1113
+#: dist/toolbar/toolbar.js:1136
msgid "Previous slide"
msgstr ""
-#: dist/toolbar/toolbar.js:1114
+#: dist/toolbar/toolbar.js:1137
msgid "Next slide"
msgstr ""
-#: dist/toolbar/toolbar.js:1192
-msgid "You are editing (others can only view)"
-msgstr ""
-
-#: dist/toolbar/toolbar.js:1192
-msgid "EDITING"
+#: dist/toolbar/toolbar.js:1305
+msgid "Layout"
msgstr ""
-#: dist/toolbar/toolbar.js:1212
-msgid "You are locked in readonly mode"
+#: dist/toolbar/toolbar.js:1319
+msgid "%n users"
msgstr ""
-#: dist/toolbar/toolbar.js:1212
-msgid "READONLY"
+#: dist/toolbar/toolbar.js:1326
+msgid "1 user"
msgstr ""
-#: dist/toolbar/toolbar.js:1324
-msgid "Layout"
+#: dist/toolbar/toolbar.js:1351 src/control/Control.DocumentRepair.js:87
+msgid "You"
msgstr ""
#: src/admin/AdminSocketBase.js:45
@@ -448,144 +598,100 @@ msgstr ""
msgid "Are you sure you want to terminate this session?"
msgstr ""
-#: src/admin/AdminStrings.js:4
-msgid "Admin console"
-msgstr ""
-
-#: src/admin/AdminStrings.js:5
-msgid "Toggle navigation"
-msgstr ""
-
-#: src/admin/AdminStrings.js:6
-msgid "Settings"
-msgstr ""
-
-#: src/admin/AdminStrings.js:7
-msgid "Overview"
-msgstr ""
-
-#: src/admin/AdminStrings.js:8
-msgid "(current)"
-msgstr ""
-
-#: src/admin/AdminStrings.js:9
-msgid "Analytics"
-msgstr ""
-
-#: src/admin/AdminStrings.js:10
-msgid "Dashboard"
-msgstr ""
-
-#: src/admin/AdminStrings.js:11
-msgid "Users online"
-msgstr ""
-
-#: src/admin/AdminStrings.js:12
-msgid "Documents opened"
-msgstr ""
-
-#: src/admin/AdminStrings.js:13
-msgid "Memory consumed"
-msgstr ""
-
-#: src/admin/AdminStrings.js:14
-msgid "PID"
-msgstr ""
-
-#: src/admin/AdminStrings.js:15
-msgid "Document"
+#: src/admin/Util.js:13
+msgid "kB"
msgstr ""
-#: src/admin/AdminStrings.js:16
-msgid "Number of views"
+#: src/admin/Util.js:13
+msgid "MB"
msgstr ""
-#: src/admin/AdminStrings.js:17
-msgid "Elapsed time"
+#: src/admin/Util.js:13
+msgid "GB"
msgstr ""
-#: src/admin/AdminStrings.js:18
-msgid "Kill"
+#: src/admin/Util.js:13
+msgid "TB"
msgstr ""
-#: src/admin/AdminStrings.js:19
-msgid "Graphs"
+#: src/admin/Util.js:41
+msgid " hrs"
msgstr ""
-#: src/admin/AdminStrings.js:21
-msgid "Cache size of memory statistics"
+#: src/admin/Util.js:43
+msgid " mins"
msgstr ""
-#: src/admin/AdminStrings.js:22
-msgid "Time interval of memory statistics (in ms)"
+#: src/admin/Util.js:45
+msgid " s"
msgstr ""
-#: src/admin/AdminStrings.js:23
-msgid "Cache size of CPU statistics"
+#: src/control/Control.ColumnHeader.js:38
+msgid "Insert column before"
msgstr ""
-#: src/admin/AdminStrings.js:24
-msgid "Time interval of CPU statistics (in ms)"
+#: src/control/Control.ColumnHeader.js:45 src/control/Control.Menubar.js:141
+msgid "Delete column"
msgstr ""
-#: src/admin/Util.js:13
-msgid "kB"
+#: src/control/Control.ColumnHeader.js:52
+msgid "Optimal Width"
msgstr ""
-#: src/admin/Util.js:13
-msgid "MB"
+#: src/control/Control.ColumnHeader.js:67
+msgid "Optimal Column Width"
msgstr ""
-#: src/admin/Util.js:13
-msgid "GB"
+#: src/control/Control.DocumentRepair.js:32
+msgid "Repair Document"
msgstr ""
-#: src/admin/Util.js:13
-msgid "TB"
+#: src/control/Control.DocumentRepair.js:40
+msgid "Type"
msgstr ""
-#: src/admin/Util.js:41
-msgid " hrs"
+#: src/control/Control.DocumentRepair.js:42
+msgid "Index"
msgstr ""
-#: src/admin/Util.js:43
-msgid " mins"
+#: src/control/Control.DocumentRepair.js:44 src/control/Control.Menubar.js:29
+msgid "Comment"
msgstr ""
-#: src/admin/Util.js:45
-msgid " s"
+#: src/control/Control.DocumentRepair.js:46
+msgid "User name"
msgstr ""
-#: src/control/Control.ColumnHeader.js:38
-msgid "Insert column before"
+#: src/control/Control.DocumentRepair.js:48
+msgid "Timestamp"
msgstr ""
-#: src/control/Control.ColumnHeader.js:45 src/control/Control.Menubar.js:134
-msgid "Delete column"
+#: src/control/Control.DocumentRepair.js:52
+msgid "Jump to state"
msgstr ""
-#: src/control/Control.Menubar.js:10 src/control/Control.Menubar.js:56
-#: src/control/Control.Menubar.js:102
+#: src/control/Control.Menubar.js:10 src/control/Control.Menubar.js:63
+#: src/control/Control.Menubar.js:109
msgid "File"
msgstr ""
-#: src/control/Control.Menubar.js:11 src/control/Control.Menubar.js:57
-#: src/control/Control.Menubar.js:103
+#: src/control/Control.Menubar.js:11 src/control/Control.Menubar.js:64
+#: src/control/Control.Menubar.js:110
msgid "Print"
msgstr ""
-#: src/control/Control.Menubar.js:12 src/control/Control.Menubar.js:58
-#: src/control/Control.Menubar.js:104
+#: src/control/Control.Menubar.js:12 src/control/Control.Menubar.js:65
+#: src/control/Control.Menubar.js:111
msgid "See revision history"
msgstr ""
-#: src/control/Control.Menubar.js:13 src/control/Control.Menubar.js:59
-#: src/control/Control.Menubar.js:105
+#: src/control/Control.Menubar.js:13 src/control/Control.Menubar.js:66
+#: src/control/Control.Menubar.js:112
msgid "Download as"
msgstr ""
-#: src/control/Control.Menubar.js:13 src/control/Control.Menubar.js:59
-#: src/control/Control.Menubar.js:105
+#: src/control/Control.Menubar.js:13 src/control/Control.Menubar.js:66
+#: src/control/Control.Menubar.js:112
msgid "PDF Document (.pdf)"
msgstr ""
@@ -601,176 +707,192 @@ msgstr ""
msgid "Microsoft Word (.docx)"
msgstr ""
-#: src/control/Control.Menubar.js:18 src/control/Control.Menubar.js:64
-#: src/control/Control.Menubar.js:110
+#: src/control/Control.Menubar.js:18 src/control/Control.Menubar.js:71
+#: src/control/Control.Menubar.js:117
msgid "Edit"
msgstr ""
-#: src/control/Control.Menubar.js:21 src/control/Control.Menubar.js:67
-#: src/control/Control.Menubar.js:113
+#: src/control/Control.Menubar.js:18
+msgid "Repair"
+msgstr ""
+
+#: src/control/Control.Menubar.js:22 src/control/Control.Menubar.js:74
+#: src/control/Control.Menubar.js:120
msgid "Cut"
msgstr ""
-#: src/control/Control.Menubar.js:22 src/control/Control.Menubar.js:68
-#: src/control/Control.Menubar.js:114
+#: src/control/Control.Menubar.js:23 src/control/Control.Menubar.js:75
+#: src/control/Control.Menubar.js:121
msgid "Copy"
msgstr ""
-#: src/control/Control.Menubar.js:23 src/control/Control.Menubar.js:69
-#: src/control/Control.Menubar.js:115
+#: src/control/Control.Menubar.js:24 src/control/Control.Menubar.js:76
+#: src/control/Control.Menubar.js:122
msgid "Paste"
msgstr ""
-#: src/control/Control.Menubar.js:25 src/control/Control.Menubar.js:71
-#: src/control/Control.Menubar.js:117
+#: src/control/Control.Menubar.js:26 src/control/Control.Menubar.js:78
+#: src/control/Control.Menubar.js:124
msgid "Select all"
msgstr ""
-#: src/control/Control.Menubar.js:27 src/control/Control.Menubar.js:36
-#: src/control/Control.Menubar.js:73 src/control/Control.Menubar.js:81
-#: src/control/Control.Menubar.js:119
+#: src/control/Control.Menubar.js:28 src/control/Control.Menubar.js:43
+#: src/control/Control.Menubar.js:80 src/control/Control.Menubar.js:88
+#: src/control/Control.Menubar.js:126
msgid "Insert"
msgstr ""
-#: src/control/Control.Menubar.js:27 src/control/Control.Menubar.js:73
-#: src/control/Control.Menubar.js:119
+#: src/control/Control.Menubar.js:28 src/control/Control.Menubar.js:80
+#: src/control/Control.Menubar.js:126
msgid "Image"
msgstr ""
-#: src/control/Control.Menubar.js:28
-msgid "Comment"
+#: src/control/Control.Menubar.js:31
+msgid "Footnote"
msgstr ""
-#: src/control/Control.Menubar.js:30 src/control/Control.Menubar.js:75
-#: src/control/Control.Menubar.js:124
+#: src/control/Control.Menubar.js:32
+msgid "Endnote"
+msgstr ""
+
+#: src/control/Control.Menubar.js:34
+msgid "Page break"
+msgstr ""
+
+#: src/control/Control.Menubar.js:35
+msgid "Column break"
+msgstr ""
+
+#: src/control/Control.Menubar.js:37 src/control/Control.Menubar.js:82
+#: src/control/Control.Menubar.js:131
msgid "View"
msgstr ""
-#: src/control/Control.Menubar.js:30 src/control/Control.Menubar.js:75
-#: src/control/Control.Menubar.js:124
+#: src/control/Control.Menubar.js:37 src/control/Control.Menubar.js:82
+#: src/control/Control.Menubar.js:131
msgid "Full screen"
msgstr ""
-#: src/control/Control.Menubar.js:36 src/control/Control.Menubar.js:81
+#: src/control/Control.Menubar.js:43 src/control/Control.Menubar.js:88
msgid "Tables"
msgstr ""
-#: src/control/Control.Menubar.js:36 src/control/Control.Menubar.js:81
+#: src/control/Control.Menubar.js:43 src/control/Control.Menubar.js:88
msgid "Rows before"
msgstr ""
-#: src/control/Control.Menubar.js:37 src/control/Control.Menubar.js:82
+#: src/control/Control.Menubar.js:44 src/control/Control.Menubar.js:89
msgid "Rows after"
msgstr ""
-#: src/control/Control.Menubar.js:39 src/control/Control.Menubar.js:84
+#: src/control/Control.Menubar.js:46 src/control/Control.Menubar.js:91
msgid "Columns left"
msgstr ""
-#: src/control/Control.Menubar.js:40 src/control/Control.Menubar.js:85
+#: src/control/Control.Menubar.js:47 src/control/Control.Menubar.js:92
msgid "Columns right"
msgstr ""
-#: src/control/Control.Menubar.js:41 src/control/Control.Menubar.js:86
+#: src/control/Control.Menubar.js:48 src/control/Control.Menubar.js:93
msgid "Delete"
msgstr ""
-#: src/control/Control.Menubar.js:41 src/control/Control.Menubar.js:86
+#: src/control/Control.Menubar.js:48 src/control/Control.Menubar.js:93
msgid "Rows"
msgstr ""
-#: src/control/Control.Menubar.js:42 src/control/Control.Menubar.js:87
+#: src/control/Control.Menubar.js:49 src/control/Control.Menubar.js:94
msgid "Columns"
msgstr ""
-#: src/control/Control.Menubar.js:43 src/control/Control.Menubar.js:44
+#: src/control/Control.Menubar.js:50 src/control/Control.Menubar.js:51
msgid "Table"
msgstr ""
-#: src/control/Control.Menubar.js:44
+#: src/control/Control.Menubar.js:51
msgid "Select"
msgstr ""
-#: src/control/Control.Menubar.js:45 src/control/Control.Menubar.js:121
+#: src/control/Control.Menubar.js:52 src/control/Control.Menubar.js:128
msgid "Row"
msgstr ""
-#: src/control/Control.Menubar.js:46 src/control/Control.Menubar.js:122
+#: src/control/Control.Menubar.js:53 src/control/Control.Menubar.js:129
msgid "Column"
msgstr ""
-#: src/control/Control.Menubar.js:47
+#: src/control/Control.Menubar.js:54
msgid "Cell"
msgstr ""
-#: src/control/Control.Menubar.js:48 src/control/Control.Menubar.js:88
+#: src/control/Control.Menubar.js:55 src/control/Control.Menubar.js:95
msgid "Merge cells"
msgstr ""
-#: src/control/Control.Menubar.js:50 src/control/Control.Menubar.js:96
-#: src/control/Control.Menubar.js:136
+#: src/control/Control.Menubar.js:57 src/control/Control.Menubar.js:103
+#: src/control/Control.Menubar.js:143
msgid "Help"
msgstr ""
-#: src/control/Control.Menubar.js:50 src/control/Control.Menubar.js:96
-#: src/control/Control.Menubar.js:136
+#: src/control/Control.Menubar.js:57 src/control/Control.Menubar.js:103
+#: src/control/Control.Menubar.js:143
msgid "Keyboard shortcuts"
msgstr ""
-#: src/control/Control.Menubar.js:51 src/control/Control.Menubar.js:97
-#: src/control/Control.Menubar.js:137
+#: src/control/Control.Menubar.js:58 src/control/Control.Menubar.js:104
+#: src/control/Control.Menubar.js:144
msgid "About"
msgstr ""
-#: src/control/Control.Menubar.js:60
+#: src/control/Control.Menubar.js:67
msgid "ODF presentation (.odp)"
msgstr ""
-#: src/control/Control.Menubar.js:61
+#: src/control/Control.Menubar.js:68
msgid "Microsoft Powerpoint 2003 (.ppt)"
msgstr ""
-#: src/control/Control.Menubar.js:62
+#: src/control/Control.Menubar.js:69
msgid "Microsoft Powerpoint (.pptx)"
msgstr ""
-#: src/control/Control.Menubar.js:90
+#: src/control/Control.Menubar.js:97
msgid "Slide"
msgstr ""
-#: src/control/Control.Menubar.js:90
+#: src/control/Control.Menubar.js:97
msgid "New slide"
msgstr ""
-#: src/control/Control.Menubar.js:106
+#: src/control/Control.Menubar.js:113
msgid "ODF spreadsheet (.ods)"
msgstr ""
-#: src/control/Control.Menubar.js:107
+#: src/control/Control.Menubar.js:114
msgid "Microsoft Excel 2003 (.xls)"
msgstr ""
-#: src/control/Control.Menubar.js:108
+#: src/control/Control.Menubar.js:115
msgid "Microsoft Excel (.xlsx)"
msgstr ""
-#: src/control/Control.Menubar.js:130
+#: src/control/Control.Menubar.js:137
msgid "Cells"
msgstr ""
-#: src/control/Control.Menubar.js:130
+#: src/control/Control.Menubar.js:137
msgid "Insert row"
msgstr ""
-#: src/control/Control.Menubar.js:131
+#: src/control/Control.Menubar.js:138
msgid "Insert column"
msgstr ""
-#: src/control/Control.Menubar.js:133 src/control/Control.RowHeader.js:43
+#: src/control/Control.Menubar.js:140 src/control/Control.RowHeader.js:43
msgid "Delete row"
msgstr ""
-#: src/control/Control.Menubar.js:306
+#: src/control/Control.Menubar.js:313
msgid "Are you sure you want to delete this slide?"
msgstr ""
@@ -778,6 +900,14 @@ msgstr ""
msgid "Insert row above"
msgstr ""
+#: src/control/Control.RowHeader.js:50
+msgid "Optimal Height"
+msgstr ""
+
+#: src/control/Control.RowHeader.js:63
+msgid "Optimal Row Height"
+msgstr ""
+
#: src/control/Control.Tabs.js:46
msgid "Insert sheet before this"
msgstr ""
@@ -802,56 +932,60 @@ msgstr ""
msgid "Enter new sheet name"
msgstr ""
-#: src/control/Toolbar.js:59 src/control/Toolbar.js:68
+#: src/control/Toolbar.js:63 src/control/Toolbar.js:72
msgid "Downloading..."
msgstr ""
-#: src/control/Toolbar.js:80 src/map/Map.js:806
+#: src/control/Toolbar.js:84 src/map/Map.js:856
msgid "Saving..."
msgstr ""
-#: src/control/Toolbar.js:212
+#: src/control/Toolbar.js:216
msgid "This version of %productName is powered by"
msgstr ""
-#: src/core/Socket.js:17
+#: src/core/Socket.js:22
msgid "Oops, there is a problem connecting to LibreOffice Online : "
msgstr ""
-#: src/core/Socket.js:139
+#: src/core/Socket.js:138
msgid "Unsupported server version."
msgstr ""
-#: src/core/Socket.js:158
+#: src/core/Socket.js:170
msgid "Document requires password to view."
msgstr ""
-#: src/core/Socket.js:161
+#: src/core/Socket.js:173
msgid "Document requires password to modify."
msgstr ""
-#: src/core/Socket.js:163
+#: src/core/Socket.js:175
msgid "Hit Cancel to open in view-only mode."
msgstr ""
-#: src/core/Socket.js:167
+#: src/core/Socket.js:179
msgid "Wrong password provided. Please try again."
msgstr ""
-#: src/core/Socket.js:304
+#: src/core/Socket.js:221
+msgid "Connecting..."
+msgstr ""
+
+#: src/core/Socket.js:339
msgid ""
"Well, this is embarrassing, we cannot connect to your document. Please try "
"again."
msgstr ""
-#: src/core/Socket.js:307
-msgid "We are sorry, this is an unexpected connection error. Please try again."
-msgstr ""
-
-#: src/map/Map.js:116
+#: src/map/Map.js:118
msgid "Initializing..."
msgstr ""
-#: src/map/Map.js:809
+#: src/map/Map.js:859
msgid "Loading..."
msgstr ""
+
+#: src/map/handler/Map.FileInserter.js:54
+msgid "Uploading..."
+msgstr ""
commit 89f29e30fc7f797cab07bb2dc12a055d1e58b71f
Author: Tor Lillqvist <tml at collabora.com>
Date: Tue Oct 11 13:05:13 2016 +0300
It's 'error:', in lower case
Clearly this if branch has never been reached.
(cherry picked from commit 9ff9452e4c427fe66ee8fea3bf0eb44a00d3d53e)
diff --git a/loolwsd/test/UnitPrefork.cpp b/loolwsd/test/UnitPrefork.cpp
index 393d449..b4213bd 100644
--- a/loolwsd/test/UnitPrefork.cpp
+++ b/loolwsd/test/UnitPrefork.cpp
@@ -62,7 +62,7 @@ public:
virtual bool filterChildMessage(const std::vector<char>& payload) override
{
const std::string memory = LOOLProtocol::getFirstLine(payload);
- if (!memory.compare(0,6,"Error:"))
+ if (!memory.compare(0,6,"error:"))
{
_failure = memory;
}
commit 98435cf718163fbf0ff14aebd3cb48ab8ff8dead
Author: Aleksander Machniak <machniak at kolabsys.com>
Date: Mon Oct 10 09:12:01 2016 +0200
Fix WOPI request header: X-WOPIOverride -> X-WOPI-Override
Change-Id: Ibd288beeffecea415c8524dfc03e77e71ba3c10e
Reviewed-on: https://gerrit.libreoffice.org/29662
Reviewed-by: Jan Holesovsky <kendy at collabora.com>
Tested-by: Jan Holesovsky <kendy at collabora.com>
(cherry picked from commit 799b783968f86f1c943e17008220bb4741f41b5f)
diff --git a/loolwsd/Storage.cpp b/loolwsd/Storage.cpp
index 57e3c5f..7cf5693 100644
--- a/loolwsd/Storage.cpp
+++ b/loolwsd/Storage.cpp
@@ -364,7 +364,7 @@ bool WopiStorage::saveLocalFileToStorage()
std::unique_ptr<Poco::Net::HTTPClientSession> psession(getHTTPClientSession(uriObject));
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
- request.set("X-WOPIOverride", "PUT");
+ request.set("X-WOPI-Override", "PUT");
request.setContentType("application/octet-stream");
request.setContentLength(size);
commit 7939ef25695bcc7cba2ac8467b1617b19a5d6f6b
Author: Henry Castro <hcastro at collabora.com>
Date: Mon Oct 10 22:28:56 2016 -0400
loolwsd: websocket shutdown cleanup
(cherry picked from commit c62344db814fe351787316accf0faf53ee811db5)
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 2b3b205..79d1986 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -182,7 +182,6 @@ static inline
void shutdownLimitReached(WebSocket& ws)
{
const std::string error = Poco::format(PAYLOAD_UNAVALABLE_LIMIT_REACHED, MAX_DOCUMENTS, MAX_CONNECTIONS);
- const std::string close = Poco::format(SERVICE_UNAVALABLE_LIMIT_REACHED, static_cast<int>(WebSocket::WS_POLICY_VIOLATION));
/* loleaflet sends loolclient, load and partrectangles message immediately
after web socket handshake, so closing web socket fails loading page in
@@ -204,7 +203,7 @@ void shutdownLimitReached(WebSocket& ws)
if (--retries == 4)
{
ws.sendFrame(error.data(), error.size());
- ws.shutdown(WebSocket::WS_POLICY_VIOLATION, close);
+ ws.shutdown(WebSocket::WS_POLICY_VIOLATION, "");
}
}
while (retries > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
@@ -212,7 +211,7 @@ void shutdownLimitReached(WebSocket& ws)
catch (Exception&)
{
ws.sendFrame(error.data(), error.size());
- ws.shutdown(WebSocket::WS_POLICY_VIOLATION, close);
+ ws.shutdown(WebSocket::WS_POLICY_VIOLATION, "");
}
}
@@ -897,8 +896,8 @@ private:
// something wrong, with internal exceptions
Log::trace("Abnormal close handshake.");
session->closeFrame();
- ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY, SERVICE_UNAVALABLE_INTERNAL_ERROR);
- session->shutdownPeer(WebSocket::WS_ENDPOINT_GOING_AWAY, SERVICE_UNAVALABLE_INTERNAL_ERROR);
+ ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY, "");
+ session->shutdownPeer(WebSocket::WS_ENDPOINT_GOING_AWAY, "");
}
}
@@ -1050,7 +1049,7 @@ public:
const std::string msg = std::string("error: ") + exc.what();
ws->sendFrame(msg.data(), msg.size());
// abnormal close frame handshake
- ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY, msg);
+ ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY, "");
}
catch (const std::exception& exc2)
{
@@ -1275,8 +1274,8 @@ public:
// something wrong, with internal exceptions
Log::trace("Abnormal close handshake.");
session->closeFrame();
- ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY, SERVICE_UNAVALABLE_INTERNAL_ERROR);
- session->shutdownPeer(WebSocket::WS_ENDPOINT_GOING_AWAY, SERVICE_UNAVALABLE_INTERNAL_ERROR);
+ ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY, "");
+ session->shutdownPeer(WebSocket::WS_ENDPOINT_GOING_AWAY, "");
}
}
catch (const Exception& exc)
diff --git a/loolwsd/UserMessages.hpp b/loolwsd/UserMessages.hpp
index 36e6ad3..7883fc0 100644
--- a/loolwsd/UserMessages.hpp
+++ b/loolwsd/UserMessages.hpp
@@ -13,9 +13,7 @@
#define INCLUDED_USERMESSAGES_HPP
//NOTE: For whatever reason Poco seems to trim the first character.
-
constexpr auto SERVICE_UNAVALABLE_INTERNAL_ERROR = " Service is unavailable. Please try again later and report to your administrator if the issue persists.";
-constexpr auto SERVICE_UNAVALABLE_LIMIT_REACHED = "error: cmd=socket kind=close code=%d";
constexpr auto PAYLOAD_UNAVALABLE_LIMIT_REACHED = "error: cmd=socket kind=limitreached params=%d,%d";
#endif
diff --git a/loolwsd/test/httpwserror.cpp b/loolwsd/test/httpwserror.cpp
index 8e7769d..509046c 100644
--- a/loolwsd/test/httpwserror.cpp
+++ b/loolwsd/test/httpwserror.cpp
@@ -103,7 +103,6 @@ void HTTPWSError::testMaxDocuments()
sendTextFrame(socket, "partpagerectangles ");
statusCode = getErrorCode(socket, message);
CPPUNIT_ASSERT_EQUAL(static_cast<Poco::UInt16>(Poco::Net::WebSocket::WS_POLICY_VIOLATION), statusCode);
- CPPUNIT_ASSERT_MESSAGE("Wrong error message ", message.find("error: cmd=socket kind=close") != std::string::npos);
}
catch (const Poco::Exception& exc)
{
@@ -144,7 +143,6 @@ void HTTPWSError::testMaxConnections()
sendTextFrame(socketN, "partpagerectangles ");
statusCode = getErrorCode(*socketN, message);
CPPUNIT_ASSERT_EQUAL(static_cast<Poco::UInt16>(Poco::Net::WebSocket::WS_POLICY_VIOLATION), statusCode);
- CPPUNIT_ASSERT_MESSAGE("Wrong error message ", message.find("error: cmd=socket kind=close") != std::string::npos);
}
catch (const Poco::Exception& exc)
{
commit 8babf00a3523c1e6808a200999f9e643eb082482
Author: Henry Castro <hcastro at collabora.com>
Date: Mon Oct 10 16:03:30 2016 -0400
loleaflet: do not show internal errors
Internal error message, it was intended for debugging purposes,
so it is not necessary to show them to final users
(cherry picked from commit 03f912115a93e94840c8cedb23ab7d5698c1257a)
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index c4bb43f..d26277d 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -336,12 +336,7 @@ L.Socket = L.Class.extend({
this._map._docLayer.removeAllViews();
}
- if (e.code && e.reason) {
- this._map.fire('error', {msg: e.reason});
- }
- else {
- this._map.fire('error', {msg: _('Well, this is embarrassing, we cannot connect to your document. Please try again.'), cmd: 'socket', kind: 'closed', id: 4});
- }
+ this._map.fire('error', {msg: _('Well, this is embarrassing, we cannot connect to your document. Please try again.'), cmd: 'socket', kind: 'closed', id: 4});
},
parseServerCmd: function (msg) {
commit bedcf4c16d8ebb87e5196b48ba4065ff1499c4c1
Author: Tor Lillqvist <tml at collabora.com>
Date: Mon Oct 10 18:16:13 2016 +0300
There doesn't seem to be any 'invalidate:' message any longer
There is only 'invalidatetiles:'. Try to document that properly then
instead.
(cherry picked from commit d5bbe8b52c27744a3e6e06c84e9e8a0cd2615b51)
diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt
index d617354..ba91ae0 100644
--- a/loolwsd/protocol.txt
+++ b/loolwsd/protocol.txt
@@ -224,20 +224,13 @@ getchildid: id=<id>
Returns the child id
-invalidate: part=<partNumber> x=<x> y=<y> width=<width> height=<height>
+invalidatetiles: part=<partNumber> x=<x> y=<y> width=<width> height=<height>
All parameters are numbers. Tells the client to invalidate any
cached tiles for the document area specified (in twips), at any
zoom level.
- The client should handle either this message or the
- invalidatetiles: message, which has a different syntax, with
- payload directly from the LOK_CALLBACK_INVALIDATE_TILES
- callback. (The latter does not contain a part number, and as the
- protocol is asynchronous, it is unclear whether a client can be
- sure, or find out with certainty, for what part the
- invalidatetiles: message is. The invalidatetiles: message will be
- dropped soon.)
+invalidatetiles: EMPTY
nextmessage: size=<byteSize>
@@ -282,17 +275,17 @@ tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<
render a tile, or the string 'cached' if the tile was found in the
cache.
-Each LOK_CALLBACK_FOO_BAR callback causes a corresponding message to
-the client, consisting of the FOO_BAR part in lowercase, without
-underscore, followed by a colon, space and the callback payload. For
-instance:
+Each LOK_CALLBACK_FOO_BAR callback except
+LOK_CALLBACK_INVALIDATE_TILES causes a corresponding message to the
+client, consisting of the FOO_BAR part in lowercase, without
+underscore, followed by a colon, space and the callback
+payload. (LOK_CALLBACK_INVALIDATE_TILES causes an invalidatetiles:
+message as documented above.) For instance:
invalidatecursor: <payload>
The payload contains a rectangle describing the cursor position.
-invalidatetiles: <payload>
-
The communication between the parent process (the one keeping open the
Websocket connections to the clients) and a child process (handling
one document through LibreOfficeKit) uses the same protocol, with
commit b3105d99d5b2fe74c55a56fb0cc7dfc8b25d6375
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Mon Oct 10 18:00:38 2016 +0530
loleaflet: Restore old coloring algorithm for non-text documents
.uno:TrackedChangeAuthors doesn't give correct colors for
documents other than writer, lets use our old algorithm for color
assignment for these documents.
Change-Id: If865788154a80da2637aad84183a0e947bb4b7e8
(cherry picked from commit a01d2fc91dfd6ea4ce365d30641fa251d45c8b04)
diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 3c51cb4..8b06ee2 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -1330,7 +1330,7 @@ map.on('addview', function(e) {
}, 3000);
var username = e.username;
- var color = L.LOUtil.rgbToHex(e.color);
+ var color = L.LOUtil.rgbToHex(map.getViewColor(e.viewId));
if (e.viewId === map._docLayer._viewId) {
username = _('You');
color = '#000';
diff --git a/loleaflet/src/core/LOUtil.js b/loleaflet/src/core/LOUtil.js
index 4ebb9d1..ed6b718 100644
--- a/loleaflet/src/core/LOUtil.js
+++ b/loleaflet/src/core/LOUtil.js
@@ -3,6 +3,21 @@
*/
L.LOUtil = {
+ // Based on core.git's colordata.hxx: COL_AUTHOR1_DARK...COL_AUTHOR9_DARK
+ // consisting of arrays of RGB values
+ // Maybe move the color logic to separate file when it becomes complex
+ darkColors: [
+ [198, 146, 0],
+ [6, 70, 162],
+ [87, 157, 28],
+ [105, 43, 157],
+ [197, 0, 11],
+ [0, 128, 128],
+ [140, 132, 0],
+ [53, 85, 107],
+ [209, 118, 0]
+ ],
+
startSpinner: function (spinnerCanvas, spinnerSpeed) {
var spinnerInterval;
spinnerCanvas.width = 50;
@@ -28,6 +43,11 @@ L.LOUtil = {
return spinnerInterval;
},
+ getViewIdHexColor: function(viewId) {
+ var color = this.darkColors[(viewId + 1) % this.darkColors.length];
+ return (color[2] | (color[1] << 8) | (color[0] << 16));
+ },
+
rgbToHex: function(color) {
return '#' + ('000000' + color.toString(16)).slice(-6);
}
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index c6d2f71..70fc83b 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -130,7 +130,7 @@ L.Map = L.Evented.extend({
addView: function(viewid, username, color) {
this._viewInfo[viewid] = {'username': username, 'color': color};
- this.fire('addview', {viewId: viewid, username: username, color: color});
+ this.fire('addview', {viewId: viewid, username: username});
},
removeView: function(viewid) {
@@ -144,6 +144,10 @@ L.Map = L.Evented.extend({
},
getViewColor: function(viewid) {
+ if (this._docLayer._docType !== 'text') {
+ return L.LOUtil.getViewIdHexColor(viewid);
+ }
+
return this._viewInfo[viewid].color;
},
commit 0f3363b6ad310f70081ac5d1e4514b99758ff09a
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Mon Oct 10 17:13:02 2016 +0530
loleaflet: Fix incorrect reference to username
Change-Id: Ibd6433c862eaf5f5fe57244180691ef8b08e3fbb
(cherry picked from commit 176367b40844038adabc8e82e076c011d6000f98)
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 38619f6..c6d2f71 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -134,7 +134,7 @@ L.Map = L.Evented.extend({
},
removeView: function(viewid) {
- var username = this._viewInfo[viewid];
+ var username = this._viewInfo[viewid].username;
delete this._viewInfo[viewid];
this.fire('removeview', {viewId: viewid, username: username});
},
commit ac6edaf3954054ccfcc78c67bf6bc6b6c9519cfb
Author: Tor Lillqvist <tml at collabora.com>
Date: Mon Oct 10 13:15:15 2016 +0300
Bin dead code
ClientSession::isLoadFailed() was not used anywhere. As a fallout, the
_loadFailed field and setLoadFailed() member function became useless,
too.
(cherry picked from commit 44d7f26c89a29b0c03137edb6b1b4bf49518ea78)
diff --git a/loolwsd/ClientSession.cpp b/loolwsd/ClientSession.cpp
index e4623ff..f3acf98 100644
--- a/loolwsd/ClientSession.cpp
+++ b/loolwsd/ClientSession.cpp
@@ -41,7 +41,6 @@ ClientSession::ClientSession(const std::string& id,
LOOLSession(id, Kind::ToClient, ws),
_docBroker(std::move(docBroker)),
_isReadOnly(readOnly),
- _loadFailed(false),
_loadPart(-1)
{
Log::info("ClientSession ctor [" + getName() + "].");
diff --git a/loolwsd/ClientSession.hpp b/loolwsd/ClientSession.hpp
index 3be6277..926d250 100644
--- a/loolwsd/ClientSession.hpp
+++ b/loolwsd/ClientSession.hpp
@@ -50,13 +50,6 @@ public:
_saveAsQueue.put(url);
}
- bool isLoadFailed() const { return _loadFailed; }
- void setLoadFailed(const std::string& reason)
- {
- Log::warn("Document load failed: " + reason);
- _loadFailed = true;
- }
-
std::shared_ptr<DocumentBroker> getDocumentBroker() const { return _docBroker; }
private:
@@ -88,8 +81,6 @@ private:
/// Store URLs of completed 'save as' documents.
MessageQueue _saveAsQueue;
- /// Marks if document loading failed.
- bool _loadFailed;
int _loadPart;
};
diff --git a/loolwsd/PrisonerSession.cpp b/loolwsd/PrisonerSession.cpp
index c40e4da..ccedaec 100644
--- a/loolwsd/PrisonerSession.cpp
+++ b/loolwsd/PrisonerSession.cpp
@@ -105,7 +105,7 @@ bool PrisonerSession::_handleInput(const char *buffer, int length)
errorKind == "wrongpassword")
{
forwardToPeer(_peer, buffer, length, isBinary);
- peer->setLoadFailed(errorKind);
+ Log::warn("Document load failed: " + errorKind);
return false;
}
}
commit d2070e834946fdd6fccb5bf0e140b576d8f2d55d
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Oct 6 20:07:53 2016 +0530
loleaflet: Use view colors directly from core
Change-Id: I2fdffd6dd0823a77ff52e40150a81db4b261ec81
(cherry picked from commit 0ad39593d02e139e5f0bba0b8262d7c12563663a)
diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 49407af..3c51cb4 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -1330,7 +1330,7 @@ map.on('addview', function(e) {
}, 3000);
var username = e.username;
- var color = L.LOUtil.getViewIdHexColor(e.viewId);
+ var color = L.LOUtil.rgbToHex(e.color);
if (e.viewId === map._docLayer._viewId) {
username = _('You');
color = '#000';
diff --git a/loleaflet/src/core/LOUtil.js b/loleaflet/src/core/LOUtil.js
index 24c516b..4ebb9d1 100644
--- a/loleaflet/src/core/LOUtil.js
+++ b/loleaflet/src/core/LOUtil.js
@@ -3,20 +3,6 @@
*/
L.LOUtil = {
- // Based on core.git's colordata.hxx: COL_AUTHOR1_DARK...COL_AUTHOR9_DARK
- // consisting of arrays of RGB values
- // Maybe move the color logic to separate file when it becomes complex
- darkColors: [
- [198, 146, 0],
- [87, 157, 28],
- [105, 43, 157],
- [197, 0, 11],
- [0, 128, 128],
- [140, 132, 0],
- [53, 85, 107],
- [209, 118, 0]
- ],
-
startSpinner: function (spinnerCanvas, spinnerSpeed) {
var spinnerInterval;
spinnerCanvas.width = 50;
@@ -42,9 +28,7 @@ L.LOUtil = {
return spinnerInterval;
},
- getViewIdHexColor: function(viewId) {
- var color = this.darkColors[(viewId + 1) % this.darkColors.length];
- var hex = color[2] | (color[1] << 8) | (color[0] << 16);
- return '#' + ('000000' + hex.toString(16)).slice(-6);
+ rgbToHex: function(color) {
+ return '#' + ('000000' + color.toString(16)).slice(-6);
}
};
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index a5aad09..452a93c 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -682,7 +682,7 @@ L.TileLayer = L.GridLayer.extend({
if (!this._isEmptyRectangle(this._cellViewCursors[viewId].bounds) && this._selectedPart === viewPart) {
if (!cellViewCursorMarker) {
- var borderColor = L.LOUtil.getViewIdHexColor(viewId);
+ var borderColor = L.LOUtil.rgbToHex(this._map.getViewColor(viewId));
cellViewCursorMarker = L.rectangle(this._cellViewCursors[viewId].bounds, {fill: false, color: borderColor, weight: 2});
this._cellViewCursors[viewId].marker = cellViewCursorMarker;
cellViewCursorMarker.bindPopup(this._map.getViewName(viewId), {autoClose: false, autoPan: false, borderColor: borderColor});
@@ -714,8 +714,8 @@ L.TileLayer = L.GridLayer.extend({
this._onUpdateViewCursor(viewId);
},
- _addView: function(viewId, username) {
- this._map.addView(viewId, username);
+ _addView: function(viewId, username, color) {
+ this._map.addView(viewId, username, color);
//TODO: We can initialize color and other properties here.
if (typeof this._viewCursors[viewId] !== 'undefined') {
@@ -755,7 +755,7 @@ L.TileLayer = L.GridLayer.extend({
var viewIds = [];
for (var viewInfoIdx in viewInfo) {
if (!(parseInt(viewInfo[viewInfoIdx].id) in this._map._viewInfo)) {
- this._addView(viewInfo[viewInfoIdx].id, viewInfo[viewInfoIdx].username);
+ this._addView(viewInfo[viewInfoIdx].id, viewInfo[viewInfoIdx].username, viewInfo[viewInfoIdx].color);
}
viewIds.push(viewInfo[viewInfoIdx].id);
}
@@ -1235,7 +1235,7 @@ L.TileLayer = L.GridLayer.extend({
(this._docType === 'text' || this._selectedPart === viewPart)) {
if (!viewCursorMarker) {
var viewCursorOptions = {
- color: L.LOUtil.getViewIdHexColor(viewId),
+ color: L.LOUtil.rgbToHex(this._map.getViewColor(viewId)),
blink: false,
header: true, // we want a 'hat' to our view cursors (which will contain view user names)
headerTimeout: 3000, // hide after some interval
@@ -1272,7 +1272,7 @@ L.TileLayer = L.GridLayer.extend({
viewSelection = new L.Polygon(viewPolygons, {
pointerEvents: 'none',
- fillColor: L.LOUtil.getViewIdHexColor(viewId),
+ fillColor: L.LOUtil.rgbToHex(this._map.getViewColor(viewId)),
fillOpacity: 0.25,
weight: 2,
opacity: 0.25
@@ -1293,7 +1293,7 @@ L.TileLayer = L.GridLayer.extend({
if (!this._isEmptyRectangle(viewBounds) &&
(this._docType === 'text' || this._selectedPart === viewPart)) {
if (!viewMarker) {
- var color = L.LOUtil.getViewIdHexColor(viewId);
+ var color = L.LOUtil.rgbToHex(this._map.getViewColor(viewId));
viewMarker = L.rectangle(viewBounds, {
pointerEvents: 'auto',
fill: false,
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 7d2dfac..38619f6 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -120,14 +120,17 @@ L.Map = L.Evented.extend({
// View info (user names and view ids)
this._viewInfo = {};
+
+ // View color map
+ this._viewColors = {};
},
// public methods that modify map state
- addView: function(viewid, username) {
- this._viewInfo[viewid] = username;
- this.fire('addview', {viewId: viewid, username: username});
+ addView: function(viewid, username, color) {
+ this._viewInfo[viewid] = {'username': username, 'color': color};
+ this.fire('addview', {viewId: viewid, username: username, color: color});
},
removeView: function(viewid) {
@@ -137,7 +140,11 @@ L.Map = L.Evented.extend({
},
getViewName: function(viewid) {
- return this._viewInfo[viewid];
+ return this._viewInfo[viewid].username;
+ },
+
+ getViewColor: function(viewid) {
+ return this._viewInfo[viewid].color;
},
// replaced by animation-powered implementation in Map.PanAnimation.js
commit 1979d96ec2549490b59faa9c2205ba84a0913a09
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Oct 6 20:08:24 2016 +0530
loolwsd: Forward 'color' property in 'viewinfo' message to client
Change-Id: Id7d28a46cacd662aeb371805509e5a81b90b9c90
(cherry picked from commit 587c0e5222def90659ec5959352c56eed0df27b5)
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 852be7a..089b695 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -874,7 +874,7 @@ private:
}
return viewInfo;
- };
+ }
std::mutex& getMutex() override
{
@@ -891,6 +891,7 @@ private:
{
// Store the list of viewid, username mapping in a map
std::map<int, std::string> viewInfoMap = getViewInfo();
+ std::map<std::string, int> viewColorsMap = getViewColors();
std::unique_lock<std::mutex> lock(_mutex);
// Double check if list of viewids from core and our list matches,
@@ -901,7 +902,7 @@ private:
{
Object::Ptr viewInfoObj = new Object();
viewInfoObj->set("id", viewId);
-
+ int color = 0;
if (viewInfoMap.find(viewId) == viewInfoMap.end())
{
Log::error("No username found for viewId [" + std::to_string(viewId) + "].");
@@ -910,7 +911,12 @@ private:
else
{
viewInfoObj->set("username", viewInfoMap[viewId]);
+ if (viewColorsMap.find(viewInfoMap[viewId]) != viewColorsMap.end())
+ {
+ color = viewColorsMap[viewInfoMap[viewId]];
+ }
}
+ viewInfoObj->set("color", color);
viewInfoArray->set(arrayIndex++, viewInfoObj);
}
@@ -931,6 +937,49 @@ private:
private:
+ // Get the color value for all author names from the core
+ std::map<std::string, int> getViewColors()
+ {
+ std::string colorValues;
+ std::map<std::string, int> viewColors;
+
+ {
+ auto lock(_loKitDocument->getLock());
+
+ char* pValues = _loKitDocument->getCommandValues(".uno:TrackedChangeAuthors");
+ colorValues = std::string(pValues == nullptr ? "" : pValues);
+ std::free(pValues);
+ }
+
+ try
+ {
+ if (!colorValues.empty())
+ {
+ Poco::JSON::Parser parser;
+ auto root = parser.parse(colorValues).extract<Poco::JSON::Object::Ptr>();
+ if (root->get("authors").type() == typeid(Poco::JSON::Array::Ptr))
+ {
+ auto authorsArray = root->get("authors").extract<Poco::JSON::Array::Ptr>();
+ for (auto& authorVar: *authorsArray)
+ {
+ auto authorObj = authorVar.extract<Poco::JSON::Object::Ptr>();
+ auto authorName = authorObj->get("name").convert<std::string>();
+ auto colorValue = authorObj->get("color").convert<int>();
+ viewColors[authorName] = colorValue;
+ }
+ }
+ }
+ }
+ catch(const Exception& exc)
+ {
+ Log::error() << "Poco Exception: " << exc.displayText()
+ << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
+ << Log::end;
+ }
+
+ return viewColors;
+ }
+
std::shared_ptr<lok::Document> load(const std::string& sessionId,
const std::string& uri,
const std::string& userName,
commit b9ca4dc7365642a271a8aaba693f86eb688cf0cb
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Oct 9 17:18:29 2016 -0400
loolwsd: kill Connection object in child
Change-Id: Ic4d0d3e7286272a0765b299824dfa3556fe56f4b
Reviewed-on: https://gerrit.libreoffice.org/29652
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit e0ff6eef6b636789b0f7e849df77a6047fec5bae)
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 95d3f8c..852be7a 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -258,123 +258,6 @@ namespace
#endif
}
-/// Connection thread with a client (via WSD).
-class Connection: public Runnable
-{
-public:
- Connection(std::shared_ptr<ChildSession> session,
- std::shared_ptr<WebSocket> ws) :
- _sessionId(session->getId()),
- _session(std::move(session)),
- _ws(std::move(ws)),
- _threadMutex(),
- _joined(false)
- {
- Log::info("Connection ctor in child for " + _sessionId);
- }
-
- ~Connection()
- {
- Log::info("~Connection dtor in child for " + _sessionId);
- stop();
- join();
- }
-
- const std::string& getSessionId() const { return _sessionId; };
- std::shared_ptr<WebSocket> getWebSocket() const { return _ws; }
- std::shared_ptr<ChildSession> getSession() { return _session; }
-
- void start()
- {
- _thread.start(*this);
-
- // Busy-wait until we run.
- // This is important to make sure we can process
- // callbacks, which if we're late to start will
- // be dropped. No need for async notification here.
- constexpr auto delay = COMMAND_TIMEOUT_MS / 20;
- for (auto i = 0; i < 20 && !isRunning(); ++i)
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(delay));
- }
- }
-
- bool isRunning()
- {
- return _thread.isRunning();
- }
-
- void stop()
- {
- // What should we do here?
- }
-
- void join()
- {
- // The thread is joinable only once.
- std::unique_lock<std::mutex> lock(_threadMutex);
- if (!_joined)
- {
- _thread.join();
- _joined = true;
- }
- }
-
- void run() override
- {
- Util::setThreadName("kit_ws_" + _sessionId);
-
- Log::debug("Thread started.");
- try
- {
- IoUtil::SocketProcessor(_ws,
- [this](const std::vector<char>& payload)
- {
- if (!_session->handleInput(payload.data(), payload.size()))
- {
- Log::info("Socket handler flagged for finishing.");
- return false;
- }
-
- return true;
- },
- [this]() { _session->closeFrame(); },
- []() { return !!TerminationFlag; });
-
- if (_session->isCloseFrame())
- {
- Log::trace("Normal close handshake.");
- _ws->shutdown();
- }
- else
- {
- Log::trace("Abnormal close handshake.");
- _ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY, SERVICE_UNAVALABLE_INTERNAL_ERROR);
- }
- }
- catch (const Exception& exc)
- {
- Log::error() << "Connection::run: Exception: " << exc.displayText()
- << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
- << Log::end;
- }
- catch (const std::exception& exc)
- {
- Log::error(std::string("Connection::run: Exception: ") + exc.what());
- }
-
- Log::debug("Thread finished.");
- }
-
-private:
- const std::string _sessionId;
- Thread _thread;
- std::shared_ptr<ChildSession> _session;
- std::shared_ptr<WebSocket> _ws;
- std::mutex _threadMutex;
- std::atomic<bool> _joined;
-};
-
/// A document container.
/// Owns LOKitDocument instance and connections.
/// Manages the lifetime of a document.
@@ -464,10 +347,10 @@ public:
if (!_sessions.emplace(sessionId, session).second)
{
- Log::error("Connection already exists for child: " + _jailId + ", session: " + sessionId);
+ Log::error("Session already exists for child: " + _jailId + ", session: " + sessionId);
}
- Log::debug("Connections: " + std::to_string(_sessions.size()));
+ Log::debug("Sessions: " + std::to_string(_sessions.size()));
return true;
}
catch (const std::exception& ex)
@@ -539,7 +422,7 @@ public:
/// Returns true if at least one *live* connection exists.
/// Does not consider user activity, just socket status.
- bool hasConnections()
+ bool hasSessions()
{
// -ve values for failure.
return purgeSessions() != 0;
@@ -550,7 +433,7 @@ public:
bool canDiscard()
{
//TODO: Implement proper time-out on inactivity.
- return !hasConnections();
+ return !hasSessions();
}
/// Set Document password for given URL
@@ -1296,7 +1179,7 @@ private:
}
else
{
- Log::error() << "Connection thread for session " << session->getId() << " for view "
+ Log::error() << "Session thread for session " << session->getId() << " for view "
<< viewId << " is not running. Dropping [" << LOKitHelper::kitCallbackTypeToString(type)
<< "] payload [" << payload << "]." << Log::end;
}
commit 9ebdc07e5d7e9aaebfa02f4e254b1b7eeec88382
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Oct 9 17:05:24 2016 -0400
loolwsd: cleanup of Connection in ChildSession
Change-Id: I07636163df7b2973dada55b9704abf7105ad285f
Reviewed-on: https://gerrit.libreoffice.org/29651
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit e33eff4abdc4a3145b5bf7a9b6def2fce63d64a6)
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 17f7f3f..95d3f8c 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -428,62 +428,21 @@ public:
_tileQueue->put("eof");
_callbackThread.join();
-
- // Flag all connections to stop.
- for (auto aIterator : _connections)
- {
- aIterator.second->stop();
- }
-
- // Destroy all connections and views.
- for (auto aIterator : _connections)
- {
- try
- {
- // stop all websockets
- if (aIterator.second->isRunning())
- {
- std::shared_ptr<WebSocket> ws = aIterator.second->getWebSocket();
- if (ws)
- {
- ws->shutdownReceive();
- aIterator.second->join();
- }
- }
- }
- catch(NetException& exc)
- {
- Log::error() << "Document::~Document: " << exc.displayText()
- << (exc.nested() ? " (" + exc.nested()->displayText() + ")" : "")
- << Log::end;
- }
- }
-
- // Destroy all connections and views.
- _connections.clear();
}
const std::string& getUrl() const { return _url; }
- bool createSession(const std::string& sessionId, const unsigned intSessionId)
+ bool createSession(const std::string& sessionId)
{
std::unique_lock<std::mutex> lock(_mutex);
try
{
- const auto& it = _connections.find(intSessionId);
- if (it != _connections.end())
+ const auto& it = _sessions.find(sessionId);
+ if (it != _sessions.end())
{
- // found item, check if still running
- if (it->second->isRunning())
- {
- Log::warn("Session [" + sessionId + "] is already running.");
- return true;
- }
-
- // Restore thread. TODO: Review this logic.
- Log::warn("Session [" + sessionId + "] is not running. Restoring.");
- _connections.erase(intSessionId);
+ Log::warn("Session [" + sessionId + "] is already running.");
+ return true;
}
Log::info() << "Creating " << (_clientViews ? "new" : "first")
@@ -503,18 +462,12 @@ public:
auto session = std::make_shared<ChildSession>(sessionId, ws, _jailId, *this);
- auto thread = std::make_shared<Connection>(session, ws);
- const auto aInserted = _connections.emplace(intSessionId, thread);
- if (aInserted.second)
- {
- thread->start();
- }
- else
+ if (!_sessions.emplace(sessionId, session).second)
{
Log::error("Connection already exists for child: " + _jailId + ", session: " + sessionId);
}
- Log::debug("Connections: " + std::to_string(_connections.size()));
+ Log::debug("Connections: " + std::to_string(_sessions.size()));
return true;
}
catch (const std::exception& ex)
@@ -531,7 +484,7 @@ public:
{
std::vector<std::shared_ptr<ChildSession>> deadSessions;
size_t numRunning = 0;
- size_t num_connections = 0;
+ size_t num_sessions = 0;
{
std::unique_lock<std::mutex> lock(_mutex, std::defer_lock);
if (!lock.try_lock())
@@ -544,20 +497,20 @@ public:
// bluntly exit, no need to clean up our own data structures. Also, there is a bug that
// causes the deadSessions.clear() call below to crash in some situations when the last
// session is being removed.
- for (auto it = _connections.cbegin(); it != _connections.cend(); ++it)
+ for (auto it = _sessions.cbegin(); it != _sessions.cend(); ++it)
{
- if (it->second->isRunning())
+ if (!it->second->isCloseFrame())
numRunning++;
}
if (numRunning > 0)
{
- for (auto it = _connections.cbegin(); it != _connections.cend(); )
+ for (auto it = _sessions.cbegin(); it != _sessions.cend(); )
{
- if (!it->second->isRunning())
+ if (it->second->isCloseFrame())
{
- deadSessions.push_back(it->second->getSession());
- it = _connections.erase(it);
+ deadSessions.push_back(it->second);
+ it = _sessions.erase(it);
}
else
{
@@ -566,7 +519,7 @@ public:
}
}
- num_connections = _connections.size();
+ num_sessions = _sessions.size();
}
if (numRunning == 0)
@@ -581,7 +534,7 @@ public:
// and the dtor tries to take its lock (which is taken).
deadSessions.clear();
- return num_connections;
+ return num_sessions;
}
/// Returns true if at least one *live* connection exists.
@@ -1027,11 +980,11 @@ private:
std::unique_lock<std::mutex> lock(_mutex);
std::map<int, std::string> viewInfo;
- for (auto& connection : _connections)
+ for (auto& pair : _sessions)
{
- if (connection.second->isRunning())
+ const auto session = pair.second;
+ if (!session->isCloseFrame())
{
- const auto session = connection.second->getSession();
const auto viewId = session->getViewId();
viewInfo[viewId] = session->getViewUserName();
}
@@ -1083,15 +1036,12 @@ private:
viewInfoArray->stringify(ossViewInfo);
// Broadcast updated viewinfo to all _active_ connections
- for (auto& connectionIt: _connections)
+ for (auto& pair : _sessions)
{
- if (connectionIt.second->isRunning())
+ const auto session = pair.second;
+ if (!session->isCloseFrame() && session->isActive())
{
- auto session = connectionIt.second->getSession();
- if (session->isActive())
- {
- session->sendTextFrame("viewinfo: " + ossViewInfo.str());
- }
+ session->sendTextFrame("viewinfo: " + ossViewInfo.str());
}
}
}
@@ -1105,15 +1055,14 @@ private:
const std::string& renderOpts,
const bool haveDocPassword)
{
- const unsigned intSessionId = Util::decodeId(sessionId);
- const auto it = _connections.find(intSessionId);
- if (it == _connections.end() || !it->second)
+ const auto it = _sessions.find(sessionId);
+ if (it == _sessions.end() || !it->second)
{
Log::error("Cannot find session [" + sessionId + "].");
return nullptr;
}
- auto session = it->second->getSession();
+ auto session = it->second;
int viewId = 0;
std::unique_lock<std::mutex> lockLokDoc;
@@ -1257,21 +1206,20 @@ private:
Log::trace("Forwarding payload to " + prefix + ' ' + message);
std::string name;
- std::string value;
- if (LOOLProtocol::parseNameValuePair(prefix, name, value, '-') && name == "child")
+ std::string viewId;
+ if (LOOLProtocol::parseNameValuePair(prefix, name, viewId, '-') && name == "child")
{
- const unsigned viewId = Util::decodeId(value);
- const auto it = _connections.find(viewId);
- if (it != _connections.end())
+ const auto it = _sessions.find(viewId);
+ if (it != _sessions.end())
{
if (message == "disconnect")
{
- Log::debug("Removing ChildSession " + value);
- _connections.erase(it);
+ Log::debug("Removing ChildSession " + viewId);
+ _sessions.erase(it);
return true;
}
- auto session = it->second->getSession();
+ auto session = it->second;
if (session)
{
return session->handleInput(message.data(), message.size());
@@ -1336,19 +1284,19 @@ private:
// Forward the callback to the same view, demultiplexing is done by the LibreOffice core.
// TODO: replace with a map to be faster.
bool isFound = false;
- for (auto& it : _connections)
+ for (auto& it : _sessions)
{
- auto session = it.second->getSession();
+ auto session = it.second;
if (session && ((session->getViewId() == viewId) || (viewId == -1)))
{
- if (it.second->isRunning())
+ if (!it.second->isCloseFrame())
{
isFound = true;
session->loKitCallback(type, payload);
}
else
{
- Log::error() << "Connection thread for session " << it.second->getSessionId() << " for view "
+ Log::error() << "Connection thread for session " << session->getId() << " for view "
<< viewId << " is not running. Dropping [" << LOKitHelper::kitCallbackTypeToString(type)
<< "] payload [" << payload << "]." << Log::end;
}
@@ -1404,7 +1352,7 @@ private:
std::condition_variable _cvLoading;
std::atomic_size_t _isLoading;
std::map<int, std::unique_ptr<CallbackDescriptor>> _viewIdToCallbackDescr;
- std::map<unsigned, std::shared_ptr<Connection>> _connections;
+ std::map<std::string, std::shared_ptr<ChildSession>> _sessions;
Poco::Thread _callbackThread;
std::atomic_size_t _clientViews;
};
@@ -1628,7 +1576,6 @@ void lokit_main(const std::string& childRoot,
else if (tokens[0] == "session")
{
const std::string& sessionId = tokens[1];
- const unsigned intSessionId = Util::decodeId(sessionId);
const std::string& docKey = tokens[2];
std::string url;
@@ -1642,7 +1589,7 @@ void lokit_main(const std::string& childRoot,
// Validate and create session.
if (!(url == document->getUrl() &&
- document->createSession(sessionId, intSessionId)))
+ document->createSession(sessionId)))
{
Log::debug("CreateSession failed.");
}
commit 5a4644e881453f2d68b0d8bf24192636e17c43fa
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Oct 9 16:37:13 2016 -0400
loolwsd: unload child view when client disconnects
Using a new internal command, when a client disconnects
an internal 'disconnect' message is dispatched so
the child process cleans up the ChildSession in question.
Change-Id: I34166ad59e84ae389a3913bd2430fe537225bb4b
Reviewed-on: https://gerrit.libreoffice.org/29650
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit 4fa7e53eaeb43233ac039525b58eb8c588968019)
diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp
index 02686fa..4e7e618 100644
--- a/loolwsd/DocumentBroker.cpp
+++ b/loolwsd/DocumentBroker.cpp
@@ -441,6 +441,10 @@ size_t DocumentBroker::removeSession(const std::string& id)
if (it != _sessions.end())
{
_sessions.erase(it);
+
+ // Let the child know the client has disconnected.
+ const std::string msg("child-" + id + " disconnect");
+ _childProcess->getWebSocket()->sendFrame(msg.data(), msg.size());
}
return _sessions.size();
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 3bb689d..17f7f3f 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -1264,6 +1264,13 @@ private:
const auto it = _connections.find(viewId);
if (it != _connections.end())
{
+ if (message == "disconnect")
+ {
+ Log::debug("Removing ChildSession " + value);
+ _connections.erase(it);
+ return true;
+ }
+
auto session = it->second->getSession();
if (session)
{
diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt
index 418986d..d617354 100644
--- a/loolwsd/protocol.txt
+++ b/loolwsd/protocol.txt
@@ -373,6 +373,24 @@ saveas: url=<url>
<url> is a URL of the destination, encoded. Sent from the child to the
parent after a saveAs() completed.
+client-<sessionId> <Payload Message>
+
+ Forwarding message between a child and its parent session.
+ The payload message is forwarded to the ClientSession.
+
+parent -> child
+===============
+
+child-<sessionId> <Payload Message>
+
+ Forwarding message between a parent and its child session.
+ The payload message is forwarded to the ChildSession.
+
+disconnect
+
+ Signals to the child that the client for the respective connection
+ has disconnected.
+
Admin console
===============
commit f63d137d5348d7f5782a805ce9ec02f799f0ae3e
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Oct 9 13:42:30 2016 -0400
loolwsd: fix convert-to handling
Change-Id: I24b8c0b7129bee2692696809613ee49a38024c98
Reviewed-on: https://gerrit.libreoffice.org/29649
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit 1edd37ea2dbe1e3d140115396b85bc09be90af4b)
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 2cbfd88..2b3b205 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -432,7 +432,9 @@ private:
auto uriPublic = DocumentBroker::sanitizeURI(fromPath);
const auto docKey = DocumentBroker::getDocKey(uriPublic);
+ Log::debug("New DocumentBroker for docKey [" + docKey + "].");
auto docBroker = std::make_shared<DocumentBroker>(uriPublic, docKey, LOOLWSD::ChildRoot, child);
+ child->setDocumentBroker(docBroker);
// This lock could become a bottleneck.
// In that case, we can use a pool and index by publicPath.
@@ -474,14 +476,24 @@ private:
session->handleInput(saveas.data(), saveas.size());
// Send it back to the client.
- Poco::URI resultURL(session->getSaveAsUrl(COMMAND_TIMEOUT_MS));
- if (!resultURL.getPath().empty())
+ try
+ {
+ Poco::URI resultURL(session->getSaveAsUrl(COMMAND_TIMEOUT_MS));
+ Log::trace("Save-as URL: " + resultURL.toString());
+
+ if (!resultURL.getPath().empty())
+ {
+ const std::string mimeType = "application/octet-stream";
+ std::string encodedFilePath;
+ URI::encode(resultURL.getPath(), "", encodedFilePath);
+ Log::trace("Sending file: " + encodedFilePath);
+ response.sendFile(encodedFilePath, mimeType);
+ sent = true;
+ }
+ }
+ catch (const std::exception& ex)
{
- const std::string mimeType = "application/octet-stream";
- std::string encodedFilePath;
- URI::encode(resultURL.getPath(), "", encodedFilePath);
- response.sendFile(encodedFilePath, mimeType);
- sent = true;
+ Log::error(std::string("Failed to get save-as url: ") + ex.what());
}
lock.lock();
@@ -495,6 +507,8 @@ private:
{
Log::error("Multiple sessions during conversion. " + std::to_string(sessionsCount) + " sessions remain.");
}
+
+ session->shutdownPeer(WebSocket::WS_NORMAL_CLOSE, "");
}
// Clean up the temporary directory the HTMLForm ctor created.
commit 3ef7835ddbc0de042496d2c0221f794cd10da0a0
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Oct 9 11:59:00 2016 -0400
loolwsd: support timeout on MessageQueue get
Change-Id: Iaad39aaa06c59cdacdd4a864599ef6a4a12976f8
Reviewed-on: https://gerrit.libreoffice.org/29648
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit 366e0e21d5733808fda7080a013bbb6c4096b669)
diff --git a/loolwsd/ClientSession.hpp b/loolwsd/ClientSession.hpp
index e9bc176..3be6277 100644
--- a/loolwsd/ClientSession.hpp
+++ b/loolwsd/ClientSession.hpp
@@ -39,9 +39,9 @@ public:
* Return the URL of the saved-as document when it's ready. If called
* before it's ready, the call blocks till then.
*/
- std::string getSaveAsUrl()
+ std::string getSaveAsUrl(const unsigned timeoutMs)
{
- const auto payload = _saveAsQueue.get();
+ const auto payload = _saveAsQueue.get(timeoutMs);
return std::string(payload.data(), payload.size());
}
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 1889987..2cbfd88 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -474,8 +474,7 @@ private:
session->handleInput(saveas.data(), saveas.size());
// Send it back to the client.
- //TODO: Should have timeout to avoid waiting forever.
- Poco::URI resultURL(session->getSaveAsUrl());
+ Poco::URI resultURL(session->getSaveAsUrl(COMMAND_TIMEOUT_MS));
if (!resultURL.getPath().empty())
{
const std::string mimeType = "application/octet-stream";
diff --git a/loolwsd/MessageQueue.cpp b/loolwsd/MessageQueue.cpp
index ffa5f79..3729018 100644
--- a/loolwsd/MessageQueue.cpp
+++ b/loolwsd/MessageQueue.cpp
@@ -32,10 +32,23 @@ void MessageQueue::put(const Payload& value)
_cv.notify_one();
}
-MessageQueue::Payload MessageQueue::get()
+MessageQueue::Payload MessageQueue::get(const unsigned timeoutMs)
{
std::unique_lock<std::mutex> lock(_mutex);
- _cv.wait(lock, [this] { return wait_impl(); });
+
+ if (timeoutMs > 0)
+ {
+ if (!_cv.wait_for(lock, std::chrono::milliseconds(timeoutMs),
+ [this] { return wait_impl(); }))
+ {
+ throw std::runtime_error("Timed out waiting to get queue item.");
+ }
+ }
+ else
+ {
+ _cv.wait(lock, [this] { return wait_impl(); });
+ }
+
return get_impl();
}
diff --git a/loolwsd/MessageQueue.hpp b/loolwsd/MessageQueue.hpp
index 8ce2287..95a5654 100644
--- a/loolwsd/MessageQueue.hpp
+++ b/loolwsd/MessageQueue.hpp
@@ -43,7 +43,8 @@ public:
}
/// Thread safe obtaining of the message.
- Payload get();
+ /// timeoutMs can be 0 to signify infinity.
+ Payload get(const unsigned timeoutMs = 0);
/// Thread safe removal of all the pending messages.
void clear();
diff --git a/loolwsd/test/integration-http-server.cpp b/loolwsd/test/integration-http-server.cpp
index 6899476..25aea88 100644
--- a/loolwsd/test/integration-http-server.cpp
+++ b/loolwsd/test/integration-http-server.cpp
@@ -243,6 +243,7 @@ void HTTPServerTest::testConvertTo()
{
const auto srcPath = Util::getTempFilePath(TDOC, "hello.odt");
std::unique_ptr<Poco::Net::HTTPClientSession> session(helpers::createSession(_uri));
+ session->setTimeout(Poco::Timespan(2, 0)); // 2 seconds.
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/lool/convert-to");
Poco::Net::HTMLForm form;
commit e29de15cef68a8d7956b412b3ea5005a1cb63734
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Oct 9 11:28:22 2016 -0400
loolwsd: send child messages to client via unified wsd-kit WS
Change-Id: I237120e5a81a2e6d8772a2b6f1e98b1ba567f97e
Reviewed-on: https://gerrit.libreoffice.org/29647
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit 128cd73154894cc63cb16cc1d47c5b905cb1f7a6)
diff --git a/loolwsd/ChildSession.hpp b/loolwsd/ChildSession.hpp
index e8e23ac..d8d68bd 100644
--- a/loolwsd/ChildSession.hpp
+++ b/loolwsd/ChildSession.hpp
@@ -50,6 +50,9 @@ public:
std::mutex& getMutex() = 0;
virtual
std::shared_ptr<TileQueue>& getTileQueue() = 0;
+
+ virtual
+ bool sendTextFrame(const std::string& message) = 0;
};
/// Represents a session to the WSD process, in a Kit process. Note that this is not a singleton.
@@ -77,6 +80,20 @@ public:
void loKitCallback(const int nType, const std::string& rPayload);
+ bool sendTextFrame(const char* buffer, const int length) override
+ {
+ const auto msg = "client-" + getId() + ' ' + std::string(buffer, length);
+
+ const auto lock = getLock();
+
+ return _docManager.sendTextFrame(msg);
+ }
+
+ bool sendTextFrame(const std::string& text)
+ {
+ return sendTextFrame(text.data(), text.size());
+ }
+
private:
bool loadDocument(const char *buffer, int length, Poco::StringTokenizer& tokens);
diff --git a/loolwsd/ClientSession.hpp b/loolwsd/ClientSession.hpp
index 7508802..e9bc176 100644
--- a/loolwsd/ClientSession.hpp
+++ b/loolwsd/ClientSession.hpp
@@ -30,6 +30,7 @@ public:
bool isReadOnly() const { return _isReadOnly; }
void setPeer(const std::shared_ptr<PrisonerSession>& peer) { _peer = peer; }
+ std::shared_ptr<PrisonerSession> getPeer() const { return _peer.lock(); }
bool shutdownPeer(Poco::UInt16 statusCode, const std::string& message);
void setUserName(const std::string& userName) { _userName = userName; }
diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp
index 3201170..02686fa 100644
--- a/loolwsd/DocumentBroker.cpp
+++ b/loolwsd/DocumentBroker.cpp
@@ -756,7 +756,15 @@ bool DocumentBroker::forwardToClient(const std::string& prefix, const std::vecto
const auto it = _sessions.find(sid);
if (it != _sessions.end())
{
- return it->second->sendTextFrame(message);
+ const auto peer = it->second->getPeer();
+ if (peer)
+ {
+ return peer->handleInput(message.data(), message.size());
+ }
+ else
+ {
+ Log::warn() << "Client session [" << sid << "] has no peer to forward message: " << message << Log::end;
+ }
}
else
{
diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp
index 66ec29c..d8ccee4 100644
--- a/loolwsd/DocumentBroker.hpp
+++ b/loolwsd/DocumentBroker.hpp
@@ -64,6 +64,7 @@ public:
void setDocumentBroker(const std::shared_ptr<DocumentBroker>& docBroker)
{
+ assert(docBroker && "Invalid DocumentBroker instance.");
_docBroker = docBroker;
}
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 65f8fa2..3bb689d 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -40,6 +40,7 @@
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/NetException.h>
+#include <Poco/Net/Socket.h>
#include <Poco/Net/WebSocket.h>
#include <Poco/NotificationQueue.h>
#include <Poco/Process.h>
@@ -78,6 +79,7 @@ using Poco::Net::HTTPClientSession;
using Poco::Net::HTTPRequest;
using Poco::Net::HTTPResponse;
using Poco::Net::NetException;
+using Poco::Net::Socket;
using Poco::Net::WebSocket;
using Poco::Path;
using Poco::Process;
@@ -799,11 +801,34 @@ public:
ws->sendFrame(response.data(), length, WebSocket::FRAME_BINARY);
}
- void sendTextFrame(const std::string& message)
+ bool sendTextFrame(const std::string& message) override
{
- std::lock_guard<std::mutex> lock(_mutex);
+ try
+ {
+ if (!_ws || _ws->poll(Poco::Timespan(0), Socket::SelectMode::SELECT_ERROR))
+ {
+ Log::error("Child Doc: Bad socket while sending [" + getAbbreviatedMessage(message) + "].");
+ return false;
+ }
+
+ const auto length = message.size();
+ if (length > SMALL_MESSAGE_SIZE)
+ {
+ const std::string nextmessage = "nextmessage: size=" + std::to_string(length);
+ _ws->sendFrame(nextmessage.data(), nextmessage.size());
+ }
- _ws->sendFrame(message.data(), message.size());
+ _ws->sendFrame(message.data(), length);
+ return true;
+ }
+ catch (const Exception& exc)
+ {
+ Log::error() << "Document::sendTextFrame: "
+ << "Exception: " << exc.displayText()
+ << (exc.nested() ? "( " + exc.nested()->displayText() + ")" : "");
+ }
+
+ return false;
}
static void GlobalCallback(const int nType, const char* pPayload, void* pData)
diff --git a/loolwsd/LOOLSession.hpp b/loolwsd/LOOLSession.hpp
index 0606f4e..b07b2c6 100644
--- a/loolwsd/LOOLSession.hpp
+++ b/loolwsd/LOOLSession.hpp
@@ -42,7 +42,9 @@ public:
const std::string& getName() const { return _name; }
bool isDisconnected() const { return _disconnected; }
+ virtual
bool sendBinaryFrame(const char *buffer, int length);
+ virtual
bool sendTextFrame(const char* buffer, const int length);
bool sendTextFrame(const std::string& text)
{
diff --git a/loolwsd/test/WhiteBoxTests.cpp b/loolwsd/test/WhiteBoxTests.cpp
index d17cc22..45db538 100644
--- a/loolwsd/test/WhiteBoxTests.cpp
+++ b/loolwsd/test/WhiteBoxTests.cpp
@@ -192,6 +192,11 @@ public:
{
return _tileQueue;
}
+
+ bool sendTextFrame(const std::string& /*message*/) override
+ {
+ return true;
+ }
};
void WhiteBoxTests::testEmptyCellCursor()
commit 50926103cd6aeff2cd97f50cabadb4fba6f8694a
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Oct 9 11:27:01 2016 -0400
loolwsd: trim forwarded messages to avoid leading whitespace
Change-Id: I932baf3ec41789d89bf897fcbf25a1ee1d27f89d
Reviewed-on: https://gerrit.libreoffice.org/29646
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit 22a5db2fc09a123f9c00135f7fc44c4d257c7a9d)
diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp
index 6c6cbb8..3201170 100644
--- a/loolwsd/DocumentBroker.cpp
+++ b/loolwsd/DocumentBroker.cpp
@@ -725,7 +725,7 @@ void DocumentBroker::setModified(const bool value)
bool DocumentBroker::forwardToChild(const std::string& viewId, const char *buffer, int length)
{
const auto message = std::string(buffer, length);
- Log::warn() << "Forwarding payload to child [" << viewId << "]: " << message << Log::end;
+ Log::trace() << "Forwarding payload to child [" << viewId << "]: " << message << Log::end;
const auto it = _sessions.find(viewId);
if (it != _sessions.end())
@@ -745,8 +745,9 @@ bool DocumentBroker::forwardToChild(const std::string& viewId, const char *buffe
bool DocumentBroker::forwardToClient(const std::string& prefix, const std::vector<char>& payload)
{
- const std::string message(payload.data() + prefix.size(), payload.size() - prefix.size());
- Log::warn("Forwarding payload to client: " + message);
+ std::string message(payload.data() + prefix.size(), payload.size() - prefix.size());
+ Util::ltrim(message);
+ Log::trace("Forwarding payload to " + prefix + ' ' + message);
std::string name;
std::string sid;
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 41d39fc..65f8fa2 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -1227,8 +1227,9 @@ private:
bool forwardToChild(const std::string& prefix, const std::vector<char>& payload)
{
- const std::string message(payload.data() + prefix.size(), payload.size() - prefix.size());
- Log::trace("Forwarding payload to client: " + message);
+ std::string message(payload.data() + prefix.size(), payload.size() - prefix.size());
+ Util::ltrim(message);
+ Log::trace("Forwarding payload to " + prefix + ' ' + message);
std::string name;
std::string value;
diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp
index bd1a5a3..df4f60c 100644
--- a/loolwsd/Util.hpp
+++ b/loolwsd/Util.hpp
@@ -153,6 +153,30 @@ namespace Util
/// Return a string that is unique across processes and calls.
std::string UniqueId();
+ /// Trim spaces from the left. Just spaces.
+ inline
+ void ltrim(std::string& s)
+ {
+ const auto pos = s.find_first_not_of(" ");
+ if (pos != std::string::npos)
+ {
+ s = s.substr(pos);
+ }
+ }
+
+ /// Trim spaces from the left and copy. Just spaces.
+ inline
+ std::string ltrimmed(const std::string& s)
+ {
+ const auto pos = s.find_first_not_of(" ");
+ if (pos != std::string::npos)
+ {
+ return s.substr(pos);
+ }
+
+ return s;
+ }
+
/// Given one or more patterns to allow, and one or more to deny,
/// the match member will return true if, and only if, the subject
/// matches the allowed list, but not the deny.
commit b8a61afe9254874d725645c17f553d0601287f69
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sat Oct 8 23:51:07 2016 -0400
loolwsd: unittest cleanup
Change-Id: I90e4fa7d5377b7ecf427c87ce068efdb4bffe933
Reviewed-on: https://gerrit.libreoffice.org/29645
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit 0f2f49823ef02c9cebb32f32d4bcd4dd44e9351c)
diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp
index a6f0654..6876218 100644
--- a/loolwsd/test/httpwstest.cpp
+++ b/loolwsd/test/httpwstest.cpp
@@ -338,21 +338,9 @@ void HTTPWSTest::loadDoc(const std::string& documentURL, const std::string& test
// Don't replace with helpers, so we catch status.
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL);
auto socket = connectLOKit(_uri, request, _response, testname);
- sendTextFrame(*socket, "load url=" + documentURL, testname);
+ sendTextFrame(socket, "load url=" + documentURL, testname);
- SocketProcessor(testname, socket, [&](const std::string& msg)
- {
- const std::string prefix = "status: ";
- if (msg.find(prefix) == 0)
- {
- const auto status = msg.substr(prefix.length());
- // Might be too strict, consider something flexible instread.
- CPPUNIT_ASSERT_EQUAL(std::string("type=text parts=1 current=0 width=12808 height=16408 viewid=0"), status);
- return false;
- }
-
- return true;
- });
+ assertResponseString(socket, "status:", testname);
}
catch (const Poco::Exception& exc)
{
commit b79a5fb056ca86d225ca53486c7a5a0fcfd1ac46
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sat Oct 8 21:48:41 2016 -0400
loolwsd: cleanup of isDocumentLoaded
Change-Id: I28321bda3000b443aff4603ad438183fa6cfb2f9
Reviewed-on: https://gerrit.libreoffice.org/29644
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit 46aec10c3c71a69f6308a404aa8bbac08af42ff3)
diff --git a/loolwsd/test/helpers.hpp b/loolwsd/test/helpers.hpp
index 651e247..bed5788 100644
--- a/loolwsd/test/helpers.hpp
+++ b/loolwsd/test/helpers.hpp
@@ -106,64 +106,6 @@ void sendTextFrame(const std::shared_ptr<Poco::Net::WebSocket>& socket, const st
}
inline
-bool isDocumentLoaded(Poco::Net::WebSocket& ws, const std::string& name = "", bool isView = true)
-{
- bool isLoaded = false;
- try
- {
- int flags = 0;
- int retries = 30;
- const Poco::Timespan waitTime(1000000);
-
- ws.setReceiveTimeout(0);
- do
- {
- char buffer[READ_BUFFER_SIZE];
- if (ws.poll(waitTime, Poco::Net::Socket::SELECT_READ))
- {
- int bytes = ws.receiveFrame(buffer, sizeof(buffer), flags);
- if (bytes > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE)
- {
- std::cerr << name << "Got " << bytes << " bytes: " << LOOLProtocol::getAbbreviatedMessage(buffer, bytes) << std::endl;
- const std::string line = LOOLProtocol::getFirstLine(buffer, bytes);
- const std::string prefix = isView ? "status:" : "statusindicatorfinish:";
- if (line.find(prefix) == 0)
- {
- isLoaded = true;
- break;
- }
- }
- else
- {
- std::cerr << name << "Got " << bytes << " bytes, flags: " << std::hex << flags << std::dec << std::endl;
- break;
- }
-
- retries = 10;
- }
- else
- {
- std::cerr << "Timeout\n";
- --retries;
- }
- }
- while (retries > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
- }
- catch (const Poco::Net::WebSocketException& exc)
- {
- std::cerr << exc.message();
- }
-
- return isLoaded;
-}
-
-inline
-bool isDocumentLoaded(std::shared_ptr<Poco::Net::WebSocket>& ws, const std::string& name = "", bool isView = true)
-{
- return isDocumentLoaded(*ws, name, isView);
-}
-
-inline
Poco::Net::HTTPClientSession* createSession(const Poco::URI& uri)
{
#if ENABLE_SSL
@@ -290,7 +232,7 @@ std::vector<char> getResponseMessage(Poco::Net::WebSocket& ws, const std::string
{
if (!timedout)
{
- std::cerr << name << "Timeout " ;
+ std::cerr << name << "Timeout ";
}
else
{
@@ -341,6 +283,20 @@ std::string assertNotInResponse(T& ws, const std::string& prefix, const std::str
return res;
}
+inline
+bool isDocumentLoaded(Poco::Net::WebSocket& ws, const std::string& name = "", bool isView = true)
+{
+ const std::string prefix = isView ? "status:" : "statusindicatorfinish:";
+ const auto message = getResponseString(ws, prefix, name);
+ return LOOLProtocol::getFirstToken(message) == prefix;
+}
+
+inline
+bool isDocumentLoaded(std::shared_ptr<Poco::Net::WebSocket>& ws, const std::string& name = "", bool isView = true)
+{
+ return isDocumentLoaded(*ws, name, isView);
+}
+
// Connecting to a Kit process is managed by document broker, that it does several
// jobs to establish the bridge connection between the Client and Kit process,
// The result, it is mostly time outs to get messages in the unit test and it could fail.
commit 50c289a43425b5bf418fed2c38993a404da85dc8
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sat Oct 8 21:40:52 2016 -0400
loolwsd: cleanup of LoolKit process counter
Change-Id: I7d8bec2634b1c838cd10a8bef928ea22c2d2f549
Reviewed-on: https://gerrit.libreoffice.org/29643
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
(cherry picked from commit d7799d21a888fe0c0325531e43feb9d613739f31)
diff --git a/loolwsd/test/countloolkits.hpp b/loolwsd/test/countloolkits.hpp
index d0c479c..b96e173 100644
--- a/loolwsd/test/countloolkits.hpp
+++ b/loolwsd/test/countloolkits.hpp
@@ -61,30 +61,33 @@ int getLoolKitProcessCount()
}
}
- std::cerr << "Number of loolkit processes: " << result << std::endl;
return result;
}
static
int countLoolKitProcesses(const int expected)
{
- // Fairly random number, I don't think there is any actual reason for using exactly this repeat
- // count.
- const size_t repeat = 21;
+ std::cerr << "Waiting to have " << expected << " loolkit processes. Loolkits: ";
+
+ // Retry for about 3 seconds.
+ const auto sleepMs = static_cast<int>(POLL_TIMEOUT_MS / 3);
+ const size_t repeat = (3000 / sleepMs) + 1;
auto count = getLoolKitProcessCount();
for (size_t i = 0; i < repeat; ++i)
{
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list