Commit graph

565 commits

Author SHA1 Message Date
Ashod Nakashian
58d9bcd685 wsd: http: map Status Codes to Reason Phrases
Change-Id: I96c953950a865fe35a17540889e4cc75c84870b1
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-22 10:09:22 -04:00
Ashod Nakashian
da07625352 wsd: http: parse the http header only
Previously, we were parsing the Status Line
and the header, both together. This of course
doesn't work when we had removed the Status
Line already. This wasn't an issue in parsing
responses from servers, but doesn't work when
parsing requests from clients (i.e. in a server).

Also, it's simpler.

Tests extended accordingly.

Change-Id: Id1c9a6385080c86b6072130fa8a169a699c42462
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-22 10:09:22 -04:00
Ashod Nakashian
b6314a6165 wsd: http: tolerate the absence of a reason phrase
Here we are more tolerant with regards to the
minimum Status Line length, since a Reason
Phrase is informative and might be omitted.

While technically it should be provided, per
the RFC, we shouldn't break when it's missing.

Change-Id: Ic702db61e5bf4272e18f09d127405033277e5943
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-22 10:09:22 -04:00
Ashod Nakashian
419e238fb7 wsd: http: better logging
Change-Id: Ic0dfe08564a1a5dd3fea5fcac93eadb21e7cb0dc
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
ea9c483a28 wsd: http: StatusLine tests
Change-Id: Iac39191b407463d2691ec3c58af2a4b4abfc6645
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
7c0851c4d4 wsd: http: support setting header fields from Request
Change-Id: I3483e20c1f54c15dbd7088f7bdb866abb7b99cf6
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
688fefcbda wsd: http: define streaming operators
Change-Id: I911951cb29fe22103076af9f082e3a6eae3c6189
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
c38e876978 wsd: minor logging improvement
Change-Id: I2fda8c023592396a937a02903e7c5260c6ccdd25
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
78fe04a58d wsd: better http poll thread name
Change-Id: I60a4ee09fcfb1bd34b44a21253ecac78f3d6830f
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
774afe1393 wsd: http::Request parser
This adds support to parse client request
on the server side.

Unit-tests included.

Change-Id: I90e9ad3007a3215682991fd2383362e1c48589a8
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
77fb416c40 wsd: http: normalize helper function API
Change-Id: I5070dd53fb6d5e38d851cb9f521f63b59353b778
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
df0ce9cc42 wsd: http: factor out whitespace check
Change-Id: Ib078b0a587ff4fd91c0d48e79e9e75b8fcc31939
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
160f87bab0 wsd: encapsulate ServerSocket::_socketFactory
Change-Id: I3d880d06d5ea537cddb4c572f3439ea6061e51bf
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Ashod Nakashian
2281ace984 wsd: http: better logging and tracing
Change-Id: Ib7ba0c2bbf0228d816403408289bdbaf52a14458
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-16 08:27:46 -04:00
Andras Timar
dd9d93de49 typo fix
Signed-off-by: Andras Timar <andras.timar@collabora.com>
Change-Id: I7c6f869be1de3b584b89999b9dc5f6085594b7f4
2021-03-14 17:54:16 +01:00
Ashod Nakashian
293d1c0a2a wsd: detect misuse of SocketPoll::startThread
There are scenarios where startThread is
called either when the thread is already
running or when it has long since finished.

