This commit is contained in:
JC-comp 2024-03-10 08:20:00 +08:00 committed by GitHub
commit 494458c733
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 585 additions and 832 deletions

View file

@ -20,16 +20,22 @@ class CurlResponse {
const(char)[][const(char)[]] requestHeaders;
const(char)[] postBody;
bool hasResponse;
string[string] responseHeaders;
HTTP.StatusLine statusLine;
char[] content;
this() {
reset();
}
void reset() {
method = HTTP.Method.undefined;
url = null;
requestHeaders = null;
postBody = null;
hasResponse = false;
responseHeaders = null;
object.destroy(statusLine);
content = null;
@ -56,6 +62,7 @@ class CurlResponse {
};
void update(HTTP *http) {
hasResponse = true;
this.responseHeaders = http.responseHeaders();
this.statusLine = http.statusLine;
}
@ -136,8 +143,10 @@ class CurlResponse {
override string toString() const {
string str = "Curl debugging: \n";
str ~= dumpDebug();
str ~= "Curl response: \n";
str ~= dumpResponse();
if (hasResponse) {
str ~= "Curl response: \n";
str ~= dumpResponse();
}
return str;
}
@ -192,15 +201,18 @@ class CurlEngine {
bool keepAlive;
ulong dnsTimeout;
CurlResponse response;
File uploadFile;
this() {
http = HTTP();
response = new CurlResponse();
response = null;
}
~this() {
object.destroy(http);
object.destroy(response);
if (uploadFile.isOpen())
uploadFile.close();
}
void initialise(ulong dnsTimeout, ulong connectTimeout, ulong dataTimeout, ulong operationTimeout, int maxRedirects, bool httpsDebug, string userAgent, bool httpProtocol, ulong userRateLimit, ulong protocolVersion, bool keepAlive=true) {
@ -286,12 +298,24 @@ class CurlEngine {
}
}
void setResponseHolder(CurlResponse response) {
if (response is null) {
// Create a response instance if it doesn't already exist
if (this.response is null)
this.response = new CurlResponse();
} else {
this.response = response;
}
}
void addRequestHeader(const(char)[] name, const(char)[] value) {
setResponseHolder(null);
http.addRequestHeader(name, value);
response.addRequestHeader(name, value);
}
void connect(HTTP.Method method, const(char)[] url) {
setResponseHolder(null);
if (!keepAlive)
addRequestHeader("Connection", "close");
http.method = method;
@ -300,6 +324,7 @@ class CurlEngine {
}
void setContent(const(char)[] contentType, const(char)[] sendData) {
setResponseHolder(null);
addRequestHeader("Content-Type", contentType);
if (sendData) {
http.contentLength = sendData.length;
@ -315,9 +340,25 @@ class CurlEngine {
}
}
void setFile(File* file, ulong offsetSize) {
void setFile(string filepath, string contentRange, ulong offset, ulong offsetSize) {
setResponseHolder(null);
// open file as read-only in binary mode
uploadFile = File(filepath, "rb");
if (contentRange.empty) {
offsetSize = uploadFile.size();
} else {
addRequestHeader("Content-Range", contentRange);
uploadFile.seek(offset);
}
// Setup progress bar to display
http.onProgress = delegate int(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) {
return 0;
};
addRequestHeader("Content-Type", "application/octet-stream");
http.onSend = data => file.rawRead(data).length;
http.onSend = data => uploadFile.rawRead(data).length;
http.contentLength = offsetSize;
}
@ -325,6 +366,7 @@ class CurlEngine {
scope(exit) {
cleanUp();
}
setResponseHolder(null);
http.onReceive = (ubyte[] data) {
response.content ~= data;
// HTTP Server Response Code Debugging if --https-debug is being used
@ -333,14 +375,11 @@ class CurlEngine {
};
http.perform();
response.update(&http);
return response.dup;
return response;
}
CurlResponse download(string originalFilename, string downloadFilename) {
// Threshold for displaying download bar
long thresholdFileSize = 4 * 2^^20; // 4 MiB
CurlResponse response = new CurlResponse();
setResponseHolder(null);
// open downloadFilename as write in binary mode
auto file = File(downloadFilename, "wb");
@ -378,7 +417,13 @@ class CurlEngine {
return 0;
};
http.contentLength = 0;
response.reset();
response = null;
// close file if open
if (uploadFile.isOpen()){
// close open file
uploadFile.close();
}
}
void shutdown() {

File diff suppressed because it is too large Load diff

View file

@ -2515,7 +2515,7 @@ class SyncEngine {
addLogEntry("Handling a OneDrive HTTP 429 Response Code (Too Many Requests)", ["debug"]);
// Read in the Retry-After HTTP header as set and delay as per this value before retrying the request
auto retryAfterValue = activeOneDriveApiInstance.getRetryAfterValue();
auto retryAfterValue = 300;
addLogEntry("Using Retry-After Value = " ~ to!string(retryAfterValue), ["debug"]);
// HTTP request returned status code 429 (Too Many Requests)
@ -2538,9 +2538,6 @@ class SyncEngine {
addLogEntry("Thread sleeping due to 'HTTP request returned status code 429' - The request has been throttled");
addLogEntry("Sleeping for " ~ to!string(delayBeforeRetry) ~ " seconds");
Thread.sleep(dur!"seconds"(delayBeforeRetry));
// Reset retry-after value to zero as we have used this value now and it may be changed in the future to a different value
activeOneDriveApiInstance.resetRetryAfterValue();
}
// If the JSON response is not correct JSON object, exit
@ -5766,7 +5763,7 @@ class SyncEngine {
addLogEntry("Fragment upload failed - received throttle request uploadResponse from OneDrive", ["debug"]);
if (exception.httpStatusCode == 429) {
auto retryAfterValue = activeOneDriveApiInstance.getRetryAfterValue();
auto retryAfterValue = 300;
addLogEntry("Using Retry-After Value = " ~ to!string(retryAfterValue), ["debug"]);
// Sleep thread as per request

View file

@ -628,7 +628,7 @@ void displayFileSystemErrorMessage(string message, string callingFunction) {
addLogEntry(" Error Message: " ~ errorMessage);
// Log the calling function
addLogEntry(" Calling Function: " ~ callingFunction, ["verbose"]);
addLogEntry(" Calling Function: " ~ callingFunction);
try {
// Safely check for disk space
@ -651,6 +651,15 @@ void displayPosixErrorMessage(string message) {
addLogEntry(" Error Message: " ~ message);
}
// Display the Error Message
void displayGeneralErrorMessage(Exception e, string callingFunction=__FUNCTION__, int lineno=__LINE__) {
addLogEntry(); // used rather than writeln
addLogEntry("ERROR: Encounter " ~ e.classinfo.name ~ ":");
addLogEntry(" Error Message: " ~ e.msg);
addLogEntry(" Calling Function: " ~ callingFunction);
addLogEntry(" Line number: " ~ to!string(lineno));
}
// Get the function name that is being called to assist with identifying where an error is being generated
string getFunctionName(alias func)() {
return __traits(identifier, __traits(parent, func)) ~ "()\n";