/* * Process redirections (HTTP 30x answers) * (This is a work in progress --not finished yet) */ static int Cache_redirect(CacheEntry_t *entry, int Flags, BrowserWindow *bw) { DilloUrl *NewUrl; _MSG(" Cache_redirect: redirect_level = %d\n", bw->redirect_level); /* Don't allow redirection for SpamSafe/local URLs */ if (URL_FLAGS(entry->Url) & URL_SpamSafe) { a_UIcmd_set_msg(bw, "WARNING: local URL with redirection. Aborting."); return 0; } /* if there's a redirect loop, stop now */ if (bw->redirect_level >= 5) entry->Flags |= CA_RedirectLoop; if (entry->Flags & CA_RedirectLoop) { a_UIcmd_set_msg(bw, "ERROR: redirect loop for: %s", URL_STR_(entry->Url)); bw->redirect_level = 0; return 0; } if ((entry->Flags & CA_Redirect && entry->Location) && (entry->Flags & CA_ForceRedirect || entry->Flags & CA_TempRedirect || !entry->Data->len || entry->Data->len < 1024)) { _MSG(">>>> Redirect from: %s\n to %s <<<<\n", URL_STR_(entry->Url), URL_STR_(entry->Location)); _MSG("%s", entry->Header->str); if (Flags & WEB_RootUrl) { /* Redirection of the main page */ NewUrl = a_Url_new(URL_STR_(entry->Location), URL_STR_(entry->Url)); if (entry->Flags & CA_TempRedirect) a_Url_set_flags(NewUrl, URL_FLAGS(NewUrl) | URL_E2EQuery); a_Nav_push(bw, NewUrl, entry->Url); a_Url_free(NewUrl); } else { /* Sub entity redirection (most probably an image) */ if (!entry->Data->len) { _MSG(">>>> Image redirection without entity-content <<<<\n"); } else { _MSG(">>>> Image redirection with entity-content <<<<\n"); } } } return 0; }
/* * Most used function for requesting a URL. * TODO: clean up the ad-hoc bindings with an API that allows dynamic * addition of new plugins. * * Return value: A primary key for identifying the client, * 0 if the client is aborted in the process. */ int a_Capi_open_url(DilloWeb *web, CA_Callback_t Call, void *CbData) { int reload; char *cmd, *server; capi_conn_t *conn = NULL; const char *scheme = URL_SCHEME(web->url); int safe = 0, ret = 0, use_cache = 0; /* reload test */ reload = (!(a_Capi_get_flags(web->url) & CAPI_IsCached) || (URL_FLAGS(web->url) & URL_E2EQuery)); if (web->flags & WEB_Download) { /* download request: if cached save from cache, else * for http, ftp or https, use the downloads dpi */ if (a_Capi_get_flags_with_redirection(web->url) & CAPI_IsCached) { if (web->filename) { if ((web->stream = fopen(web->filename, "w"))) { use_cache = 1; } else { MSG_WARN("Cannot open \"%s\" for writing.\n", web->filename); } } } else if (a_Cache_download_enabled(web->url)) { server = "downloads"; cmd = Capi_dpi_build_cmd(web, server); a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1); dFree(cmd); } } else if (Capi_url_uses_dpi(web->url, &server)) { /* dpi request */ if ((safe = a_Capi_dpi_verify_request(web->bw, web->url))) { if (dStrcasecmp(scheme, "dpi") == 0) { /* make "dpi:/" prefixed urls always reload. */ a_Url_set_flags(web->url, URL_FLAGS(web->url) | URL_E2EQuery); reload = 1; } if (reload) { a_Capi_conn_abort_by_url(web->url); /* Send dpip command */ cmd = Capi_dpi_build_cmd(web, server); a_Capi_dpi_send_cmd(web->url, web->bw, cmd, server, 1); dFree(cmd); } use_cache = 1; } dFree(server); } else if (!dStrcasecmp(scheme, "http")) { /* http request */ if (reload) { a_Capi_conn_abort_by_url(web->url); /* create a new connection and start the CCC operations */ conn = Capi_conn_new(web->url, web->bw, "http", "none"); /* start the reception branch before the query one because the DNS * may callback immediatly. This may avoid a race condition. */ a_Capi_ccc(OpStart, 2, BCK, a_Chain_new(), conn, "http"); a_Capi_ccc(OpStart, 1, BCK, a_Chain_new(), conn, web); } use_cache = 1; } else if (!dStrcasecmp(scheme, "about")) { /* internal request */ use_cache = 1; } if (use_cache) { if (!conn || (conn && Capi_conn_valid(conn))) { /* not aborted, let's continue... */ ret = a_Cache_open_url(web, Call, CbData); } } else { a_Web_free(web); } return ret; }