Logs are added to catch them, and better
document the expected behavior in those
cases (they shouldn't happen).

Change-Id: I219a59b92c943445ec4520667a8ed6d9bd1c328d
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
0e73346d5e wsd: read -> wrote
Change-Id: I1a02b42931a1ab2202233918d542be7c2ccb9225
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
9ce552b5a5 wsd: better logging
Change-Id: I9c6bfcc22b1d80a27a4b4fa7229766d95fc62f9a
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
e6fe7c0bd0 wsd: improved thread ownership management and logging
Change-Id: I00a7dc303a873cc249ec56db0611d104557bbf45
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
8fd593c076 wsd: do more outside mutex and std::move
Change-Id: I994cc62ffee41b9d8d86748b25e27a473b124599
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
6d134c3228 wsd: log on EPIPE while writing to socket
Change-Id: I27c4df2d8e139e9da5a97acb0cb16e55501174d9
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
0cd55fde61 wsd: better socket logging
Change-Id: If7d8411b40510d4942c6ef7a1c248f587b7dbdae
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
65f71a2efb wsd: better logging of hex data dumps
And guard http data dumping with debug directives.

Change-Id: I22a725ba49bfb0399a27889ce9732dfe061e2563
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
5467a7f7ef wsd: simplify and document dumpHex
Change-Id: I636dd6548b0712a72dfc162eb7381e3e7ac18b5a
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
c4c354e7cf wsd: remove a TODO and explain rationale
Change-Id: I903ac749c4e17753136cb999df622bcaf593d479
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 19:34:02 -05:00
Ashod Nakashian
42a7607489 wsd: avoid static SocketPoll
The lifetime management of static objects
is extremely unpredictable and depends on
many variables outside of our control or
even reliable reproducibility.

Complex static objects that own threads
and other objects are doubly problematic
because of their dependency and/or
interaction with other objects.

Here we replace the static DelayPoll
instance with one we control its lifetime
in the LOOLWSD main body, such that it
is destroyed properly.

Specifically, DelayPoll's dtor  was
accessing Poco's Logging subsystem out of
order. That is, after Poco had been
destroyed.

Another advantage to this approach is that
we don't even create the DelayPoll at all
if we don't need it. The onus now is on
the user of DelayPoll to make sure they
create a Delay object with a long-enough
lifetime to encompase it use.

For completeness, here is the stacktrace:

    terminate called after throwing an instance of 'std::bad_alloc'
      what():  std::bad_alloc

    Program received signal SIGABRT, Aborted.
    __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
    51      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
    (gdb) bt
    #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
    #1  0x00007ffff613f801 in __GI_abort () at abort.c:79
    #2  0x00007ffff6d51957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    #3  0x00007ffff6d57ae6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    #4  0x00007ffff6d56b49 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    #5  0x00007ffff6d574b8 in __gxx_personality_v0 () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    #6  0x00007ffff671f573 in ?? () from /lib/x86_64-linux-gnu/libgcc_s.so.1
    #7  0x00007ffff671fad1 in _Unwind_RaiseException () from /lib/x86_64-linux-gnu/libgcc_s.so.1
    #8  0x00007ffff6d57d47 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    #9  0x00007ffff6d582dc in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    #10 0x00005555556b5927 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) [clone .isra.41] ()
    #11 0x0000555555982a14 in Poco::Message::Message(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Poco::Message::Priority) ()
    #12 0x000055555585a909 in SocketPoll::~SocketPoll (this=0x555555d10f60 <DelayPoll>, __in_chrg=<optimized out>) at net/Socket.cpp:145
    #13 0x00007ffff6142041 in __run_exit_handlers (status=0, listp=0x7ffff64ea718 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at exit.c:108
    #14 0x00007ffff614213a in __GI_exit (status=<optimized out>) at exit.c:139
    #15 0x0000555555752d78 in LOOLWSD::innerInitialize (this=<optimized out>, self=...) at wsd/LOOLWSD.cpp:1213
    #16 0x0000555555788b07 in LOOLWSD::initialize (this=<optimized out>, self=...) at wsd/LOOLWSD.hpp:432
    #17 0x00005555558dd7e4 in Poco::Util::Application::run() ()
    #18 0x00005555556b6574 in main (argc=2, argv=0x7fffffffe528) at wsd/LOOLWSD.cpp:4276

Change-Id: Ifda55fe869fa6734b9c2490da4497d2551ac21c1
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 16:44:09 -05:00
Ashod Nakashian
e9cf4681a2 wsd: move TerminatingPoll to Socket.hpp
Makes it accessible to more code.

Change-Id: I73dd1895defe47ae40873b6155203768055206ec
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-13 16:44:09 -05:00
Ashod Nakashian
30fe875419 wsd: better http::Session::create API
Change-Id: I8d89bfc3ed482b775029ef23527e02f379051796
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-11 09:15:40 -05:00
Ashod Nakashian
6e7c5b6013 wsd: improved SocketPoll start-thread guard
Change-Id: I92e2bcf4efacd67fc336ab40194d8cc51da7e4f4
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-11 09:15:40 -05:00
Ashod Nakashian
0f9f7629b5 wsd: better logging of socket activity
Especially error reporting is now better.

Change-Id: I032f6e8403660c2ac24be2d80b53b63831ec1066
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-11 09:15:40 -05:00
Ashod Nakashian
86940a2261 wsd: move ServerSocket creation into ServerSocket class
Change-Id: I25bca69943b69798db2e58af62902111c988a29e
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-11 09:15:40 -05:00
Ashod Nakashian
26b7e43ecb wsd: comment typos
Change-Id: I4789899ac58c3c07c66b47d1945b04a5029e7b56
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-11 09:15:40 -05:00
Ashod Nakashian
89a587a695 wsd: always set the Fin bit for WS frames
Change-Id: I60f676fb5022ee1b2740f5cc6974595f3e86d039
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-08 22:49:53 -05:00
Ashod Nakashian
a7aeea33cf wsd: cosmetic
Change-Id: I4885e91a3fdf0f1cd5caf79e7a41a289dde42150
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-08 22:49:53 -05:00
Ashod Nakashian
5371715a52 wsd: logging improvements
Change-Id: Ic887c42f0ca844e54bfc054e9c0706bbec7ebb6f
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-01 21:50:18 -05:00
Ashod Nakashian
21e99cf128 wsd: better errno handling in sockets
Change-Id: Id3a7744802cbf693a92e39ef4d99433951dfa923
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-01 21:50:18 -05:00
Ashod Nakashian
16185ff4fd wsd: cosmetics
Change-Id: I8ceb1a14f4d479dd7cae9a0a9a2f02990a7b4279
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-01 21:50:18 -05:00
Ashod Nakashian
feaed252bf wsd: retry flushing the WS buffered data when shutting down
Normally writeOutgoingData flushes all the available
write buffer to the socket. However, when an error
occures during the write, the flushing loop is
broken and the error is expected to be handled
in the poll loop (or, at any rate, the poll loop
will sooner or later retry).

This doesn't work when the socket is being shut
down. Details and stack-trace is added in the
code to document this scenario.

The proper fix to flushing before shutting
down is to do it asynchronously (i.e. flag for
shutdown, let poll flush the buffers, and then
close the socket), but currently this isn't
easily possible (again, details in the added
comment). For now, we do a second attempt to
write, before we give up and warn of lost data.

Worth noting that this was caught thanks to the
simulated socket error logic. Every so often the
Close Frame of the WebSocket was getting lost.
This frame is asserted in the 'crash test' and
the explanation is that it happened when the
simulated socket error happened to hit during
the writing of the Close Frame (as one statistic
this happened ~15% of the time, when running the
crash test in a loop). With the retrying in this
patch I was able to run the crash test successfully
a few 100 times without failures.

Finally, we unify the flushing with the mobile-app case
to minimize the differences as much as possible and
improved the logging a bit.

Change-Id: I0c0559d6095cd2af8250a7e65a972ba672ecd4b1
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-01 21:49:26 -05:00
Ashod Nakashian
7a13fa0943 wsd: socket error simulation to maintain the ssl state
SSL signals whether it needs more data to read or write
so that we perform the appropriate polling and call
the respective API. Since during error simulation
we skip calling the SSL API altogether, we shouldn't
change the last desired operation it communicated to us.

This becomes clear when we consider that we always read,
unconditionally, in StreamSocket::handlePoll (but write
only when poll signals POLLOUT event). This means that
if we decide to simulate a socket error during such
uncoditional read, and SSL wants to write, we would
reset its last wantsTo flag from write to read!

Logically, since we aren't even invoking any SSL API
during a simulated error, we shouldn't change the
SSL state one way or the other.

Change-Id: Ie4ddbc959f8424ea4ac3bc52f30edbc7399b2c7a
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-01 21:48:43 -05:00
Ashod Nakashian
3982c7b34f wsd: set errno when simulating socket errors for SSL
The API is the same for both SSL and non-SSL sockets
(they are virtual functions), and the API relies on
errno to detect errors and decide to retry, log, or
break. As such, we must set the same EAGAIN when
simulating socket errors for both SSL and non-SSL
cases, so that the behavior would also be the same.

Change-Id: Ib1695cc94d93f5ecc53d7b22872f459ac8b11bbd
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-03-01 21:48:43 -05:00
Ashod Nakashian
561a9ce991 wsd: storage: upload to storage using http::Request
This converts Poco to http::Request in sync mode,
thereby not changing functionality. In a follow-up,
this will be converted to async.

Change-Id: Ifbecd44ff599394799c1131470d77f803ed8cc45
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-02-27 08:57:25 -05:00
Ashod Nakashian
b0b1d9ef3d wsd: fail when trying to connect to an invalid host
Change-Id: I3fb1a625a5e88fbbf5726034559207684f2851f2
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-02-22 14:24:36 -05:00
Ashod Nakashian
658968fbf1 wsd: http::StatusLine initialized as invalid
This guarantees that any early failure results
in the status to also be invalid. That is,
only when we do get 200 OK from the host do
we set it in the StatusLine, never by default.

Change-Id: I4e31cb48cce0ed8962a737c4784fd6453b9a48cf
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-02-22 14:24:36 -05:00
Ashod Nakashian
78d24686e1 wsd: log WebSocket activity better
Change-Id: I551a20a14518a1794195442cec351f0755b094da
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-02-21 13:07:05 -05:00
Gleb Popov
8727db1746 Fix build with libc++: std::min() parameters should be of the same type.
Signed-off-by: Gleb Popov <6yearold@gmail.com>
Change-Id: Icdb67f0576992cd54c8e15c85fbaf2745aba218c
2021-02-11 00:31:57 +03:00
Miklos Vajna
b74f26910d net: http version string may not be null-terminated
Limit its length, we know the version length anyway.

Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I0db2b9227baf3e10055082ad394c0f555b9898e1
2021-01-27 13:33:30 +01:00
Ashod Nakashian
efa3e44231 wsd: remove debug logs
Change-Id: I68a856ff9678fe09ff4fcc597c46de9e29f72060
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-01-23 23:55:43 +00:00
Ashod Nakashian
72e9f3d2d6 wsd: asynchronous HTTP/1.1 implementation
This implements HTTP/1.1 per RFC 7230, partially.

Unit-tests are provided with documentation on usage.

This is desgined to serve as the http implementation
throughout loolwsd, for both synchronous and
asynchronous requests.

Change-Id: Iaf1b8c5fcb8cec032445e27c9f70d2fb807aa4dc
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-01-21 12:36:41 +01:00
Ashod Nakashian
ce3dd02ef3 wsd: new NetUtil file for network utilities
Move the connect function into the NetUtil
translation unit to aid using it for the
upcoming async socket logic.

The NetUtil should also come in handy for
the miscellaneous network helpers we have.

Change-Id: I2ee0c6e3e1769fd87572d7407d3b4979b59ffe6a
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-01-13 22:05:18 -05:00
Ashod Nakashian
417d19bce6 wsd: log when simulating socket error to help troubleshoot
When we simulate socket error it's hard to understand
what is going on, since there is no real errno to
explain the -1 return value. This is at least true
in the SSL case where we don't set errno (perhaps
we should?). At any rate, it's good form to log
that we are messing up with the return value and
that the real socket API hasn't been even invoked.

Change-Id: Ib76f0259dbdcfe0cfae97343c11ca45461079fa1
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
2021-01-13 16:24:29 -05:00