commit 864c851839ab5667ecc39f1633c407e35b649b8a
parent 333252b443356f2bb9733ea2656a09c66d2fd203
Author: Henrik RydgÄrd <hrydgard@gmail.com>
Date: Fri, 21 Jul 2023 17:38:51 +0200
Add naettGetTotalBytesRead, for reading download progress safely
Diffstat:
7 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/naett.h b/naett.h
@@ -112,6 +112,13 @@ const void* naettGetBody(naettRes* response, int* outSize);
const char* naettGetHeader(naettRes* response, const char* name);
/**
+ * @brief Returns how many bytes have been read from the response so far,
+ * and the integer pointed to by totalSize gets the Content-Length if available,
+ * or -1 if not (or 0 if headers have not been read yet).
+ */
+int naettGetTotalBytesRead(naettRes* response, int* totalSize);
+
+/**
* @brief Enumerates all response headers as long as the `lister`
* returns true.
*/
diff --git a/src/naett_android.c b/src/naett_android.c
@@ -198,6 +198,11 @@ static void* processRequest(void* data) {
}
res->headers = firstHeader;
+ const char *contentLength = naettGetHeader((naettRes *)res, "Content-Length");
+ if (!contentLength || sscanf(contentLength, "%d", &res->contentLength) != 1) {
+ res->contentLength = -1;
+ }
+
int statusCode = intCall(env, connection, "getResponseCode", "()I");
jobject inputStream = NULL;
@@ -221,9 +226,11 @@ static void* processRequest(void* data) {
}
if (bytesRead < 0) {
break;
+ } else if (bytesRead > 0) {
+ (*env)->GetByteArrayRegion(env, buffer, 0, bytesRead, (jbyte*) byteBuffer);
+ req->options.bodyWriter(byteBuffer, bytesRead, req->options.bodyWriterData);
+ res->totalBytesRead += bytesRead;
}
- (*env)->GetByteArrayRegion(env, buffer, 0, bytesRead, (jbyte*) byteBuffer);
- req->options.bodyWriter(byteBuffer, bytesRead, req->options.bodyWriterData);
} while (!res->closeRequested);
voidCall(env, inputStream, "close", "()V");
diff --git a/src/naett_core.c b/src/naett_core.c
@@ -314,6 +314,15 @@ const void* naettGetBody(naettRes* response, int* size) {
return res->body.data;
}
+int naettGetTotalBytesRead(naettRes* response, int* totalSize) {
+ assert(response != NULL);
+ assert(totalSize != NULL);
+
+ InternalResponse* res = (InternalResponse*)response;
+ *totalSize = res->contentLength;
+ return res->totalBytesRead;
+}
+
const char* naettGetHeader(naettRes* response, const char* name) {
assert(response != NULL);
assert(name != NULL);
diff --git a/src/naett_internal.h b/src/naett_internal.h
@@ -86,6 +86,8 @@ typedef struct {
int complete;
KVLink* headers;
Buffer body;
+ int contentLength; // 0 if headers not read, -1 if Content-Length missing.
+ int totalBytesRead;
#if __APPLE__
id session;
#endif
diff --git a/src/naett_linux.c b/src/naett_linux.c
@@ -48,6 +48,7 @@ static void* curlWorker(void* data) {
int bytesRead = read(handleReadFD, newHandle.buf, sizeof(newHandle.buf) - newHandlePos);
if (bytesRead > 0) {
newHandlePos += bytesRead;
+ res->totalBytesRead += bytesRead;
}
if (newHandlePos == sizeof(newHandle.buf)) {
curl_multi_add_handle(mc, newHandle.handle);
diff --git a/src/naett_osx.c b/src/naett_osx.c
@@ -106,11 +106,18 @@ void didReceiveData(id self, SEL _sel, id session, id dataTask, id data) {
firstHeader = node;
}
res->headers = firstHeader;
+
+ const char *contentLength = naettGetHeader((naettRes *)res, "Content-Length");
+ if (!contentLength || sscanf(contentLength, "%d", &res->contentLength) != 1) {
+ res->contentLength = -1;
+ }
}
const void* bytes = objc_msgSend_t(const void*)(data, sel("bytes"));
NSUInteger length = objc_msgSend_t(NSUInteger)(data, sel("length"));
+
res->request->options.bodyWriter(bytes, length, res->request->options.bodyWriterData);
+ res->totalBytesRead += (int)length;
release(p);
}
diff --git a/src/naett_win.c b/src/naett_win.c
@@ -114,6 +114,11 @@ static void CALLBACK callback(HINTERNET request,
unpackHeaders(res, buffer);
free(buffer);
+ const char *contentLength = naettGetHeader((naettRes *)res, "Content-Length");
+ if (!contentLength || sscanf(contentLength, "%d", &res->contentLength) != 1) {
+ res->contentLength = -1;
+ }
+
DWORD statusCode = 0;
DWORD statusCodeSize = sizeof(statusCode);
@@ -154,7 +159,7 @@ static void CALLBACK callback(HINTERNET request,
res->code = naettReadError;
res->complete = 1;
}
-
+ res->totalBytesRead += (int)bytesRead;
res->bytesLeft -= bytesRead;
if (res->bytesLeft > 0) {
size_t bytesToRead = min(res->bytesLeft, sizeof(res->buffer));