Commit graph

148 commits

Author SHA1 Message Date
Mihai Varga
5085fd4e0c loolwsd: move tiles to persistent folder on save 2015-07-16 12:51:07 +03:00
Mihai Varga
2ebe9f1be1 loolwsd: format and options in 'saveas' are optional 2015-07-16 12:51:07 +03:00
Mihai Varga
675cfb8c4a loolwsd: send part names with the status message
Also disabled the status length assertion because part names
are separated by new-line characters ('\n')
2015-07-15 18:49:32 +03:00
Mihai Varga
97191d985b loolwsd: allow an extra paramater to the tile command (ID) 2015-07-14 19:46:04 +03:00
Henry Castro
bb3611399b loolwsd: Use fork but no execve 2015-07-13 10:13:06 -04:00
Mihai Varga
6d2d8361b6 loolwsd: the third argument in postUnoCommand must be null not space 2015-07-08 09:09:58 +03:00
Jan Holesovsky
767d6a0a32 Create /dev/*random in the chroot so that ssl works.
Also add the missing library to the systemplate.
2015-07-06 19:35:50 +02:00
Henry Castro
e50e302839 loolwsd: Handle file URI schema
In the file:// case, if it is on linux, hard link function is used
and copy only if hard link fails.
2015-07-04 20:46:13 -04:00
Henry Castro
d788fa92e9 loolwsd: let libreoffice handle http protocol 2015-07-03 10:04:24 -04:00
Tor Lillqvist
f4da368a52 Add a FIXME, found by looking, no time to investigate 2015-07-02 16:26:09 +03:00
Jan Holesovsky
4071022305 The payload format has changed, swap the parameters accondingly. 2015-06-25 17:03:18 +02:00
Jan Holesovsky
7c48ea1fe3 Change the tiles cache to 2-level cache.
Now we have 2 caching directories: 'persistent', and 'editing'.

The Persistent cache always represents the document as it is saved, the
Editing one caches the current edits.  The Editing state is copied to
Persistent on save.  The Editing state is destroyed on reload.
2015-06-24 22:07:58 +02:00
Mihai Varga
e8007ea405 Server getTextSelection implementation 2015-06-24 18:08:15 +03:00
Tor Lillqvist
f7a769ef28 Avoid assertion when the --lotemplate parameter ends with a slash 2015-06-17 16:52:54 +03:00
Tor Lillqvist
6804750463 Don't bother with storing a ref to Application::instance() in a variable in some places 2015-06-09 18:30:21 +03:00
Tor Lillqvist
d3f4ddd355 Use a queue also in the child processes 2015-06-09 18:30:12 +03:00
Tor Lillqvist
629ba87139 Add a "canceltiles" message to the protocol and handle it
Implementing this Was harder than I first expected. The basic idea is as
follows: The master process puts each message arriving from a client that
isn't "canceltiles" into a (client-specific) queue. A separate thread that
pulls messages from the queue at its own pace and handles them as
before. Incoming "canceltiles" messages are handled specially, though: The
queue is emptied of "tile" messages.

The above sounds simple but there are several details that were a bit tricky
to get right.
2015-06-09 18:29:48 +03:00
Tor Lillqvist
a7f2e5aa29 The buffer parameter to handleInput() can be const 2015-06-08 17:56:10 +03:00
Tor Lillqvist
a608aaee90 Add an invalidate: message that is in LOOL style with named parameters
The invalidatetiles: message as generated directly from the
LOK_CALLBACK_INVALIDATE_TILES will be dropped soon.
2015-05-29 09:44:39 +03:00
Tor Lillqvist
1b85e8eaaa Be more consistent in using 'using' 2015-05-29 08:49:49 +03:00
Tor Lillqvist
bf985624f1 Handle LOK_CALLBACK_INVALIDATE_TILES in the server too
Remove any intersecting cached tiles. It is the parent process that handles
the tile cache, so it must look for invalidatetiles: messages, too, before
passing them on to the client. To know for which part we should remove tiles,
add an "ephemeral" curpart: message that the child process sends to the parent
process before the invalidatetils: message.
2015-05-28 18:48:51 +03:00
Tor Lillqvist
f6a00edbee Use shared_ptr to the WebSockets for increased robustness
Why did I wait so long to do this? This is obviously the right thing to do, I
hope, and has a very significant impact on the robustness of the server...
2015-05-28 16:46:37 +03:00
Tor Lillqvist
d0dbc5e1dd Send a nextmessage: message also preceding a tile: message from the cache 2015-05-28 16:46:37 +03:00
Tor Lillqvist
09b261d57b Handle LOK_CALLBACK_DOCUMENT_SIZE_CHANGED even better
Just call the getStatus() function directly in the child process, which will
always cause a complete status: message to be sent to the client. No
documentsizechanged: messages now sent to the client at all.
2015-05-28 16:46:37 +03:00
Tor Lillqvist
13645eb769 There should be whitespace after the message keyword and colon 2015-05-28 12:59:11 +03:00
Tor Lillqvist
cedee8f1a9 Log the input to MasterProcessSession::handleInput() earlier 2015-05-28 12:58:08 +03:00
Tor Lillqvist
0092414470 Handle LOK_CALLBACK_DOCUMENT_SIZE_CHANGED callbacks more cleverly
When a child process sends a documentsizechanged: message to the parent, to be
forwarded to the client, parse it and update a cached status of the doucment,
if available, and send an updated status: message to the client instead.

Note that clients should not rely on getting only status: messages and never
documentsizechanged: messages, though; the cache might be cleaned at any time
even while the server is running. If there is no cached status of the document
to update and re-use, we have to forward the documentsizechanged: message as
such to the client.
2015-05-28 12:53:14 +03:00
Tor Lillqvist
84819b6f0c Improve error handling 2015-05-27 21:44:39 +03:00
Miklos Vajna
d8d054fa47 LOOLSession: PAGE_COUNT -> DOCUMENT_SIZE 2015-05-27 17:34:10 +02:00
Miklos Vajna
6453f130c0 LOOLSession: handle LOK_CALLBACK_SET_PART 2015-05-27 11:36:21 +02:00
Jan Holesovsky
029a41ba81 Fix non-debug build. 2015-05-26 10:11:06 +02:00
Henry Castro
d33d1afcf3 Added missing rectangle to invalidate cursor. 2015-05-25 00:40:08 -04:00
Tor Lillqvist
0053f18e2d Handle LOK_CALLBACK_PAGE_COUNT_CHANGED 2015-05-23 11:26:11 +01:00
Tor Lillqvist
180f8fcba0 Pass the --uid option to the child too 2015-05-22 17:42:36 +01:00
Tor Lillqvist
9af39d189a Add some fairly hackish things to make this run better on OS X 2015-05-22 14:34:21 +01:00
Tor Lillqvist
0440a908fa For some reason linking the PkgInfo file fails in OS X
No idea. Does not even work from the command line...  But after
"fixing" this, we run into other weird problems anyway. (Maybe one
needs to use lower-level (Mach) APIs for esoteric stuff like chroot?)
So, getting loolwsd to work on OS X seems unexpectedly hard even
before considering what changes might be needed to LibreOfficeKit. Oh
well.
2015-05-22 12:43:00 +01:00
Mihai Varga
c62ee92519 Search not found callback handler 2015-05-20 16:54:40 +03:00
Tor Lillqvist
058416b9d7 Handle arbitrarily large tile: messages from child to parent
The parent currently uses a fixed-size 100000 byte buffer to receive
messages. Even with a tile size of 256x256 pixels, that is not enough for some
tiles that compress badly as PNG. Add a nextmessage: message that gives the
size of the immediately following message. Send a such before each tile:
message, and handle it appropriately. The nextmessage: message is used only
from child to parent process, it is never sent to the Websocket client.

Once Poco 1.6.1 is released, this will not be necessary.
2015-05-18 11:24:32 +03:00
Tor Lillqvist
b6c36e23f3 Improve error handling for documents that can't be opened
Catch IOException when trying to copy the document and send error message.
Otherwise, the exception will just propagate up to handleRequest() and the
connection will be silently closed. Closing the connection is fine as such, I
think, but we need to send an error message first.
2015-05-12 12:44:19 +03:00
Tor Lillqvist
3e9c4d4bf3 Use a separate HTTPServer listening for child processes connnecting
Otherwise, if we use the same port number and same HTTPServer, if enough
clients try to contact us and, we won't be able to accept child processes
having been spawned.

Also add some temporary debugging output here and there to debug lifecycle
management issues.
2015-05-08 21:30:32 +03:00
Tor Lillqvist
3a23186217 If we run out of pre-spawned children, spawn one more
Just a stopgap measure so far. Clearly will need some logic to get rid of too
many children if they are just hanging around with no clients incoming. Also,
we need some sanity check not to spawn an unlimited number of children.
2015-05-08 21:30:17 +03:00
Tor Lillqvist
e22e1da038 Must use thread-local storage for the variables used by the nftw callback
Otherwise two or more linkOrCopy() functions running simultaneously will lead
to a mess.

Actually nftw() is not guaranteed to be thread-safe, I think, so we should
really use something that is, like Poco's SimpleRecursiveDirectoryIterator.
2015-05-07 20:24:14 +03:00
Tor Lillqvist
c69fc09a1b Use just one RNG for the MasterProcessSession objects
It probably is not a good idea to keep depleting the entropy source needlessly
by having a separate RNG in the preSpawn(). Use just one shared RNG and
protect access to it with a mutex.
2015-05-07 20:24:06 +03:00
Tor Lillqvist
0ca7f3129b Add code to wait for a child session to become available
Not sure it is completely correct. Lots of testing needed.
2015-05-07 16:29:36 +03:00
Tor Lillqvist
5aec1fc2f8 Register for callbacks from the LibreOfficeKit object, too
They are used for statgus indicator callbacks while loading a document. (This
is a fresh feature in LO master.)
2015-05-06 17:58:00 +03:00
Tor Lillqvist
600b5bc4d8 Log also when copying of the document is done 2015-04-30 21:05:16 +03:00
Tor Lillqvist
af400fcef4 This is cleaner 2015-04-30 18:44:27 +03:00
Tor Lillqvist
f7375bb5ba Try to be a little more robust 2015-04-30 18:03:00 +03:00
Tor Lillqvist
59055b975e Use Poco::StreamCopier, just because it looks nicer
A test program did not show any performance difference between using the
std::copy() thing, Poco::StreamCopier, or std output << input.rdbuf() trick.
2015-04-30 18:01:21 +03:00
Tor Lillqvist
8b43cd25b0 Handle file: and http: URLs 2015-04-30 15:58:13 +03:00
Tor Lillqvist
1b06290d2b Add a part parameter to the tile messages
The JS code always passes in 0 for now. The server parses the parameter and
calls LibreOfficeKitDocument::setPart() before calling paintTile().

Probably also the status, key, mouse and selection messages will need a part
number. The intent is after all that the protocol is as stateless as
possible. (So maybe we should also pass the document URL in each message?)
2015-04-27 21:30:26 +03:00
Tor Lillqvist
389815ac63 Introduce LOLProtocol::getTokenKeyword() and use it
The new function takes a map from keywords to integer values, and accepts
parameters in the form of either name=keyword, or for backward compatibility,
name='keyword'. Use it to parse the type parameter of the key, mouse,
selecttext and selectgraphic messages. This restricts the accepted keywords to
those actually valid for each message.
2015-04-27 21:12:20 +03:00
Tor Lillqvist
0019dc4943 Preserve timestamp of directories created in the jail
Needed for /usr/share/fonts so that fontconfig trusts its cache, but no harm
doing it for all directories. (Except a slight slowdown, need to see it if
has any significant impact if we would do the utime() only for directories
under /usr/share/fonts.)

Thus we need to pass the FTW_DEPTH flag to nftw() and handle FTP_DP instead of
FTP_D. We also need to make sure the directory is created also in the case of
an empty directory, for which no FTW_F callback of files inside it has been
received.

It is safest to not exit the nftw() in the FTW_SLN case.
2015-04-27 15:57:18 +03:00
Miklos Vajna
0615ce950f LOOLSession: log error if nftw() fails
Should help finding out the problem if --lotemplate is given a
non-existing directory by mistake.
2015-04-25 01:40:16 +02:00
Tor Lillqvist
b49d4d8885 Use shared_ptr and weak_ptr in attempt to make the pointer dance more robust
It was obviously very wrong to use both a unique_ptr to the
MasterProcessSession in WebSocketRequestHandler::handleRequest(), and then a
bare pointers to the peer object in the MasterProcessSession object. We got
crashes here and there related to the destructors.

Let's see if we can manage without mutexes.
2015-04-22 21:50:17 +03:00
Tor Lillqvist
eade187ebb Bin pointless logging
We logged effectively the same information a few lines earlier.
2015-04-22 21:50:04 +03:00
Tor Lillqvist
59bd08299c _childId is used only in MasterProcessSession 2015-04-22 21:49:53 +03:00
Tor Lillqvist
08f53df08a _childIdToChildSession[childId] is not used 2015-04-22 21:49:37 +03:00
Tor Lillqvist
d94b494c0c Check if the peer MasterProcessSession has a tile cache yet 2015-04-22 21:48:48 +03:00
Tor Lillqvist
54d106f47b Factor out WebSocket::shutdown() ignoring IOException 2015-04-22 21:48:42 +03:00
Tor Lillqvist
a0292468da Catch (and ignore) Poco::IOException in a couple of places
There probably are more places where I should catch those and act
appropriately. At least in these places, where the websocket connection is
already closed, or being closed, anyway, the right thing to do is just to
ignore exceptions, which are generated from attempts to write to an already
closed Poco WebSocket, for instance.
2015-04-22 21:48:14 +03:00
Tor Lillqvist
fcea475bb5 Use separate classes derived from LOOLSession for parent and child processes
Work in progress. Does not work properly yet.
2015-04-22 21:48:04 +03:00
Tor Lillqvist
a63f797fff Call shutdown on the peer's websocket when the session to the client dies
Also, seems that calling LOKitDocument::destroy() (in the child process's
LOOLSession dtor) causes crashes, avoid that. The can be little need for any
cleanup as the process is about to exit anyway, and the user profile is a
temporary one that will be binned.
2015-04-22 21:47:13 +03:00
Tor Lillqvist
39b6258aa9 Clean up the jail after the prisoner has died 2015-04-22 21:46:33 +03:00
Tor Lillqvist
27a680457e Pre-spawn a new child when we take one into use 2015-04-22 21:45:57 +03:00
Tor Lillqvist
b760359bda Terminology change: s/fork/spawn
We aren't doing any fork-but-not-exec trick anyway, just a straightforward
start of a child process.
2015-04-22 21:45:31 +03:00
Tor Lillqvist
a2e2102ad1 Call dispatchChild() only if needed 2015-04-22 21:45:22 +03:00
Tor Lillqvist
d513536cfe Must seed the RNG explicitly
Otherwise it uses a timestamp with one-second granularity as seed, and thus
most of the child processes pre-spawned at start will use the same seed, which
causes breakage.
2015-04-22 21:44:42 +03:00
Tor Lillqvist
3abb6d0307 Now the chroot etc re-work is getting closer to working
Works now for the trivial 'connect' test program. Still need to add
pre-spawning of a new child process as soon as an existing one from the pool
has been taking into use. And need to test with the actual JS client.
2015-04-22 21:44:17 +03:00
Tor Lillqvist
8800dd46e1 Fix typo and bin leftover FOO debug output 2015-04-22 21:43:55 +03:00
Tor Lillqvist
652580a761 Another intermediate commit, code still in a non-working state 2015-04-22 21:43:44 +03:00
Tor Lillqvist
0a60ea9dcc Bump Emacs fill-column to 100
The default 70 is so last century.
2015-04-22 21:43:11 +03:00
Tor Lillqvist
f9d93ea57c Work in progress: "pre-forking", chroot, etc. Non-working state
Lots of changes to the server code, LOOLWSD and LOOLSession mainly. This is an
intermediate commit.
2015-04-22 21:42:17 +03:00
Tor Lillqvist
6950f7d841 Adapt to changed LibreOfficeKitDocument::postUnoCommand() API 2015-04-22 21:41:49 +03:00
Tor Lillqvist
c72f197e71 Handle LOK_CALLBACK_STATE_CHANGED 2015-04-14 14:51:36 +03:00
Tor Lillqvist
aedea4229f Call LibreOfficeKitDocument::initializeForRendering() 2015-04-10 12:21:28 +03:00
Tor Lillqvist
06d98ec0b7 This is C++ 2015-04-10 01:25:48 +03:00
Tor Lillqvist
41f41f7af5 Have lokitclient display tiles using ImageMagick's 'display' if available
Refactor the PNG encoding of a pixmap out to Util.
2015-03-28 13:57:03 +02:00
Tor Lillqvist
56f3678b36 Add a separate include file for some helper functions 2015-03-28 13:22:15 +02:00
Tor Lillqvist
422dfd1767 Start on load testing
Add a new program, loadtest, that runs a requested number of client sessions
in parallel to a loolwsd server. A client session loads one of a list of test
documents, and does some operations on it.

Move the getTokenInteger() and getTokenString() functions out from LOOLSession
into a new namespace LOOLProtocol, as they are neeeded also in the loadtest
program.

Add, also in LOOLProtocol, functions to parse some of the messages from the
server. (In general that is done in client JavaScript code, of course; only
for testing purposes needed in C++ code.)
2015-03-26 17:04:08 +02:00
Tor Lillqvist
eb695513de Use const reference parameter 2015-03-26 17:04:08 +02:00
Tor Lillqvist
5df0766dad Return an error if the documentLoad() fails 2015-03-25 15:48:20 +02:00
Tor Lillqvist
cae997c184 Check 'tile' parameter validity 2015-03-24 18:59:23 +02:00
Tor Lillqvist
97fbe8e857 Add 'saveas' 2015-03-23 22:14:11 +02:00
Tor Lillqvist
1e734c2c0e Reduce copypasta
Handle the start of a child process when needed centrally, not in each command
handler.

Also, handle unrecognized commands always already in the parent
process. (Command syntax checks still done in child process, though.)
2015-03-20 15:53:00 +02:00
Tor Lillqvist
e05092ece2 Obviously need to handle input events etc in the child process
I need to re-factor this stuff, too much copypasta.
2015-03-20 15:52:43 +02:00
Tor Lillqvist
a3897bd906 paintTile does not take a row stride parameter any more 2015-03-20 13:18:01 +02:00
Tor Lillqvist
215fda0235 Add key and mouse event handling, uno command, and selection handling
Not "handled" here of course, just pass them on to LibreOfficeKit.
2015-03-20 13:18:01 +02:00
Tor Lillqvist
e8ea0f0d2e Use separate child processes for LibreOfficeKit
For now, each LOOL client has a separate child process (or none at all, if it
has accessed only information found in the cache). This will obviously have to
chnage to handle collaboration. Etc.

The parent process talks the same Websocket protocol with the child
processes. When there is a child process for a client, traffic from the client
is forwarded as such to the child process and vice versa.
2015-03-18 15:38:01 +02:00
Tor Lillqvist
ea01aa2002 Cache also document status 2015-03-13 14:17:51 +02:00
Tor Lillqvist
44c2ef32f5 Small fix to error handling 2015-03-13 13:59:51 +02:00
Tor Lillqvist
68fec97752 More LibreOfficeKitCallbackType values have been added 2015-03-13 11:30:23 +02:00
Tor Lillqvist
94254ec9e4 Missing break 2015-03-13 11:25:00 +02:00
Tor Lillqvist
ad3fda27af Further hacking on tile cache 2015-03-13 01:34:42 +02:00
Tor Lillqvist
076733251f No need for the DUMPPNG debugging feature any more 2015-03-12 18:58:29 +02:00
Tor Lillqvist
08583f8ebe Add first cut at caching of tiles 2015-03-12 17:26:35 +02:00
Tor Lillqvist
bf611698b2 No need for a separate 'close' request
Having a 'close' would mean being able to do a new 'open', too, which
introduces unneeded complexity, at least at this stage.

Just start a fresh WebSocket connection for each document.
2015-03-09 17:45:51 +02:00
Tor Lillqvist
ce438007b2 Rename LOOLConnectionServer to LOOLSession
That is hopefully a better name.
2015-03-09 10:02:47 +02:00
Renamed from loolwsd/LOOLConnectionServer.cpp (Browse further)