Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/network/access/qnetworkaccessftpbackend.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||
2 | - | |||||||||||||
3 | - | |||||||||||||
4 | - | |||||||||||||
5 | - | |||||||||||||
6 | enum { | - | ||||||||||||
7 | DefaultFtpPort = 21 | - | ||||||||||||
8 | }; | - | ||||||||||||
9 | - | |||||||||||||
10 | static QByteArray makeCacheKey(const QUrl &url) | - | ||||||||||||
11 | { | - | ||||||||||||
12 | QUrl copy = url; | - | ||||||||||||
13 | copy.setPort(url.port(DefaultFtpPort)); | - | ||||||||||||
14 | return "ftp-connection:" + | - | ||||||||||||
15 | copy.toEncoded(QUrl::RemovePassword | QUrl::RemovePath | QUrl::RemoveQuery | | - | ||||||||||||
16 | QUrl::RemoveFragment); | - | ||||||||||||
17 | } | - | ||||||||||||
18 | - | |||||||||||||
19 | QStringList QNetworkAccessFtpBackendFactory::supportedSchemes() const | - | ||||||||||||
20 | { | - | ||||||||||||
21 | return QStringList(([]() -> QString { enum { Size = sizeof(u"" "ftp")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "ftp" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }())); | - | ||||||||||||
22 | } | - | ||||||||||||
23 | - | |||||||||||||
24 | QNetworkAccessBackend * | - | ||||||||||||
25 | QNetworkAccessFtpBackendFactory::create(QNetworkAccessManager::Operation op, | - | ||||||||||||
26 | const QNetworkRequest &request) const | - | ||||||||||||
27 | { | - | ||||||||||||
28 | - | |||||||||||||
29 | switch (op) { | - | ||||||||||||
30 | case QNetworkAccessManager::GetOperation: | - | ||||||||||||
31 | case QNetworkAccessManager::PutOperation: | - | ||||||||||||
32 | break; | - | ||||||||||||
33 | - | |||||||||||||
34 | default: | - | ||||||||||||
35 | - | |||||||||||||
36 | return 0; | - | ||||||||||||
37 | } | - | ||||||||||||
38 | - | |||||||||||||
39 | QUrl url = request.url(); | - | ||||||||||||
40 | if (url.scheme().compare(QLatin1String("ftp"), Qt::CaseInsensitive) == 0) | - | ||||||||||||
41 | return new QNetworkAccessFtpBackend; | - | ||||||||||||
42 | return 0; | - | ||||||||||||
43 | } | - | ||||||||||||
44 | - | |||||||||||||
45 | class QNetworkAccessCachedFtpConnection: public QFtp, public QNetworkAccessCache::CacheableObject | - | ||||||||||||
46 | { | - | ||||||||||||
47 | - | |||||||||||||
48 | public: | - | ||||||||||||
49 | QNetworkAccessCachedFtpConnection() | - | ||||||||||||
50 | { | - | ||||||||||||
51 | setExpires(true); | - | ||||||||||||
52 | setShareable(false); | - | ||||||||||||
53 | } | - | ||||||||||||
54 | - | |||||||||||||
55 | void dispose() override | - | ||||||||||||
56 | { | - | ||||||||||||
57 | connect(this, qFlagLocation("2""done(bool)" "\0" __FILE__ ":" "95""101"), this, qFlagLocation("1""deleteLater()" "\0" __FILE__ ":" "95""101")); | - | ||||||||||||
58 | close(); | - | ||||||||||||
59 | } | - | ||||||||||||
60 | }; | - | ||||||||||||
61 | - | |||||||||||||
62 | QNetworkAccessFtpBackend::QNetworkAccessFtpBackend() | - | ||||||||||||
63 | : ftp(0), uploadDevice(0), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), | - | ||||||||||||
64 | supportsSize(false), supportsMdtm(false), state(Idle) | - | ||||||||||||
65 | { | - | ||||||||||||
66 | } | - | ||||||||||||
67 | - | |||||||||||||
68 | QNetworkAccessFtpBackend::~QNetworkAccessFtpBackend() | - | ||||||||||||
69 | { | - | ||||||||||||
70 | - | |||||||||||||
71 | if (ftp && state != Disconnecting) | - | ||||||||||||
72 | ftp->abort(); | - | ||||||||||||
73 | disconnectFromFtp(); | - | ||||||||||||
74 | } | - | ||||||||||||
75 | - | |||||||||||||
76 | void QNetworkAccessFtpBackend::open() | - | ||||||||||||
77 | { | - | ||||||||||||
78 | - | |||||||||||||
79 | QNetworkProxy proxy; | - | ||||||||||||
for (QForeachContainer<typename QtPrivate::remove_reference<decltype(proxyList())>::type> _container_((proxyList())); _container_.control && _container_.i != _container_.e; | ||||||||||||||
80 | ++_container_.i, _container_.control ^const auto proxies = 1)proxyList(); | - | ||||||||||||
81 | for (const QNetworkProxy &p = *_container_.i; _container_.control; _container_.control = 0: proxies) { | - | ||||||||||||
82 | - | |||||||||||||
83 | - | |||||||||||||
84 | if (p.type() == QNetworkProxy::FtpCachingProxy
| 2-53 | ||||||||||||
85 | || p.type() == QNetworkProxy::NoProxy
| 5-48 | ||||||||||||
86 | proxy = p; | - | ||||||||||||
87 | break; executed 50 times by 1 test: break; Executed by:
| 50 | ||||||||||||
88 | } | - | ||||||||||||
89 | } executed 5 times by 1 test: end of block Executed by:
| 5 | ||||||||||||
90 | - | |||||||||||||
91 | - | |||||||||||||
92 | if (proxy.type() == QNetworkProxy::DefaultProxy
| 3-50 | ||||||||||||
93 | - | |||||||||||||
94 | error(QNetworkReply::ProxyNotFoundError, | - | ||||||||||||
95 | tr("No suitable proxy found")); | - | ||||||||||||
96 | finished(); | - | ||||||||||||
97 | return; executed 3 times by 1 test: return; Executed by:
| 3 | ||||||||||||
98 | } | - | ||||||||||||
99 | - | |||||||||||||
100 | - | |||||||||||||
101 | - | |||||||||||||
102 | QUrl url = this->url(); | - | ||||||||||||
103 | if (url.path().isEmpty()
| 1-49 | ||||||||||||
104 | url.setPath(QLatin1String("/")); | - | ||||||||||||
105 | setUrl(url); | - | ||||||||||||
106 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||
107 | if (url.path().endsWith(QLatin1Char('/'))
| 1-49 | ||||||||||||
108 | error(QNetworkReply::ContentOperationNotPermittedError, | - | ||||||||||||
109 | tr("Cannot open %1: is a directory").arg(url.toString())); | - | ||||||||||||
110 | finished(); | - | ||||||||||||
111 | return; executed 1 time by 1 test: return; Executed by:
| 1 | ||||||||||||
112 | } | - | ||||||||||||
113 | state = LoggingIn; | - | ||||||||||||
114 | - | |||||||||||||
115 | QNetworkAccessCache* objectCache = QNetworkAccessManagerPrivate::getObjectCache(this); | - | ||||||||||||
116 | QByteArray cacheKey = makeCacheKey(url); | - | ||||||||||||
117 | if (!objectCache->requestEntry(cacheKey, this,
| 1-48 | ||||||||||||
118 | qFlagLocation("1""ftpConnectionReady(QNetworkAccessCache::CacheableObject*)" "\0" __FILE__ ":" "155""162"))
| 1-48 | ||||||||||||
119 | ftp = new QNetworkAccessCachedFtpConnection; | - | ||||||||||||
120 | - | |||||||||||||
121 | - | |||||||||||||
122 | ftp->setProperty("_q_networksession", property("_q_networksession")); | - | ||||||||||||
123 | - | |||||||||||||
124 | - | |||||||||||||
125 | if (proxy.type() == QNetworkProxy::FtpCachingProxy
| 2-46 | ||||||||||||
126 | ftp->setProxy(proxy.hostName(), proxy.port()); executed 2 times by 1 test: ftp->setProxy(proxy.hostName(), proxy.port()); Executed by:
| 2 | ||||||||||||
127 | - | |||||||||||||
128 | ftp->connectToHost(url.host(), url.port(DefaultFtpPort)); | - | ||||||||||||
129 | ftp->login(url.userName(), url.password()); | - | ||||||||||||
130 | - | |||||||||||||
131 | objectCache->addEntry(cacheKey, ftp); | - | ||||||||||||
132 | ftpConnectionReady(ftp); | - | ||||||||||||
133 | } executed 48 times by 1 test: end of block Executed by:
| 48 | ||||||||||||
134 | - | |||||||||||||
135 | - | |||||||||||||
136 | if (operation() == QNetworkAccessManager::PutOperation
| 13-36 | ||||||||||||
137 | uploadDevice = QNonContiguousByteDeviceFactory::wrap(createUploadByteDevice()); | - | ||||||||||||
138 | uploadDevice->setParent(this); | - | ||||||||||||
139 | } executed 13 times by 1 test: end of block Executed by:
| 13 | ||||||||||||
140 | } executed 49 times by 1 test: end of block Executed by:
| 49 | ||||||||||||
141 | - | |||||||||||||
142 | void QNetworkAccessFtpBackend::closeDownstreamChannel() | - | ||||||||||||
143 | { | - | ||||||||||||
144 | state = Disconnecting; | - | ||||||||||||
145 | if (operation() == QNetworkAccessManager::GetOperation) | - | ||||||||||||
146 | ftp->abort(); | - | ||||||||||||
147 | } | - | ||||||||||||
148 | - | |||||||||||||
149 | void QNetworkAccessFtpBackend::downstreamReadyWrite() | - | ||||||||||||
150 | { | - | ||||||||||||
151 | if (state == Transferring && ftp && ftp->bytesAvailable()) | - | ||||||||||||
152 | ftpReadyRead(); | - | ||||||||||||
153 | } | - | ||||||||||||
154 | - | |||||||||||||
155 | void QNetworkAccessFtpBackend::ftpConnectionReady(QNetworkAccessCache::CacheableObject *o) | - | ||||||||||||
156 | { | - | ||||||||||||
157 | ftp = static_cast<QNetworkAccessCachedFtpConnection *>(o); | - | ||||||||||||
158 | connect(ftp, qFlagLocation("2""done(bool)" "\0" __FILE__ ":" "195""202"), qFlagLocation("1""ftpDone()" "\0" __FILE__ ":" "195""202")); | - | ||||||||||||
159 | connect(ftp, qFlagLocation("2""rawCommandReply(int,QString)" "\0" __FILE__ ":" "196""203"), qFlagLocation("1""ftpRawCommandReply(int,QString)" "\0" __FILE__ ":" "196""203")); | - | ||||||||||||
160 | connect(ftp, qFlagLocation("2""readyRead()" "\0" __FILE__ ":" "197""204"), qFlagLocation("1""ftpReadyRead()" "\0" __FILE__ ":" "197""204")); | - | ||||||||||||
161 | - | |||||||||||||
162 | - | |||||||||||||
163 | if (ftp->state() == QFtp::LoggedIn) | - | ||||||||||||
164 | ftpDone(); | - | ||||||||||||
165 | - | |||||||||||||
166 | - | |||||||||||||
167 | } | - | ||||||||||||
168 | - | |||||||||||||
169 | void QNetworkAccessFtpBackend::disconnectFromFtp(CacheCleanupMode mode) | - | ||||||||||||
170 | { | - | ||||||||||||
171 | state = Disconnecting; | - | ||||||||||||
172 | - | |||||||||||||
173 | if (ftp) { | - | ||||||||||||
174 | disconnect(ftp, 0, this, 0); | - | ||||||||||||
175 | - | |||||||||||||
176 | QByteArray key = makeCacheKey(url()); | - | ||||||||||||
177 | if (mode == RemoveCachedConnection) { | - | ||||||||||||
178 | QNetworkAccessManagerPrivate::getObjectCache(this)->removeEntry(key); | - | ||||||||||||
179 | ftp->dispose(); | - | ||||||||||||
180 | } else { | - | ||||||||||||
181 | QNetworkAccessManagerPrivate::getObjectCache(this)->releaseEntry(key); | - | ||||||||||||
182 | } | - | ||||||||||||
183 | - | |||||||||||||
184 | ftp = 0; | - | ||||||||||||
185 | } | - | ||||||||||||
186 | } | - | ||||||||||||
187 | - | |||||||||||||
188 | void QNetworkAccessFtpBackend::ftpDone() | - | ||||||||||||
189 | { | - | ||||||||||||
190 | - | |||||||||||||
191 | if (state == LoggingIn
| 4-129 | ||||||||||||
192 | if (ftp->state() == QFtp::Connected
| 1-3 | ||||||||||||
193 | - | |||||||||||||
194 | QUrl newUrl = url(); | - | ||||||||||||
195 | QString userInfo = newUrl.userInfo(); | - | ||||||||||||
196 | newUrl.setUserInfo(QString()); | - | ||||||||||||
197 | setUrl(newUrl); | - | ||||||||||||
198 | - | |||||||||||||
199 | QAuthenticator auth; | - | ||||||||||||
200 | authenticationRequired(&auth); | - | ||||||||||||
201 | - | |||||||||||||
202 | if (!auth.isNull()
| 0-3 | ||||||||||||
203 | - | |||||||||||||
204 | newUrl.setUserName(auth.user()); | - | ||||||||||||
205 | ftp->login(auth.user(), auth.password()); | - | ||||||||||||
206 | return; never executed: return; | 0 | ||||||||||||
207 | } | - | ||||||||||||
208 | - | |||||||||||||
209 | - | |||||||||||||
210 | newUrl.setUserInfo(userInfo); | - | ||||||||||||
211 | setUrl(newUrl); | - | ||||||||||||
212 | - | |||||||||||||
213 | error(QNetworkReply::AuthenticationRequiredError, | - | ||||||||||||
214 | tr("Logging in to %1 failed: authentication required") | - | ||||||||||||
215 | .arg(url().host())); | - | ||||||||||||
216 | } executed 3 times by 1 test: else {end of block Executed by:
| 3 | ||||||||||||
217 | - | |||||||||||||
218 | QNetworkReply::NetworkError code; | - | ||||||||||||
219 | switch (ftp->error()) { | - | ||||||||||||
220 | case executed 1 time by 1 test: QFtp::HostNotFound:case QFtp::HostNotFound: Executed by:
executed 1 time by 1 test: case QFtp::HostNotFound: Executed by:
| 1 | ||||||||||||
221 | code = QNetworkReply::HostNotFoundError; | - | ||||||||||||
222 | break; executed 1 time by 1 test: break; Executed by:
| 1 | ||||||||||||
223 | - | |||||||||||||
224 | case never executed: QFtp::ConnectionRefused:case QFtp::ConnectionRefused: never executed: case QFtp::ConnectionRefused: | 0 | ||||||||||||
225 | code = QNetworkReply::ConnectionRefusedError; | - | ||||||||||||
226 | break; never executed: break; | 0 | ||||||||||||
227 | - | |||||||||||||
228 | default never executed: :default: never executed: default: | 0 | ||||||||||||
229 | code = QNetworkReply::ProtocolFailure; | - | ||||||||||||
230 | break; never executed: break; | 0 | ||||||||||||
231 | } | - | ||||||||||||
232 | - | |||||||||||||
233 | error(code, ftp->errorString()); | - | ||||||||||||
234 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||
235 | - | |||||||||||||
236 | - | |||||||||||||
237 | disconnectFromFtp(RemoveCachedConnection); | - | ||||||||||||
238 | finished(); | - | ||||||||||||
239 | return; executed 4 times by 1 test: return; Executed by:
| 4 | ||||||||||||
240 | } | - | ||||||||||||
241 | - | |||||||||||||
242 | - | |||||||||||||
243 | if (ftp->error() != QFtp::NoError
| 5-169 | ||||||||||||
244 | QString msg; | - | ||||||||||||
245 | if (operation() == QNetworkAccessManager::GetOperation
| 0-5 | ||||||||||||
246 | msg = tr("Error while downloading %1: %2"); executed 5 times by 1 test: msg = tr("Error while downloading %1: %2"); Executed by:
| 5 | ||||||||||||
247 | else | - | ||||||||||||
248 | msg = tr("Error while uploading %1: %2"); never executed: msg = tr("Error while uploading %1: %2"); | 0 | ||||||||||||
249 | msg = msg.arg(url().toString(), ftp->errorString()); | - | ||||||||||||
250 | - | |||||||||||||
251 | if (state == Statting
| 1-4 | ||||||||||||
252 | - | |||||||||||||
253 | error(QNetworkReply::ContentNotFoundError, msg); executed 4 times by 1 test: error(QNetworkReply::ContentNotFoundError, msg); Executed by:
| 4 | ||||||||||||
254 | else | - | ||||||||||||
255 | error(QNetworkReply::ContentAccessDenied, msg); executed 1 time by 1 test: error(QNetworkReply::ContentAccessDenied, msg); Executed by:
| 1 | ||||||||||||
256 | - | |||||||||||||
257 | disconnectFromFtp(RemoveCachedConnection); | - | ||||||||||||
258 | finished(); | - | ||||||||||||
259 | } executed 5 times by 1 test: end of block Executed by:
| 5 | ||||||||||||
260 | - | |||||||||||||
261 | if (state == LoggingIn
| 45-129 | ||||||||||||
262 | state = CheckingFeatures; | - | ||||||||||||
263 | if (operation() == QNetworkAccessManager::GetOperation
| 11-34 | ||||||||||||
264 | - | |||||||||||||
265 | QString command = url().path(); | - | ||||||||||||
command.prepend(QLatin1String("%1 "));helpId = ftp->rawCommand(QLatin1String("HELP")); | ||||||||||||||
266 | } executed 34 times by 1 test: else {end of block Executed by:
| 34 | ||||||||||||
267 | ftpDone(); | - | ||||||||||||
268 | } executed 11 times by 1 test: end of block Executed by:
| 11 | ||||||||||||
269 | } else if (state == CheckingFeatures
| 45-84 | ||||||||||||
270 | state = Statting; | - | ||||||||||||
271 | if (operation() == QNetworkAccessManager::GetOperation
| 11-34 | ||||||||||||
272 | - | |||||||||||||
273 | const QString commandpath = url().path(); | - | ||||||||||||
274 | command.prepend(QLatin1String("%1 "));if (supportsSize
| 0-34 | ||||||||||||
275 | ftp->rawCommand(QLatin1String("TYPE I")); | - | ||||||||||||
276 | sizeId = ftp->rawCommand(command.arg(QLatin1String("SIZE")));"SIZE ") + path); | - | ||||||||||||
277 | } executed 34 times by 1 test: end of block Executed by:
| 34 | ||||||||||||
278 | if (supportsMdtm
| 0-34 | ||||||||||||
279 | mdtmId = ftp->rawCommand(command.arg(QLatin1String("MDTM")));"MDTM ") + path); executed 34 times by 1 test: mdtmId = ftp->rawCommand(QLatin1String("MDTM ") + path); Executed by:
| 34 | ||||||||||||
280 | if (!supportsSize
| 0-34 | ||||||||||||
281 | ftpDone(); never executed: ftpDone(); | 0 | ||||||||||||
282 | } executed 34 times by 1 test: else {end of block Executed by:
| 34 | ||||||||||||
283 | ftpDone(); | - | ||||||||||||
284 | } executed 11 times by 1 test: end of block Executed by:
| 11 | ||||||||||||
285 | } else if (state == Statting
| 41-43 | ||||||||||||
286 | - | |||||||||||||
287 | metaDataChanged(); | - | ||||||||||||
288 | state = Transferring; | - | ||||||||||||
289 | - | |||||||||||||
290 | QFtp::TransferType type = QFtp::Binary; | - | ||||||||||||
291 | if (operation() == QNetworkAccessManager::GetOperation
| 11-30 | ||||||||||||
292 | setCachingEnabled(true); | - | ||||||||||||
293 | ftp->get(url().path(), 0, type); | - | ||||||||||||
294 | } executed 30 times by 1 test: else {end of block Executed by:
| 30 | ||||||||||||
295 | ftp->put(uploadDevice, url().path(), type); | - | ||||||||||||
296 | } executed 11 times by 1 test: end of block Executed by:
| 11 | ||||||||||||
297 | - | |||||||||||||
298 | } else if (state == Transferring
| 5-38 | ||||||||||||
299 | - | |||||||||||||
300 | disconnectFromFtp(); | - | ||||||||||||
301 | finished(); | - | ||||||||||||
302 | } executed 38 times by 1 test: end of block Executed by:
| 38 | ||||||||||||
303 | } executed 174 times by 1 test: end of block Executed by:
| 174 | ||||||||||||
304 | - | |||||||||||||
305 | void QNetworkAccessFtpBackend::ftpReadyRead() | - | ||||||||||||
306 | { | - | ||||||||||||
307 | QByteArray data = ftp->readAll(); | - | ||||||||||||
308 | QByteDataBuffer list; | - | ||||||||||||
309 | list.append(data); | - | ||||||||||||
310 | data.clear(); | - | ||||||||||||
311 | writeDownstreamData(list); | - | ||||||||||||
312 | } | - | ||||||||||||
313 | - | |||||||||||||
314 | void QNetworkAccessFtpBackend::ftpRawCommandReply(int code, const QString &text) | - | ||||||||||||
315 | { | - | ||||||||||||
316 | - | |||||||||||||
317 | int id = ftp->currentId(); | - | ||||||||||||
318 | - | |||||||||||||
319 | if ((id == helpId) && ((code == 200) || (code == 214))) { | - | ||||||||||||
320 | - | |||||||||||||
321 | - | |||||||||||||
322 | - | |||||||||||||
323 | if (text.contains(QLatin1String("SIZE"), Qt::CaseSensitive)) | - | ||||||||||||
324 | supportsSize = true; | - | ||||||||||||
325 | if (text.contains(QLatin1String("MDTM"), Qt::CaseSensitive)) | - | ||||||||||||
326 | supportsMdtm = true; | - | ||||||||||||
327 | } else if (code == 213) { | - | ||||||||||||
328 | if (id == sizeId) { | - | ||||||||||||
329 | - | |||||||||||||
330 | setHeader(QNetworkRequest::ContentLengthHeader, text.toLongLong()); | - | ||||||||||||
331 | - | |||||||||||||
332 | } else if (id == mdtmId) { | - | ||||||||||||
333 | QDateTime dt = QDateTime::fromString(text, QLatin1String("yyyyMMddHHmmss")); | - | ||||||||||||
334 | setHeader(QNetworkRequest::LastModifiedHeader, dt); | - | ||||||||||||
335 | - | |||||||||||||
336 | } | - | ||||||||||||
337 | } | - | ||||||||||||
338 | } | - | ||||||||||||
339 | - | |||||||||||||
340 | - | |||||||||||||
Switch to Source code | Preprocessed file |