971
971
/* ************************************************************************* */
974
/* *** create () *** */
976
try_create_tested_existence (SoupSession *session, SoupMessage *msg,
979
GVfsJob *job = G_VFS_JOB (user_data);
980
GVfsBackendHttp *op_backend = job->backend_data;
981
GOutputStream *stream;
982
SoupMessage *put_msg;
984
if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
986
g_vfs_job_failed (job,
989
_("Target file already exists"));
992
/* FIXME: other errors */
994
put_msg = message_new_from_uri ("PUT", soup_message_get_uri (msg));
996
soup_message_headers_append (put_msg->request_headers, "If-None-Match", "*");
997
stream = soup_output_stream_new (op_backend->session, put_msg, -1);
998
g_object_unref (put_msg);
1000
g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), stream);
1001
g_vfs_job_succeeded (job);
1005
try_create (GVfsBackend *backend,
1006
GVfsJobOpenForWrite *job,
1007
const char *filename,
1008
GFileCreateFlags flags)
1010
GVfsBackendHttp *op_backend;
1013
/* FIXME: if SoupOutputStream supported chunked requests, we could
1014
* use a PUT with "If-None-Match: *" and "Expect: 100-continue"
1017
op_backend = G_VFS_BACKEND_HTTP (backend);
1019
msg = message_new_from_filename (backend, "HEAD", filename);
1021
g_vfs_job_set_backend_data (G_VFS_JOB (job), op_backend, NULL);
1022
soup_session_queue_message (op_backend->session, msg,
1023
try_create_tested_existence, job);
1027
/* *** replace () *** */
1029
open_for_replace_succeeded (GVfsBackendHttp *op_backend, GVfsJob *job,
1030
SoupURI *uri, const char *etag)
1032
SoupMessage *put_msg;
1033
GOutputStream *stream;
1035
put_msg = message_new_from_uri (SOUP_METHOD_PUT, uri);
1038
soup_message_headers_append (put_msg->request_headers, "If-Match", etag);
1040
stream = soup_output_stream_new (op_backend->session, put_msg, -1);
1041
g_object_unref (put_msg);
1043
g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), stream);
1044
g_vfs_job_succeeded (job);
1048
try_replace_checked_etag (SoupSession *session, SoupMessage *msg,
1051
GVfsJob *job = G_VFS_JOB (user_data);
1052
GVfsBackendHttp *op_backend = job->backend_data;
1054
if (msg->status_code == SOUP_STATUS_PRECONDITION_FAILED)
1056
g_vfs_job_failed (G_VFS_JOB (job),
1058
G_IO_ERROR_WRONG_ETAG,
1059
_("The file was externally modified"));
1062
/* FIXME: other errors */
1064
open_for_replace_succeeded (op_backend, job, soup_message_get_uri (msg),
1065
soup_message_headers_get (msg->request_headers, "If-Match"));
1069
try_replace (GVfsBackend *backend,
1070
GVfsJobOpenForWrite *job,
1071
const char *filename,
1073
gboolean make_backup,
1074
GFileCreateFlags flags)
1076
GVfsBackendHttp *op_backend;
1079
/* FIXME: if SoupOutputStream supported chunked requests, we could
1080
* use a PUT with "If-Match: ..." and "Expect: 100-continue"
1083
op_backend = G_VFS_BACKEND_HTTP (backend);
1087
g_vfs_job_failed (G_VFS_JOB (job),
1089
G_IO_ERROR_CANT_CREATE_BACKUP,
1090
_("Backup file creation failed"));
1096
uri = g_vfs_backend_uri_for_filename (backend, filename);
1102
msg = soup_message_new_from_uri (SOUP_METHOD_HEAD, uri);
1103
soup_uri_free (uri);
1104
soup_message_headers_append (msg->request_headers, "User-Agent", "gvfs/" VERSION);
1105
soup_message_headers_append (msg->request_headers, "If-Match", etag);
1107
g_vfs_job_set_backend_data (G_VFS_JOB (job), op_backend, NULL);
1108
soup_session_queue_message (op_backend->session, msg,
1109
try_replace_checked_etag, job);
1113
open_for_replace_succeeded (op_backend, G_VFS_JOB (job), uri, NULL);
1114
soup_uri_free (uri);
1118
/* *** write () *** */
1120
write_ready (GObject *source_object,
1121
GAsyncResult *result,
1124
GOutputStream *stream;
1129
stream = G_OUTPUT_STREAM (source_object);
1131
job = G_VFS_JOB (user_data);
1133
nwrote = g_output_stream_write_finish (stream, result, &error);
1137
g_vfs_job_failed (G_VFS_JOB (job),
1142
g_error_free (error);
1146
g_vfs_job_write_set_written_size (G_VFS_JOB_WRITE (job), nwrote);
1147
g_vfs_job_succeeded (job);
1151
try_write (GVfsBackend *backend,
1153
GVfsBackendHandle handle,
1157
GVfsBackendHttp *op_backend;
1158
GOutputStream *stream;
1160
op_backend = G_VFS_BACKEND_HTTP (backend);
1161
stream = G_OUTPUT_STREAM (handle);
1163
g_output_stream_write_async (stream,
1167
G_VFS_JOB (job)->cancellable,
1173
/* *** close_write () *** */
1175
close_write_ready (GObject *source_object,
1176
GAsyncResult *result,
1179
GOutputStream *stream;
1184
job = G_VFS_JOB (user_data);
1185
stream = G_OUTPUT_STREAM (source_object);
1186
res = g_output_stream_close_finish (stream,
1191
g_vfs_job_failed (G_VFS_JOB (job),
1196
g_error_free (error);
1199
g_vfs_job_succeeded (job);
1201
g_object_unref (stream);
1205
try_close_write (GVfsBackend *backend,
1206
GVfsJobCloseWrite *job,
1207
GVfsBackendHandle handle)
1209
GVfsBackendHttp *op_backend;
1210
GOutputStream *stream;
1212
op_backend = G_VFS_BACKEND_HTTP (backend);
1213
stream = G_OUTPUT_STREAM (handle);
1215
g_output_stream_close_async (stream,
1217
G_VFS_JOB (job)->cancellable,
1224
/* ************************************************************************* */
975
1228
g_vfs_backend_dav_class_init (GVfsBackendDavClass *klass)