bool Application::GetResource (const Uri *resourceBase, const Uri *uri, NotifyFunc notify_cb, EventHandler write_cb, DownloaderAccessPolicy policy, HttpRequest::Options options, Cancellable *cancellable, gpointer user_data) { if (!uri) { g_warning ("Passing a null uri to Application::GetResource"); if (notify_cb) notify_cb (NotifyFailed, GPOINTER_TO_INT(NULL), user_data); return false; } if (get_resource_cb && !uri->IsAbsolute ()) { ManagedStreamCallbacks stream; if (!Uri::IsNullOrEmpty (uri)) { stream = get_resource_cb (resourceBase, uri); } else { memset (&stream, 0, sizeof (stream)); } if (stream.handle) { if (notify_cb) notify_cb (NotifyStarted, GPOINTER_TO_INT(NULL), user_data); if (write_cb) { char buf[4096]; int offset = 0; int nread; if (stream.CanSeek (stream.handle)) stream.Seek (stream.handle, 0, 0); HttpRequestWriteEventArgs *args = new HttpRequestWriteEventArgs (NULL, 0, 0); do { if ((nread = stream.Read (stream.handle, buf, 0, sizeof (buf))) <= 0) break; args->SetData (buf); args->SetOffset (offset); args->SetCount (nread); write_cb (this, args, user_data); offset += nread; } while (true); args->unref (); } if (notify_cb) notify_cb (NotifyCompleted, GPOINTER_TO_INT(NULL), user_data); stream.Close (stream.handle); return true; } } #if 0 // FIXME: drt 171 and 173 expect this to fail simply because the uri // begins with a '/', but other drts (like 238) depend on this // working. I give up. if (!uri->isAbsolute && uri->path && uri->path[0] == '/') { if (notify_cb) notify_cb (NotifyFailed, NULL, user_data); return false; } #endif //no get_resource_cb or empty stream HttpRequest *request; if (!(request = GetDeployment ()->CreateHttpRequest (options))) { if (notify_cb) notify_cb (NotifyFailed, GPOINTER_TO_INT(NULL), user_data); return false; } NotifyCtx *ctx = g_new (NotifyCtx, 1); ctx->user_data = user_data; ctx->notify_cb = notify_cb; ctx->write_cb = write_cb; ctx->request = request; if (notify_cb) { request->AddHandler (HttpRequest::ProgressChangedEvent, application_downloader_progress_changed, ctx); request->AddHandler (HttpRequest::StartedEvent, application_downloader_started, ctx); } if (cancellable) { cancellable->SetCancelFuncAndData (application_downloader_abort, request, ctx); } request->AddHandler (HttpRequest::WriteEvent, application_downloader_write, ctx); request->AddHandler (HttpRequest::StoppedEvent, application_downloader_stopped, ctx); request->Open ("GET", uri, resourceBase, policy); request->Send (); return true; }