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)
// 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);
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;