summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/UnitWOPISaveAs.cpp5
-rw-r--r--wsd/Storage.cpp34
2 files changed, 35 insertions, 4 deletions
diff --git a/test/UnitWOPISaveAs.cpp b/test/UnitWOPISaveAs.cpp
index 4bd3e9e06..82e89de07 100644
--- a/test/UnitWOPISaveAs.cpp
+++ b/test/UnitWOPISaveAs.cpp
@@ -33,7 +33,8 @@ public:
void assertPutFileRelativeRequest(const Poco::Net::HTTPRequest& request) override
{
- CPPUNIT_ASSERT_EQUAL(std::string("/path/to/hello world.txt"), request.get("X-WOPI-RelativeTarget"));
+ // spec says UTF-7...
+ CPPUNIT_ASSERT_EQUAL(std::string("/jan/hole+AWE-ovsk+AP0-/hello world.txt"), request.get("X-WOPI-SuggestedTarget"));
exitTest(TestResult::Ok);
}
@@ -49,7 +50,7 @@ public:
initWebsocket("/wopi/files/0?access_token=anything");
helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "load url=" + _wopiSrc, testName);
- helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "saveas url=wopi:///path/to/hello%20world.txt", testName);
+ helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "saveas url=wopi:///jan/hole%C5%A1ovsk%C3%BD/hello%20world.txt", testName);
SocketPoll::wakeupWorld();
_phase = Phase::Polling;
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index 6d0aa2c1c..af60c2374 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -14,6 +14,7 @@
#include <algorithm>
#include <cassert>
#include <fstream>
+#include <iconv.h>
#include <string>
#include <Poco/DateTime.h>
@@ -664,7 +665,7 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization&
// TODO: Check if this URI has write permission (canWrite = true)
const auto size = getFileSize(_jailedFilePath);
- const bool isSaveAs = !saveAsPath.empty();
+ const bool isSaveAs = !saveAsPath.empty() && !saveAsFilename.empty();
Poco::URI uriObject(_uri);
uriObject.setPath(isSaveAs? uriObject.getPath(): uriObject.getPath() + "/contents");
@@ -701,7 +702,36 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization&
{
// save as
request.set("X-WOPI-Override", "PUT_RELATIVE");
- request.set("X-WOPI-RelativeTarget", saveAsFilename);
+
+ // the suggested target has to be in UTF-7; default to extension
+ // only when the conversion fails
+ std::string suggestedTarget = "." + Poco::Path(saveAsFilename).getExtension();
+
+ iconv_t cd = iconv_open("UTF-7", "UTF-8");
+ if (cd == (iconv_t) -1)
+ LOG_ERR("Failed to initialize iconv for UTF-7 conversion, using '" << suggestedTarget << "'.");
+ else
+ {
+ std::vector<char> input(saveAsFilename.begin(), saveAsFilename.end());
+ std::vector<char> buffer(8 * saveAsFilename.size());
+
+ char* in = &input[0];
+ size_t in_left = input.size();
+ char* out = &buffer[0];
+ size_t out_left = buffer.size();
+
+ if (iconv(cd, &in, &in_left, &out, &out_left) == (size_t) -1)
+ LOG_ERR("Failed to convert '" << saveAsFilename << "' to UTF-7, using '" << suggestedTarget << "'.");
+ else
+ {
+ // conversion succeeded
+ suggestedTarget = std::string(&buffer[0], buffer.size() - out_left);
+ LOG_TRC("Converted '" << saveAsFilename << "' to UTF-7 as '" << suggestedTarget << "'.");
+ }
+ }
+
+ request.set("X-WOPI-SuggestedTarget", suggestedTarget);
+
request.set("X-WOPI-Size", std::to_string(size));
}