mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-27 11:22:00 -04:00
http: Add flatpak_load_uri_full with some more complete features
This allows: * getting http status * getting www-authenticate header * Doing HEAD instead of get This is needed by the OCI registry code for authentication
This commit is contained in:
committed by
Alexander Larsson
parent
b1083a4c41
commit
618d0c8fae
@@ -45,12 +45,26 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlatpakHttpSession, flatpak_http_session_free)
|
||||
typedef enum {
|
||||
FLATPAK_HTTP_FLAGS_NONE = 0,
|
||||
FLATPAK_HTTP_FLAGS_ACCEPT_OCI = 1 << 0,
|
||||
FLATPAK_HTTP_FLAGS_STORE_COMPRESSED = 2 << 0,
|
||||
FLATPAK_HTTP_FLAGS_STORE_COMPRESSED = 1 << 1,
|
||||
FLATPAK_HTTP_FLAGS_NOCHECK_STATUS = 1 << 2,
|
||||
FLATPAK_HTTP_FLAGS_HEAD = 1 << 3,
|
||||
} FlatpakHTTPFlags;
|
||||
|
||||
typedef void (*FlatpakLoadUriProgress) (guint64 downloaded_bytes,
|
||||
gpointer user_data);
|
||||
|
||||
GBytes * flatpak_load_uri_full (FlatpakHttpSession *http_session,
|
||||
const char *uri,
|
||||
FlatpakHTTPFlags flags,
|
||||
const char *auth,
|
||||
const char *token,
|
||||
FlatpakLoadUriProgress progress,
|
||||
gpointer user_data,
|
||||
int *out_status,
|
||||
char **out_content_type,
|
||||
char **out_www_authenticate,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GBytes * flatpak_load_uri (FlatpakHttpSession *http_session,
|
||||
const char *uri,
|
||||
FlatpakHTTPFlags flags,
|
||||
|
||||
@@ -55,12 +55,15 @@ typedef struct
|
||||
|
||||
guint64 downloaded_bytes;
|
||||
char buffer[16 * 1024];
|
||||
FlatpakHTTPFlags flags;
|
||||
FlatpakLoadUriProgress progress;
|
||||
GCancellable *cancellable;
|
||||
gpointer user_data;
|
||||
guint64 last_progress_time;
|
||||
CacheHttpData *cache_data;
|
||||
int *status_out;
|
||||
char **content_type_out;
|
||||
char **www_authenticate_out;
|
||||
} LoadUriData;
|
||||
|
||||
#define CACHE_HTTP_XATTR "user.flatpak.http"
|
||||
@@ -430,6 +433,7 @@ load_uri_callback (GObject *source_object,
|
||||
{
|
||||
int code;
|
||||
GQuark domain = G_IO_ERROR;
|
||||
gboolean http_error = TRUE;
|
||||
|
||||
switch (msg->status_code)
|
||||
{
|
||||
@@ -457,33 +461,41 @@ load_uri_callback (GObject *source_object,
|
||||
break;
|
||||
|
||||
case SOUP_STATUS_CANCELLED:
|
||||
http_error = FALSE;
|
||||
code = G_IO_ERROR_CANCELLED;
|
||||
break;
|
||||
|
||||
case SOUP_STATUS_CANT_RESOLVE:
|
||||
case SOUP_STATUS_CANT_CONNECT:
|
||||
http_error = FALSE;
|
||||
code = G_IO_ERROR_HOST_NOT_FOUND;
|
||||
break;
|
||||
|
||||
case SOUP_STATUS_INTERNAL_SERVER_ERROR:
|
||||
/* The server did return something, but it was useless to us, so that’s basically equivalent to not returning */
|
||||
http_error = FALSE;
|
||||
code = G_IO_ERROR_HOST_UNREACHABLE;
|
||||
break;
|
||||
|
||||
case SOUP_STATUS_IO_ERROR:
|
||||
http_error = FALSE;
|
||||
code = G_IO_ERROR_CONNECTION_CLOSED;
|
||||
break;
|
||||
|
||||
default:
|
||||
http_error = FALSE;
|
||||
code = G_IO_ERROR_FAILED;
|
||||
}
|
||||
|
||||
data->error = g_error_new (domain, code,
|
||||
"Server returned status %u: %s",
|
||||
msg->status_code,
|
||||
soup_status_get_phrase (msg->status_code));
|
||||
g_main_context_wakeup (data->context);
|
||||
return;
|
||||
if (!http_error || (data->flags & FLATPAK_HTTP_FLAGS_NOCHECK_STATUS) == 0)
|
||||
{
|
||||
data->error = g_error_new (domain, code,
|
||||
"Server returned status %u: %s",
|
||||
msg->status_code,
|
||||
soup_status_get_phrase (msg->status_code));
|
||||
g_main_context_wakeup (data->context);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->cache_data)
|
||||
@@ -492,6 +504,12 @@ load_uri_callback (GObject *source_object,
|
||||
if (data->content_type_out)
|
||||
*data->content_type_out = g_strdup (soup_message_headers_get_content_type (msg->response_headers, NULL));
|
||||
|
||||
if (data->www_authenticate_out)
|
||||
*data->www_authenticate_out = g_strdup (soup_message_headers_get_one (msg->response_headers, "WWW-Authenticate"));
|
||||
|
||||
if (data->status_out)
|
||||
*data->status_out = msg->status_code;
|
||||
|
||||
if (data->out_tmpfile)
|
||||
{
|
||||
g_autoptr(GOutputStream) out = NULL;
|
||||
@@ -602,10 +620,13 @@ static GBytes *
|
||||
flatpak_load_http_uri_once (FlatpakHttpSession *http_session,
|
||||
const char *uri,
|
||||
FlatpakHTTPFlags flags,
|
||||
const char *auth,
|
||||
const char *token,
|
||||
FlatpakLoadUriProgress progress,
|
||||
gpointer user_data,
|
||||
int *out_status,
|
||||
char **out_content_type,
|
||||
char **out_www_authenticate,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
@@ -626,10 +647,13 @@ flatpak_load_http_uri_once (FlatpakHttpSession *http_session,
|
||||
data.progress = progress;
|
||||
data.cancellable = cancellable;
|
||||
data.user_data = user_data;
|
||||
data.flags = flags;
|
||||
data.last_progress_time = g_get_monotonic_time ();
|
||||
data.www_authenticate_out = out_www_authenticate;
|
||||
data.content_type_out = out_content_type;
|
||||
data.status_out = out_status;
|
||||
|
||||
request = soup_session_request_http (soup_session, "GET",
|
||||
request = soup_session_request_http (soup_session, (data.flags & FLATPAK_HTTP_FLAGS_HEAD) != 0 ? "HEAD" : "GET",
|
||||
uri, error);
|
||||
if (request == NULL)
|
||||
return NULL;
|
||||
@@ -640,6 +664,11 @@ flatpak_load_http_uri_once (FlatpakHttpSession *http_session,
|
||||
soup_message_headers_replace (m->request_headers, "Accept",
|
||||
FLATPAK_OCI_MEDIA_TYPE_IMAGE_MANIFEST ", " FLATPAK_DOCKER_MEDIA_TYPE_IMAGE_MANIFEST2 ", " FLATPAK_OCI_MEDIA_TYPE_IMAGE_INDEX);
|
||||
|
||||
if (auth)
|
||||
{
|
||||
g_autofree char *basic_auth = g_strdup_printf ("Basic %s", auth);
|
||||
soup_message_headers_replace (m->request_headers, "Authorization", basic_auth);
|
||||
}
|
||||
|
||||
if (token)
|
||||
{
|
||||
@@ -667,15 +696,18 @@ flatpak_load_http_uri_once (FlatpakHttpSession *http_session,
|
||||
}
|
||||
|
||||
GBytes *
|
||||
flatpak_load_uri (FlatpakHttpSession *http_session,
|
||||
const char *uri,
|
||||
FlatpakHTTPFlags flags,
|
||||
const char *token,
|
||||
FlatpakLoadUriProgress progress,
|
||||
gpointer user_data,
|
||||
char **out_content_type,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
flatpak_load_uri_full (FlatpakHttpSession *http_session,
|
||||
const char *uri,
|
||||
FlatpakHTTPFlags flags,
|
||||
const char *auth,
|
||||
const char *token,
|
||||
FlatpakLoadUriProgress progress,
|
||||
gpointer user_data,
|
||||
int *out_status,
|
||||
char **out_content_type,
|
||||
char **out_www_authenticate,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
guint n_retries_remaining = DEFAULT_N_NETWORK_RETRIES;
|
||||
@@ -708,8 +740,9 @@ flatpak_load_uri (FlatpakHttpSession *http_session,
|
||||
progress (0, user_data); /* Reset the progress */
|
||||
}
|
||||
|
||||
bytes = flatpak_load_http_uri_once (http_session, uri, flags,
|
||||
token, progress, user_data, out_content_type,
|
||||
bytes = flatpak_load_http_uri_once (http_session, uri, flags, auth, token,
|
||||
progress, user_data,
|
||||
out_status, out_content_type, out_www_authenticate,
|
||||
cancellable, &local_error);
|
||||
|
||||
if (local_error == NULL)
|
||||
@@ -722,6 +755,23 @@ flatpak_load_uri (FlatpakHttpSession *http_session,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GBytes *
|
||||
flatpak_load_uri (FlatpakHttpSession *http_session,
|
||||
const char *uri,
|
||||
FlatpakHTTPFlags flags,
|
||||
const char *token,
|
||||
FlatpakLoadUriProgress progress,
|
||||
gpointer user_data,
|
||||
char **out_content_type,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
return flatpak_load_uri_full (http_session, uri, flags, NULL, token,
|
||||
progress, user_data, NULL, out_content_type, NULL,
|
||||
cancellable, error);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
flatpak_download_http_uri_once (FlatpakHttpSession *http_session,
|
||||
const char *uri,
|
||||
@@ -750,6 +800,7 @@ flatpak_download_http_uri_once (FlatpakHttpSession *http_session,
|
||||
data.cancellable = cancellable;
|
||||
data.user_data = user_data;
|
||||
data.last_progress_time = g_get_monotonic_time ();
|
||||
data.flags = flags;
|
||||
|
||||
request = soup_session_request_http (soup_session, "GET",
|
||||
uri, error);
|
||||
@@ -938,6 +989,7 @@ flatpak_cache_http_uri_once (FlatpakHttpSession *http_session,
|
||||
data.progress = progress;
|
||||
data.cancellable = cancellable;
|
||||
data.user_data = user_data;
|
||||
data.flags = flags;
|
||||
data.last_progress_time = g_get_monotonic_time ();
|
||||
|
||||
request = soup_session_request_http (soup_session, "GET",
|
||||
|
||||
Reference in New Issue
Block a user