service/DavResponse.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QByteArray> | ||
| 4 | #include <QMetaType> | ||
| 5 | #include <QString> | ||
| 6 | |||
| 7 | // Result of a raw DAV resource request (PUT/DELETE/GET), shared by the | ||
| 8 | // CalDAV and CardDAV clients (Sprint 93 S93.1.6, extracted in Sprint 97 so | ||
| 9 | // both write outboxes speak the same contract). | ||
| 10 | struct DavResponse { | ||
| 11 | quint64 request = 0; | ||
| 12 | QByteArray method; // "PUT", "DELETE", "GET", "POST", "OPTIONS" | ||
| 13 | QString url; | ||
| 14 | int status = 0; // HTTP status; 0 = transport failure / limit hit | ||
| 15 | QByteArray body; | ||
| 16 | QString etag; | ||
| 17 | QString location; // resolved Location header (PUT create) | ||
| 18 | QByteArray davHeader; // the DAV header (OPTIONS: compliance classes, Sprint 108) | ||
| 19 | QString error; // transport or limit error text (never shown to users) | ||
| 20 | // S106-059: the client refused the request before the network (invalid or | ||
| 21 | // weak entity-tag, rejected URL) — the same request is refused every time. | ||
| 22 | bool refusedLocally = false; | ||
| 23 | 1 | bool transportFailure() const { return status == 0; } | |
| 24 | }; | ||
| 25 |
4/7✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 14 not taken.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 14 → 15 not taken.
|
1 | Q_DECLARE_METATYPE(DavResponse) |
| 26 | |||
| 27 | namespace DavEntityTag { | ||
| 28 | |||
| 29 | // RFC 9110 §8.8.3: entity-tag = [ weak ] opaque-tag, etagc = %x21 / | ||
| 30 | // %x23-7E / obs-text. If-Match uses strong comparison, so weak tags never | ||
| 31 | // match and are refused. Validates the encoded field value, because that is | ||
| 32 | // what QNetworkRequest receives. | ||
| 33 | 241 | inline bool isValid(const QString &etag) { | |
| 34 |
1/1✓ Branch 2 → 3 taken 241 times.
|
241 | const QByteArray bytes = etag.toUtf8(); |
| 35 |
2/2✓ Branch 5 → 6 taken 5 times.
✓ Branch 5 → 7 taken 236 times.
|
241 | if (bytes.startsWith("W/")) |
| 36 | 5 | return false; | |
| 37 |
9/9✓ Branch 8 → 9 taken 233 times.
✓ Branch 8 → 13 taken 3 times.
✓ Branch 10 → 11 taken 231 times.
✓ Branch 10 → 13 taken 2 times.
✓ Branch 11 → 12 taken 231 times.
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 14 taken 229 times.
✓ Branch 15 → 16 taken 7 times.
✓ Branch 15 → 17 taken 229 times.
|
236 | if (bytes.size() < 2 || bytes.at(0) != '"' || bytes.back() != '"') |
| 38 | 7 | return false; | |
| 39 |
2/2✓ Branch 26 → 18 taken 2445 times.
✓ Branch 26 → 27 taken 226 times.
|
2671 | for (qsizetype i = 1; i < bytes.size() - 1; ++i) { |
| 40 | 2445 | const auto value = static_cast<unsigned char>(bytes.at(i)); | |
| 41 |
8/8✓ Branch 19 → 20 taken 2444 times.
✓ Branch 19 → 24 taken 1 time.
✓ Branch 20 → 21 taken 2442 times.
✓ Branch 20 → 22 taken 2 times.
✓ Branch 21 → 22 taken 5 times.
✓ Branch 21 → 24 taken 2437 times.
✓ Branch 22 → 23 taken 3 times.
✓ Branch 22 → 24 taken 4 times.
|
2445 | if (value != 0x21 && !(value >= 0x23 && value <= 0x7E) && value < 0x80) |
| 42 | 3 | return false; | |
| 43 | } | ||
| 44 | 226 | return true; | |
| 45 | 241 | } | |
| 46 | |||
| 47 | } // namespace DavEntityTag | ||
| 48 |