Problem/Motivation

Not sure if this is evidence of a bug, or my ignorance.

For any document uploaded to Drupal and edited in ONLYOFFICE, the content of the file loads into only office, users are able to edit the file, but when the file saves back to Drupal upon ONLYOFFICE session end, the original document is overwritten with a blank document (0 bytes). Both ONLYOFFICE and Drupal are each in separate docker stacks on different networks.

The issue is not document-type specific. This occurs for text docs, spreadsheets, and presentations. The title remains the same, but the contents are overwritten as blank.

Drupal 9.5.8, Kubernetes/docker, Apache and Nginx reverse proxy
ONLYOFFICE Docs Community Edition Docker, no configuration changes, in a temporary github codespace

Steps to reproduce

  1. Go to the Content > Media
  2. Add a docx document and save
  3. From Content > Media, select 'edit in ONLYOFFICE' from the dropdown
  4. Make changes to the file, close out onlyoffice session
  5. Either download the file, or open it again on ONLYOFFICE - file is blank, and is now 0 bytes size

There is nothing coming up in the ONLYOFFICE logs that would point to an issue.

In the Drupal logs, we see that the config is generated for the document with what looks like all the correct information, and "Connected to the media document REDACTED.docx co-editing." appears in the logs, along with the "Request from Document Editing Service" json. When the session is closed, Media document "REDACTED.docx was successfully saved." prints to the Drupal log.

