# HG changeset patch # User Chris Cannam # Date 1184323875 0 # Node ID 7802b0e2b0ffdf0e7a48fc08f63bee96eb7515a9 # Parent 9a13687c078b864f025c728295550b016a74ffb2 * Encoded entities in file name when saving wave-file model * Proper handling for percent-encodings in URLs for RemoteFile, and for queries in URLs diff -r 9a13687c078b -r 7802b0e2b0ff data/fileio/RemoteFile.cpp --- a/data/fileio/RemoteFile.cpp Thu Jul 12 16:14:59 2007 +0000 +++ b/data/fileio/RemoteFile.cpp Fri Jul 13 10:51:15 2007 +0000 @@ -64,8 +64,54 @@ this, SLOT(dataReadProgress(int, int))); connect(m_http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(httpResponseHeaderReceived(const QHttpResponseHeader &))); - QString path = url.path(); - std::cerr << "RemoteFile: path is \"" << path.toStdString() << "\"" << std::endl; + + // I don't quite understand this. url.path() returns a path + // without percent encoding; for example, spaces appear as + // literal spaces. This generally won't work if sent to the + // server directly. You can retrieve a correctly encoded URL + // from QUrl using url.toEncoded(), but that gives you the + // whole URL; there doesn't seem to be any way to retrieve + // only an encoded path. Furthermore there doesn't seem to be + // any way to convert a retrieved path into an encoded path + // without explicitly specifying that you don't want the path + // separators ("/") to be encoded. (Besides being painful to + // manage, I don't see how this can work correctly in any case + // where a percent-encoded "/" is supposed to appear within a + // path element?) There also seems to be no way to retrieve + // the path plus query string, i.e. everything that I need to + // send to the HTTP server. And no way for QHttp to take a + // QUrl argument. I'm obviously missing something. + + // So, two ways to do this: query the bits from the URL, + // encode them individually, and glue them back together + // again... + /* + QString path = QUrl::toPercentEncoding(url.path(), "/"); + QList > query = url.queryItems(); + if (!query.empty()) { + QStringList q2; + for (QList >::iterator i = query.begin(); + i != query.end(); ++i) { + q2.push_back(QString("%1=%3") + .arg(QString(QUrl::toPercentEncoding(i->first))) + .arg(QString(QUrl::toPercentEncoding(i->second)))); + } + path = QString("%1%2%3") + .arg(path).arg("?") + .arg(q2.join("&")); + } + */ + + // ...or, much simpler but relying on knowledge about the + // scheme://host/path/path/query etc format of the URL, we can + // get the whole URL ready-encoded and then split it on "/" as + // appropriate... + + QString path = "/" + QString(url.toEncoded()).section('/', 3); + + std::cerr << "RemoteFile: path is \"" + << path.toStdString() << "\"" << std::endl; + m_http->get(path, m_localFile); } else if (scheme == "ftp") { diff -r 9a13687c078b -r 7802b0e2b0ff data/model/WaveFileModel.cpp --- a/data/model/WaveFileModel.cpp Thu Jul 12 16:14:59 2007 +0000 +++ b/data/model/WaveFileModel.cpp Fri Jul 13 10:51:15 2007 +0000 @@ -615,7 +615,7 @@ { Model::toXml(out, indent, QString("type=\"wavefile\" file=\"%1\" %2") - .arg(m_path).arg(extraAttributes)); + .arg(encodeEntities(m_path)).arg(extraAttributes)); } QString @@ -624,6 +624,6 @@ { return Model::toXmlString(indent, QString("type=\"wavefile\" file=\"%1\" %2") - .arg(m_path).arg(extraAttributes)); + .arg(encodeEntities(m_path)).arg(extraAttributes)); }