From: Michael Tremer Date: Tue, 13 Aug 2024 18:54:15 +0000 (+0000) Subject: xfer: Fail if the connection was unexpectedly closed X-Git-Tag: 0.9.30~1206 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2626820b3054a1fb38fb03782775a90789eaac8;p=pakfire.git xfer: Fail if the connection was unexpectedly closed Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/xfer.c b/src/libpakfire/xfer.c index ff88c52b5..c4e7c3016 100644 --- a/src/libpakfire/xfer.c +++ b/src/libpakfire/xfer.c @@ -717,6 +717,133 @@ int pakfire_xfer_auth(struct pakfire_xfer* xfer) { return 0; } +/* + This function translates any cURL error codes into xfer codes +*/ +static pakfire_xfer_error_code_t pakfire_xfer_code(CURLcode code, int http_status) { + switch (code) { + case CURLE_OK: + return PAKFIRE_XFER_OK; + + // Unsupported requests + case CURLE_UNSUPPORTED_PROTOCOL: + case CURLE_NOT_BUILT_IN: + case CURLE_RANGE_ERROR: + return PAKFIRE_XFER_UNSUPPORTED; + + // Invalid requests + case CURLE_URL_MALFORMAT: + return PAKFIRE_XFER_INVALID_URL; + + // Invalid responses + case CURLE_TOO_MANY_REDIRECTS: + case CURLE_GOT_NOTHING: + case CURLE_BAD_CONTENT_ENCODING: + return PAKFIRE_XFER_INVALID_RESPONSE; + + // DNS Errors + case CURLE_COULDNT_RESOLVE_PROXY: + case CURLE_COULDNT_RESOLVE_HOST: + case CURLE_FTP_CANT_GET_HOST: + return PAKFIRE_XFER_DNS_ERROR; + + // Authentication + case CURLE_AUTH_ERROR: + return PAKFIRE_XFER_AUTH_ERROR; + + // Transport Errors + case CURLE_PROXY: + case CURLE_SSL_CONNECT_ERROR: + case CURLE_SSL_CERTPROBLEM: + case CURLE_SSL_CIPHER: + case CURLE_PEER_FAILED_VERIFICATION: + return PAKFIRE_XFER_TRANSPORT_ERROR; + + // Access Denied + case CURLE_REMOTE_ACCESS_DENIED: + return PAKFIRE_XFER_ACCESS_DENIED; + + // Timeout + case CURLE_FTP_ACCEPT_TIMEOUT: + case CURLE_OPERATION_TIMEDOUT: + return PAKFIRE_XFER_TIMEOUT; + + // Write error + case CURLE_WRITE_ERROR: + return PAKFIRE_XFER_WRITE_ERROR; + + // Read error + case CURLE_READ_ERROR: + case CURLE_FILE_COULDNT_READ_FILE: + return PAKFIRE_XFER_READ_ERROR; + + // Aborted + case CURLE_ABORTED_BY_CALLBACK: + return PAKFIRE_XFER_ABORTED; + + // HTTP Errors + case CURLE_HTTP_RETURNED_ERROR: + switch (http_status) { + // Proxy Error + case 502: + return PAKFIRE_XFER_TRANSPORT_ERROR; + + // Service Unavailable + case 503: + return PAKFIRE_XFER_TRANSPORT_ERROR; + + default: + return PAKFIRE_XFER_FAILED; + } + break; + + // Return "unknown error" for any other codes + default: + return PAKFIRE_XFER_FAILED; + } +} + +static int pakfire_xfer_fail(struct pakfire_xfer* xfer, int code) { + int r; + + CTX_DEBUG(xfer->ctx, "Xfer failed\n"); + + // Throw away any downloaded data + if (xfer->fin) { + // Get file descriptor + int fd = fileno(xfer->fin); + + // Truncate downloaded data + if (fd >= 0) { + r = ftruncate(fd, 0); + if (r) + return r; + } + + // Rewind + rewind(xfer->fin); + } + + // Did we use a mirror? + if (xfer->mirror) { + pakfire_mirror_xfer_failed(xfer->mirror); + + // Try again with another mirror + return -EAGAIN; + } + + // Call the close callback for WebSockets + if (xfer->direction == PAKFIRE_XFER_SOCKET) { + if (xfer->callbacks.close) { + r = xfer->callbacks.close(xfer, code, xfer->callbacks.data); + if (r) + return r; + } + } + + return code; +} + static int pakfire_xfer_select_mirror(struct pakfire_xfer* xfer) { // Choose the next mirror if (xfer->mirror) @@ -794,10 +921,18 @@ static int pakfire_xfer_socket_recv(struct pakfire_xfer* xfer) { // Read as many bytes as possible r = curl_ws_recv(xfer->handle, buffer, sizeof(buffer), &bytes_received, &meta); - if (r) { - CTX_ERROR(xfer->ctx, "Could not read from WebSocket: %s\n", curl_easy_strerror(r)); + switch (r) { + case CURLE_OK: + break; - return r; + // We seem to have lost the connection + case CURLE_GOT_NOTHING: + return pakfire_xfer_fail(xfer, PAKFIRE_XFER_TRANSPORT_ERROR); + + default: + CTX_ERROR(xfer->ctx, "Could not read from WebSocket: %s\n", curl_easy_strerror(r)); + + return r; } CTX_DEBUG(xfer->ctx, "Read %zu byte(s) from WebSocket\n", bytes_received); @@ -943,133 +1078,6 @@ static int pakfire_xfer_save(struct pakfire_xfer* xfer) { return 0; } -/* - This function translates any cURL error codes into xfer codes -*/ -static pakfire_xfer_error_code_t pakfire_xfer_code(CURLcode code, int http_status) { - switch (code) { - case CURLE_OK: - return PAKFIRE_XFER_OK; - - // Unsupported requests - case CURLE_UNSUPPORTED_PROTOCOL: - case CURLE_NOT_BUILT_IN: - case CURLE_RANGE_ERROR: - return PAKFIRE_XFER_UNSUPPORTED; - - // Invalid requests - case CURLE_URL_MALFORMAT: - return PAKFIRE_XFER_INVALID_URL; - - // Invalid responses - case CURLE_TOO_MANY_REDIRECTS: - case CURLE_GOT_NOTHING: - case CURLE_BAD_CONTENT_ENCODING: - return PAKFIRE_XFER_INVALID_RESPONSE; - - // DNS Errors - case CURLE_COULDNT_RESOLVE_PROXY: - case CURLE_COULDNT_RESOLVE_HOST: - case CURLE_FTP_CANT_GET_HOST: - return PAKFIRE_XFER_DNS_ERROR; - - // Authentication - case CURLE_AUTH_ERROR: - return PAKFIRE_XFER_AUTH_ERROR; - - // Transport Errors - case CURLE_PROXY: - case CURLE_SSL_CONNECT_ERROR: - case CURLE_SSL_CERTPROBLEM: - case CURLE_SSL_CIPHER: - case CURLE_PEER_FAILED_VERIFICATION: - return PAKFIRE_XFER_TRANSPORT_ERROR; - - // Access Denied - case CURLE_REMOTE_ACCESS_DENIED: - return PAKFIRE_XFER_ACCESS_DENIED; - - // Timeout - case CURLE_FTP_ACCEPT_TIMEOUT: - case CURLE_OPERATION_TIMEDOUT: - return PAKFIRE_XFER_TIMEOUT; - - // Write error - case CURLE_WRITE_ERROR: - return PAKFIRE_XFER_WRITE_ERROR; - - // Read error - case CURLE_READ_ERROR: - case CURLE_FILE_COULDNT_READ_FILE: - return PAKFIRE_XFER_READ_ERROR; - - // Aborted - case CURLE_ABORTED_BY_CALLBACK: - return PAKFIRE_XFER_ABORTED; - - // HTTP Errors - case CURLE_HTTP_RETURNED_ERROR: - switch (http_status) { - // Proxy Error - case 502: - return PAKFIRE_XFER_TRANSPORT_ERROR; - - // Service Unavailable - case 503: - return PAKFIRE_XFER_TRANSPORT_ERROR; - - default: - return PAKFIRE_XFER_FAILED; - } - break; - - // Return "unknown error" for any other codes - default: - return PAKFIRE_XFER_FAILED; - } -} - -static int pakfire_xfer_fail(struct pakfire_xfer* xfer, int code) { - int r; - - CTX_DEBUG(xfer->ctx, "Xfer failed\n"); - - // Throw away any downloaded data - if (xfer->fin) { - // Get file descriptor - int fd = fileno(xfer->fin); - - // Truncate downloaded data - if (fd >= 0) { - r = ftruncate(fd, 0); - if (r) - return r; - } - - // Rewind - rewind(xfer->fin); - } - - // Did we use a mirror? - if (xfer->mirror) { - pakfire_mirror_xfer_failed(xfer->mirror); - - // Try again with another mirror - return -EAGAIN; - } - - // Call the close callback for WebSockets - if (xfer->direction == PAKFIRE_XFER_SOCKET) { - if (xfer->callbacks.close) { - r = xfer->callbacks.close(xfer, code, xfer->callbacks.data); - if (r) - return r; - } - } - - return code; -} - pakfire_xfer_error_code_t pakfire_xfer_done(struct pakfire_xfer* xfer, int code) { CURL* h = xfer->handle; int r;