We do get several warnings in the logs related to the callback, which likely explain why the document does not save back properly, all citing line 287 of OnlyofficeCallbackController.php. I am pasting them here, with the stack trace:

Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in Drupal\onlyoffice\Controller\OnlyofficeCallbackController->proccessSave() (line 287 of /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php)
#0 /var/www/html/web/core/includes/bootstrap.inc(347): _drupal_error_handler_real(2, 'file_get_conten...', '/var/www/html/w...', 287)
#1 [internal function]: _drupal_error_handler(2, 'file_get_conten...', '/var/www/html/w...', 287)
#2 /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php(287): file_get_contents('https://kelizol...')
#3 /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php(242): Drupal\onlyoffice\Controller\OnlyofficeCallbackController->proccessSave(Object(stdClass), Object(Drupal\media\Entity\Media), Array)
#4 [internal function]: Drupal\onlyoffice\Controller\OnlyofficeCallbackController->callback('amZPY0RoRzZlMGc...', Object(Symfony\Component\HttpFoundation\Request))
#5 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#6 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(580): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#7 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#8 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#9 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(169): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#10 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#11 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(718): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#20 {main}
.
Warning: file_get_contents(): Failed to enable crypto in Drupal\onlyoffice\Controller\OnlyofficeCallbackController->proccessSave() (line 287 of /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php)
#0 /var/www/html/web/core/includes/bootstrap.inc(347): _drupal_error_handler_real(2, 'file_get_conten...', '/var/www/html/w...', 287)
#1 [internal function]: _drupal_error_handler(2, 'file_get_conten...', '/var/www/html/w...', 287)
#2 /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php(287): file_get_contents('https://kelizol...')
#3 /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php(242): Drupal\onlyoffice\Controller\OnlyofficeCallbackController->proccessSave(Object(stdClass), Object(Drupal\media\Entity\Media), Array)
#4 [internal function]: Drupal\onlyoffice\Controller\OnlyofficeCallbackController->callback('amZPY0RoRzZlMGc...', Object(Symfony\Component\HttpFoundation\Request))
#5 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#6 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(580): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#7 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#8 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#9 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(169): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#10 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#11 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(718): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#20 {main}
.
Warning: file_get_contents(https://REDACTED.github.dev/cache/files/data/b7c66e33-4fbd-41b8-96b1-d46adbf08abc_MTY4NDc5NzIwMw==_664/output.pptx/output.pptx?md5=Eocbj0kGiL-u15Np5qbUHw&expires=1684800427&filename=output.pptx): Failed to open stream: operation failed in Drupal\onlyoffice\Controller\OnlyofficeCallbackController->proccessSave() (line 287 of /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php)
#0 /var/www/html/web/core/includes/bootstrap.inc(347): _drupal_error_handler_real(2, 'file_get_conten...', '/var/www/html/w...', 287)
#1 [internal function]: _drupal_error_handler(2, 'file_get_conten...', '/var/www/html/w...', 287)
#2 /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php(287): file_get_contents('https://kelizol...')
#3 /var/www/html/web/modules/contrib/onlyoffice/src/Controller/OnlyofficeCallbackController.php(242): Drupal\onlyoffice\Controller\OnlyofficeCallbackController->proccessSave(Object(stdClass), Object(Drupal\media\Entity\Media), Array)
#4 [internal function]: Drupal\onlyoffice\Controller\OnlyofficeCallbackController->callback('amZPY0RoRzZlMGc...', Object(Symfony\Component\HttpFoundation\Request))
#5 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#6 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(580): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#7 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#8 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#9 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(169): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#10 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(81): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#11 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /var/www/html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(718): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#20 {main}
.
CommentFileSizeAuthor
#5 log.PNG9 KBaleksandr.fedorov

Comments

k.elizabeth created an issue. See original summary.

aleksandr.fedorov’s picture

Hi k.elizabeth, on the ONLYOFFICE document server, are you using a certificate issued by a trusted certificate authority?

k.elizabeth’s picture

aleksandr.fedorov yes, it is a certificate issued by Linode.

k.elizabeth’s picture

I updated the module on our Drupal with the recent bugfix - thank you. Now the docservice out.log says:

[2023-06-02T00:40:22.238] [ERROR] [localhost] [ae0e1018-6109-41e9-9fec-c173883ea09f_MTY4NTY2MjQ5Mg==] [11] nodeJS - sendServerRequest error: url = https://REDACTED/onlyoffice-callback/ZmRPbTNtQ3lteHVGWDBFdHZqYTRyZm1EcTh5NFJCTkxmbng4WXlFdDIzRT83MThiNTc1ZC0xZjA4LTQ5Y2MtYTM4NS0wOWIyZjRmZmQ5YmU;data = {"key":"ae0e1018-6109-41e9-9fec-c173883ea09f_MTY4NTY2MjQ5Mg==","status":2,"url":"https://REDACTED/cache/files/data/ae0e1018-6109-41e9-9fec-c173883ea09f_MTY4NTY2MjQ5Mg==_9308/output.docx/output.docx?md5=0QbYr-aoDQVBkYGjFIrIbg&expires=1685667322&filename=output.docx","history":{},"users":["1"],"actions":[{"type":0,"userid":"1"}],"lastsave":"2023-06-01T23:39:38.000Z","notmodified":false,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJhZTBlMTAxOC02MTA5LTQxZTktOWZlYy1jMTczODgzZWEwOWZfTVRZNE5UWTJNalE1TWc9PSIsInN0YXR1cyI6MiwidXJsIjoiaHR0cHM6Ly80NS03OS0xOTItNzkuaXAubGlub2RldXNlcmNvbnRlbnQuY29tL2NhY2hlL2ZpbGVzL2RhdGEvYWUwZTEwMTgtNjEwOS00MWU5LTlmZWMtYzE3Mzg4M2VhMDlmX01UWTROVFkyTWpRNU1nPT1fOTMwOC9vdXRwdXQuZG9jeC9vdXRwdXQuZG9jeD9tZDU9MFFiWXItYW9EUVZCa1lHakZJckliZyZleHBpcmVzPTE2ODU2NjczMjImZmlsZW5hbWU9b3V0cHV0LmRvY3giLCJoaXN0b3J5Ijp7fSwidXNlcnMiOlsiMSJdLCJhY3Rpb25zIjpbeyJ0eXBlIjowLCJ1c2VyaWQiOiIxIn1dLCJsYXN0c2F2ZSI6IjIwMjMtMDYtMDFUMjM6Mzk6MzguMDAwWiIsIm5vdG1vZGlmaWVkIjpmYWxzZSwiZmlsZXR5cGUiOiJkb2N4IiwiaWF0IjoxNjg1NjY2NDIxLCJleHAiOjE2ODU2NjY3MjF9.4wLwcePpIeMHQBT07VtNegbV76r0NURZlEHJXrs1GH0","filetype":"docx"} Error: Error response: statusCode:400; headers:{"date":"Fri, 02 Jun 2023 00:40:22 GMT","content-type":"application/json","transfer-encoding":"chunked","connection":"keep-alive","x-powered-by":"PHP/8.1.19","cache-control":"must-revalidate, no-cache, private","x-ua-compatible":"IE=edge","content-language":"en","x-content-type-options":"nosniff","x-frame-options":"SAMEORIGIN","expires":"Sun, 19 Nov 1978 05:00:00 GMT","x-generator":"Drupal 9 (https://www.drupal.org)","strict-transport-security":"max-age=15724800; includeSubDomains"}; body:
{"error":1,"message":"Error download file from https:\/\/REDACTED\/cache\/files\/data\/ae0e1018-6109-41e9-9fec-c173883ea09f_MTY4NTY2MjQ5Mg==_9308\/output.docx\/output.docx?md5=0QbYr-aoDQVBkYGjFIrIbg\u0026expires=1685667322\u0026filename=output.docx"}
    at Request._callback (/snapshot/server/build/server/Common/sources/utils.js)
    at Request.callback (/snapshot/server/build/server/Common/node_modules/request/request.js:185:22)
    at Request.emit (events.js:400:28)
    at Request.<anonymous> (/snapshot/server/build/server/Common/node_modules/request/request.js:1154:10)
    at Request.emit (events.js:400:28)
    at IncomingMessage.<anonymous> (/snapshot/server/build/server/Common/node_modules/request/request.js:1076:12)
    at Object.onceWrapper (events.js:519:28)
    at IncomingMessage.emit (events.js:412:35)
    at endReadableNT (internal/streams/readable.js:1333:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)
[2023-06-02T00:40:22.243] [WARN] [localhost] [ae0e1018-6109-41e9-9fec-c173883ea09f_MTY4NTY2MjQ5Mg==] [11] nodeJS - storeForgotten

In this case, we are using the ONLYOFFICE docker deployment through the Linode marketplace. We have not made any customizations to the default deployment. https://www.linode.com/docs/products/tools/marketplace/guides/onlyoffice/

aleksandr.fedorov’s picture

StatusFileSize
new9 KB

The edit was aimed at fixing saving an empty file. This was indeed a vulnerability in our application. But it wasn't supposed to fix the certificate validation problem. All the same, your problem should be related to the ONLYOFFICE Docs certificate. This can be seen from this log, Drupal cannot connect to ONLYOFFICE Docs Server due to "certificate verify failed":

log

k.elizabeth’s picture

Yes, understood.

I have tested the cert on the host I am using for onlyoffice with https://www.ssllabs.com/ to be sure. It is a valid, trusted LE Certificate. The issue cited in the warning is for the tls_process_server_certificate, where ssl labs is able to complete the tls handshake.

I know that this question is beyond the scope of this particular ticket (which with your bugfix I consider resolved) and probably the module in general, but is there anything that we might do on either end to override the ssl certification requirement? At this point we are trying to get a proof of concept prepared in order to get approval to acquire an enterprise license of onlyoffice, and can certainly continue to debug this for production.

EDIT: We are just going to override the SSL verification check for now in file_get_contents(). An ugly hotfix, but it will get us moving. This ticket may be closed.

k.elizabeth’s picture

Status: Active » Reviewed & tested by the community