Example #1
0
/**
 * Create a path from a nsurl using amiga file handling.
 *
 * @param[in] url The url to encode.
 * @param[out] path_out A string containing the result path which should
 *                      be freed by the caller.
 * @return NSERROR_OK and the path is written to \a path or error code
 *         on faliure.
 */
static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out)
{
	lwc_string *urlpath;
	char *path;
	bool match;
	lwc_string *scheme;
	nserror res;
	char *colon;
	char *slash;

	if ((url == NULL) || (path_out == NULL)) {
		return NSERROR_BAD_PARAMETER;
	}

	scheme = nsurl_get_component(url, NSURL_SCHEME);

	if (lwc_string_caseless_isequal(scheme, corestring_lwc_file,
					&match) != lwc_error_ok)
	{
		return NSERROR_BAD_PARAMETER;
	}
	lwc_string_unref(scheme);
	if (match == false) {
		return NSERROR_BAD_PARAMETER;
	}

	urlpath = nsurl_get_component(url, NSURL_PATH);
	if (urlpath == NULL) {
		return NSERROR_BAD_PARAMETER;
	}

	res = url_unescape(lwc_string_data(urlpath) + 1, &path);
	lwc_string_unref(urlpath);
	if (res != NSERROR_OK) {
		return res;
	}

	colon = strchr(path, ':');
	if(colon == NULL)
	{
		slash = strchr(path, '/');
		if(slash)
		{
			*slash = ':';
		}
		else
		{
			int len = strlen(path);
			path[len] = ':';
			path[len + 1] = '\0';
		}
	}

	*path_out = path;

	return NSERROR_OK;
}
Example #2
0
/**
 * Try and find the correct RISC OS filetype from a download context.
 */
static nserror download_ro_filetype(download_context *ctx, bits *ftype_out)
{
	nsurl *url = download_context_get_url(ctx);
	bits ftype = 0;
	lwc_string *scheme;

	/* If the file is local try and read its filetype */
	scheme = nsurl_get_component(url, NSURL_SCHEME);
	if (scheme != NULL) {
		bool filescheme;
		if (lwc_string_isequal(scheme,
				       corestring_lwc_file,
				       &filescheme) != lwc_error_ok) {
			filescheme = false;
		}

		if (filescheme) {
			lwc_string *path = nsurl_get_component(url, NSURL_PATH);
			if (path != NULL && lwc_string_length(path) != 0) {
				char *raw_path;
				if (url_unescape(lwc_string_data(path),
						 lwc_string_length(path),
						 &raw_path) == NSERROR_OK) {
					ftype =	ro_filetype_from_unix_path(raw_path);
					free(raw_path);
				}
			}
		}
	}

	/* If we still don't have a filetype (i.e. failed reading local
	 * one or fetching a remote object), then use the MIME type.
	 */
	if (ftype == 0) {
		/* convert MIME type to RISC OS file type */
		os_error *error;
		const char *mime_type;

		mime_type = download_context_get_mime_type(ctx);
		error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype);
		if (error) {
			LOG("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess);
			ro_warn_user("MiscError", error->errmess);
			ftype = 0xffd;
		}
	}

	*ftype_out = ftype;
	return NSERROR_OK;
}
Example #3
0
/**
 * Open the login dialog
 */
void gui_401login_open(nsurl *url, const char *realm,
		nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
	lwc_string *host = nsurl_get_component(url, NSURL_HOST);
	assert(host != NULL);

	ro_gui_401login_open(url, host, realm, cb, cbpw);

	lwc_string_unref(host);
}
Example #4
0
extern "C" void gui_401login_open(nsurl *url, const char *realm,
		nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
	lwc_string *host;

	host = nsurl_get_component(url, NSURL_HOST);

	create_login_window(url, host, realm, cb, cbpw);

	free(host);
}
Example #5
0
END_TEST

/**
 * check get component asserts on NULL parameter
 */
START_TEST(nsurl_api_assert_get_component1_test)
{
	lwc_string *lwcs;

	lwcs = nsurl_get_component(NULL, NSURL_PATH);
	ck_assert(lwcs == NULL);
}
Example #6
0
extern "C" nserror gui_401login_open(nsurl *url, const char *realm,
		const char *username, const char *password,
		nserror (*cb)(const char *username,
				const char *password,
				void *pw),
		void *cbpw)
{
	lwc_string *host;

	host = nsurl_get_component(url, NSURL_HOST);

	create_login_window(url, host, realm, cb, cbpw);

	free(host);

	return NSERROR_OK;
}
Example #7
0
/** callback to set up a resource fetch context. */
static void *
fetch_resource_setup(struct fetch *fetchh,
		 nsurl *url,
		 bool only_2xx,
		 bool downgrade_tls,
		 const char *post_urlenc,
		 const struct fetch_multipart_data *post_multipart,
		 const char **headers)
{
	struct fetch_resource_context *ctx;
	lwc_string *path;

	ctx = calloc(1, sizeof(*ctx));
	if (ctx == NULL)
		return NULL;

	ctx->handler = fetch_resource_notfound_handler;

	if ((path = nsurl_get_component(url, NSURL_PATH)) != NULL) {
		uint32_t i;
		bool match;

		/* Ensure requested path is valid */
		for (i = 0; i < fetch_resource_path_count; i++) {
			if (lwc_string_isequal(path, 
					fetch_resource_map[i].path, 
					&match) == lwc_error_ok && match) {
				ctx->redirect_url = 
					nsurl_ref(fetch_resource_map[i].url);
				ctx->handler =
					fetch_resource_redirect_handler;
				break;
			}
		}

		lwc_string_unref(path);
	}

	ctx->url = nsurl_ref(url);

	ctx->fetchh = fetchh;

	RING_INSERT(ring, ctx);

	return ctx;
}
Example #8
0
/* exported interface documented in content/fetch.h */
bool fetch_can_fetch(const nsurl *url)
{
	scheme_fetcher *fetcher = fetchers;
	bool match;
	lwc_string *scheme = nsurl_get_component(url, NSURL_SCHEME);

	while (fetcher != NULL) {
		if (lwc_string_isequal(fetcher->scheme_name, scheme, &match) == lwc_error_ok && match == true) {
			break;
		}

		fetcher = fetcher->next_fetcher;
	}

	lwc_string_unref(scheme);

	return fetcher == NULL ? false : fetcher->can_fetch(url);
}
Example #9
0
END_TEST

/**
 * check get component asserts on bad component parameter
 */
START_TEST(nsurl_api_assert_get_component2_test)
{
	nserror err;
	nsurl *res;
	lwc_string *lwcs;

	err = nsurl_create(base_str, &res);
	ck_assert(err == NSERROR_OK);

	lwcs = nsurl_get_component(res, -1);
	ck_assert(lwcs == NULL);

	nsurl_unref(res);
}
Example #10
0
END_TEST

/**
 * refragment url
 */
START_TEST(nsurl_refragment_test)
{
	nserror err;
	nsurl *url;
	nsurl *res_url;
	const struct test_pairs *tst = &fragment_tests[_i];
	lwc_string *frag;

	/* not testing create, this should always succeed */
	err = nsurl_create(tst->test, &url);
	ck_assert(err == NSERROR_OK);

	/* grab the fragment - not testing should succeed */
	frag = nsurl_get_component(url, NSURL_FRAGMENT);
	ck_assert(frag != NULL);
	nsurl_unref(url);

	/* not testing create, this should always succeed */
	err = nsurl_create(tst->res, &url);
	ck_assert(err == NSERROR_OK);

	err = nsurl_refragment(url, frag, &res_url);
	if (tst->res == NULL) {
		/* result must be invalid (bad input) */
		ck_assert(err != NSERROR_OK);
	} else {
		/* result must be valid */
		ck_assert(err == NSERROR_OK);

		ck_assert_str_eq(nsurl_access(res_url), tst->test);

		nsurl_unref(res_url);
	}

	lwc_string_unref(frag);

	nsurl_unref(url);
}
Example #11
0
/** callback to set up a about fetch context. */
static void *
fetch_about_setup(struct fetch *fetchh,
		 nsurl *url,
		 bool only_2xx,
		 bool downgrade_tls,
		 const char *post_urlenc,
		 const struct fetch_multipart_data *post_multipart,
		 const char **headers)
{
	struct fetch_about_context *ctx;
	unsigned int handler_loop;
	lwc_string *path;
	bool match;

	ctx = calloc(1, sizeof(*ctx));
	if (ctx == NULL)
		return NULL;

	path = nsurl_get_component(url, NSURL_PATH);

	for (handler_loop = 0; 
	     handler_loop < about_handler_list_len; 
	     handler_loop++) {
		ctx->handler = about_handler_list[handler_loop].handler;
		if (lwc_string_isequal(path, 
				       about_handler_list[handler_loop].lname, 
				       &match) == lwc_error_ok && match) {
			break;
		}		
	}

	if (path != NULL)
		lwc_string_unref(path);

	ctx->fetchh = fetchh;
	ctx->url = nsurl_ref(url);

	RING_INSERT(ring, ctx);

	return ctx;
}
Example #12
0
/* exported interface documented in content/fetch.h */
struct fetch * fetch_start(nsurl *url, nsurl *referer,
			   fetch_callback callback,
			   void *p, bool only_2xx, const char *post_urlenc,
			   const struct fetch_multipart_data *post_multipart,
			   bool verifiable, bool downgrade_tls,
			   const char *headers[])
{
	struct fetch *fetch;
	scheme_fetcher *fetcher = fetchers;
	lwc_string *scheme;
	bool match;

	fetch = malloc(sizeof (*fetch));
	if (fetch == NULL)
		return NULL;

	/* The URL we're fetching must have a scheme */
	scheme = nsurl_get_component(url, NSURL_SCHEME);
	assert(scheme != NULL);

#ifdef DEBUG_FETCH_VERBOSE
	LOG(("fetch %p, url '%s'", fetch, nsurl_access(url)));
#endif

	/* construct a new fetch structure */
	fetch->callback = callback;
	fetch->url = nsurl_ref(url);
	fetch->verifiable = verifiable;
	fetch->p = p;
	fetch->http_code = 0;
	fetch->r_prev = NULL;
	fetch->r_next = NULL;
	fetch->referer = NULL;
	fetch->send_referer = false;
	fetch->fetcher_handle = NULL;
	fetch->ops = NULL;
	fetch->fetch_is_active = false;
	fetch->host = nsurl_get_component(url, NSURL_HOST);

	if (referer != NULL) {
		lwc_string *ref_scheme;
		fetch->referer = nsurl_ref(referer);

		ref_scheme = nsurl_get_component(referer, NSURL_SCHEME);
		/* Not a problem if referer has no scheme */

		/* Determine whether to send the Referer header */
		if (nsoption_bool(send_referer) && ref_scheme != NULL) {
			/* User permits us to send the header
			 * Only send it if:
			 *    1) The fetch and referer schemes match
			 * or 2) The fetch is https and the referer is http
			 *
			 * This ensures that referer information is only sent
			 * across schemes in the special case of an https
			 * request from a page served over http. The inverse
			 * (https -> http) should not send the referer (15.1.3)
			 */
			bool match1;
			bool match2;
			if (lwc_string_isequal(scheme, ref_scheme,
					       &match) != lwc_error_ok) {
				match = false;
			}
			if (lwc_string_isequal(scheme, corestring_lwc_https,
					       &match1) != lwc_error_ok) {
				match1 = false;
			}
			if (lwc_string_isequal(ref_scheme, corestring_lwc_http,
					       &match2) != lwc_error_ok) {
				match2= false;
			}
			if (match == true || (match1 == true && match2 == true))
				fetch->send_referer = true;
		}
		if (ref_scheme != NULL)
			lwc_string_unref(ref_scheme);
	}

	/* Pick the scheme ops */
	while (fetcher) {
		if ((lwc_string_isequal(fetcher->scheme_name, scheme,
					&match) == lwc_error_ok) && (match == true)) {
			fetch->ops = fetcher;
			break;
		}
		fetcher = fetcher->next_fetcher;
	}

	if (fetch->ops == NULL)
		goto failed;

	/* Got a scheme fetcher, try and set up the fetch */
	fetch->fetcher_handle = fetch->ops->setup_fetch(fetch, url,
							only_2xx, downgrade_tls,
							post_urlenc, post_multipart,
							headers);

	if (fetch->fetcher_handle == NULL)
		goto failed;

	/* Rah, got it, so ref the fetcher. */
	fetch_ref_fetcher(fetch->ops);

	/* these aren't needed past here */
	lwc_string_unref(scheme);

	/* Dump us in the queue and ask the queue to run. */
	RING_INSERT(queue_ring, fetch);
	fetch_dispatch_jobs();

	return fetch;

failed:
	lwc_string_unref(scheme);

	if (fetch->host != NULL)
		lwc_string_unref(fetch->host);
	if (fetch->url != NULL)
		nsurl_unref(fetch->url);
	if (fetch->referer != NULL)
		nsurl_unref(fetch->referer);

	free(fetch);

	return NULL;
}
Example #13
0
/* exported interface documented in image_cache.h */
int image_cache_snentryf(char *string, size_t size, unsigned int entryn,
		const char *fmt)
{
	struct image_cache_entry_s *centry;
	size_t slen = 0; /* current output string length */
	int fmtc = 0; /* current index into format string */
	lwc_string *origin; /* current entry's origin */

	centry = image_cache__findn(entryn);
	if (centry == NULL)
		return -1;

	while((slen < size) && (fmt[fmtc] != 0)) {
		if (fmt[fmtc] == '%') {
			fmtc++;
			switch (fmt[fmtc]) {
			case 'e':
				slen += snprintf(string + slen, size - slen,
						"%d", entryn);
				break;

			case 'r':
				slen += snprintf(string + slen, size - slen,
						"%u", centry->redraw_count);
				break;

			case 'a':
				slen += snprintf(string + slen, size - slen,
						 "%.2f", (float)((image_cache->current_age -  centry->redraw_age)) / 1000);
				break;


			case 'c':
				slen += snprintf(string + slen, size - slen,
						"%d", centry->conversion_count);
				break;

			case 'g':
				slen += snprintf(string + slen, size - slen,
						"%.2f", (float)((image_cache->current_age -  centry->bitmap_age)) / 1000);
				break;

			case 'k':
				slen += snprintf(string + slen, size - slen,
						"%p", centry->content);
				break;

			case 'U':
				slen += snprintf(string + slen, size - slen,
				    		"%s", nsurl_access(llcache_handle_get_url(centry->content->llcache)));
				break;

			case 'o':
				if (nsurl_has_component(llcache_handle_get_url(
						centry->content->llcache),
						NSURL_HOST)) {
					origin = nsurl_get_component(
							llcache_handle_get_url(
							centry->content->
								llcache),
							NSURL_HOST);
					
					slen += snprintf(string + slen,
							size - slen, "%s",
				    			lwc_string_data(
				    				origin));

					lwc_string_unref(origin);
				} else {
					slen += snprintf(string + slen,
							size - slen, "%s",
				    			"localhost");
				}
				break;
			
			case 's':
				if (centry->bitmap != NULL) {
					slen += snprintf(string + slen,
							 size - slen,
							 "%"SSIZET_FMT,
							 centry->bitmap_size);
				} else {
					slen += snprintf(string + slen,
							 size - slen,
							 "0");
				}
				break;
			}
			fmtc++;
		} else {
			string[slen] = fmt[fmtc];
			slen++;
			fmtc++;
		}
	}

	/* Ensure that we NUL-terminate the output */
	string[min(slen, size - 1)] = '\0';

	return slen;
}
Example #14
0
static struct gui_download_window *
gui_download_window_create(download_context *ctx, struct gui_window *gui)
{
	nsurl *url = download_context_get_url(ctx);
	unsigned long total_size = download_context_get_total_length(ctx);
	gchar *domain;
	gchar *destination;
	gboolean unknown_size = total_size == 0;
	const char *size = (total_size == 0 ?
			    messages_get("gtkUnknownSize") :
			    human_friendly_bytesize(total_size));

	nsgtk_download_parent =
		nsgtk_scaffolding_window(nsgtk_get_scaffold(gui));

	struct gui_download_window *download = malloc(sizeof *download);
	if (download == NULL) {
		return NULL;
	}

	/* set the domain to the host component of the url if it exists */
	if (nsurl_has_component(url, NSURL_HOST)) {
		domain = g_strdup(lwc_string_data(nsurl_get_component(url, NSURL_HOST)));
	} else {
		domain = g_strdup(messages_get("gtkUnknownHost"));
	}
	if (domain == NULL) {
		free(download);
		return NULL;
	}

	/* show the dialog */
	destination = nsgtk_download_dialog_show(
		download_context_get_filename(ctx), domain, size);
	if (destination == NULL) {
		g_free(domain);
		free(download);
		return NULL;
	}

	/* Add the new row and store the reference to it (which keeps track of
	 * the tree changes) */
	gtk_list_store_prepend(nsgtk_download_store, &nsgtk_download_iter);
	download->row = gtk_tree_row_reference_new(
		GTK_TREE_MODEL(nsgtk_download_store),
		gtk_tree_model_get_path(
			GTK_TREE_MODEL(nsgtk_download_store),
			&nsgtk_download_iter));

	download->ctx = ctx;
	download->name = g_string_new(download_context_get_filename(ctx));
	download->time_left = g_string_new("");
	download->size_total = total_size;
	download->size_downloaded = 0;
	download->speed = 0;
	download->start_time = g_timer_elapsed(nsgtk_downloads_timer, NULL);
	download->time_remaining = -1;
	download->status = NSGTK_DOWNLOAD_NONE;
	download->progress = 0;
	download->error = NULL;
	download->write =
		g_io_channel_new_file(destination, "w", &download->error);

	if (nsgtk_download_handle_error(download->error)) {
		g_string_free(download->name, TRUE);
		g_string_free(download->time_left, TRUE);
		free(download);
		return NULL;
	}
	g_io_channel_set_encoding(download->write, NULL, &download->error);

	nsgtk_download_change_sensitivity(download, NSGTK_DOWNLOAD_CANCEL);

	nsgtk_download_store_create_item(download);
	nsgtk_download_show(nsgtk_download_parent);

	if (unknown_size)
		nsgtk_download_change_status(download, NSGTK_DOWNLOAD_WORKING);

	if (nsgtk_downloads_num_active == 0) {
		g_timeout_add(UPDATE_RATE,
			      (GSourceFunc) nsgtk_download_update, FALSE);
	}

	nsgtk_downloads_list = g_list_prepend(nsgtk_downloads_list, download);

	return download;
}
Example #15
0
/**
 * Start fetching data for the given URL.
 *
 * The function returns immediately. The fetch may be queued for later
 * processing.
 *
 * A pointer to an opaque struct curl_fetch_info is returned, which can be
 * passed to fetch_abort() to abort the fetch at any time. Returns 0 if memory
 * is exhausted (or some other fatal error occurred).
 *
 * The caller must supply a callback function which is called when anything
 * interesting happens. The callback function is first called with msg
 * FETCH_HEADER, with the header in data, then one or more times
 * with FETCH_DATA with some data for the url, and finally with
 * FETCH_FINISHED. Alternatively, FETCH_ERROR indicates an error occurred:
 * data contains an error message. FETCH_REDIRECT may replace the FETCH_HEADER,
 * FETCH_DATA, FETCH_FINISHED sequence if the server sends a replacement URL.
 *
 * Some private data can be passed as the last parameter to fetch_start, and
 * callbacks will contain this.
 */
static void *
fetch_curl_setup(struct fetch *parent_fetch,
		 nsurl *url,
		 bool only_2xx,
		 bool downgrade_tls,
		 const char *post_urlenc,
		 const struct fetch_multipart_data *post_multipart,
		 const char **headers)
{
	struct curl_fetch_info *fetch;
	struct curl_slist *slist;
	int i;

	fetch = malloc(sizeof (*fetch));
	if (fetch == NULL)
		return 0;

	fetch->fetch_handle = parent_fetch;

	LOG("fetch %p, url '%s'", fetch, nsurl_access(url));

	/* construct a new fetch structure */
	fetch->curl_handle = NULL;
	fetch->had_headers = false;
	fetch->abort = false;
	fetch->stopped = false;
	fetch->only_2xx = only_2xx;
	fetch->downgrade_tls = downgrade_tls;
	fetch->headers = NULL;
	fetch->url = nsurl_ref(url);
	fetch->host = nsurl_get_component(url, NSURL_HOST);
	fetch->location = NULL;
	fetch->content_length = 0;
	fetch->http_code = 0;
	fetch->cookie_string = NULL;
	fetch->realm = NULL;
	fetch->post_urlenc = NULL;
	fetch->post_multipart = NULL;
	if (post_urlenc) {
		fetch->post_urlenc = strdup(post_urlenc);
	} else if (post_multipart) {
		fetch->post_multipart = fetch_curl_post_convert(post_multipart);
	}
	fetch->last_progress_update = 0;

	/* TLS defaults */
	memset(fetch->cert_data, 0, sizeof(fetch->cert_data));
	fetch->cert_depth = -1;

	if ((fetch->host == NULL) ||
	    (post_multipart != NULL && fetch->post_multipart == NULL) ||
	    (post_urlenc != NULL && fetch->post_urlenc == NULL)) {
		goto failed;
	}

#define APPEND(list, value) \
	slist = curl_slist_append(list, value);		\
	if (slist == NULL)				\
		goto failed;				\
	list = slist;

	/* remove curl default headers */
	APPEND(fetch->headers, "Pragma:");

	/* when doing a POST libcurl sends Expect: 100-continue" by default
	 * which fails with lighttpd, so disable it (see bug 1429054) */
	APPEND(fetch->headers, "Expect:");

	if ((nsoption_charp(accept_language) != NULL) &&
	    (nsoption_charp(accept_language)[0] != '\0')) {
		char s[80];
		snprintf(s, sizeof s, "Accept-Language: %s, *;q=0.1",
			 nsoption_charp(accept_language));
		s[sizeof s - 1] = 0;
		APPEND(fetch->headers, s);
	}

	if (nsoption_charp(accept_charset) != NULL &&
	    nsoption_charp(accept_charset)[0] != '\0') {
		char s[80];
		snprintf(s, sizeof s, "Accept-Charset: %s, *;q=0.1",
			 nsoption_charp(accept_charset));
		s[sizeof s - 1] = 0;
		APPEND(fetch->headers, s);
	}

	if (nsoption_bool(do_not_track) == true) {
		APPEND(fetch->headers, "DNT: 1");
	}

	/* And add any headers specified by the caller */
	for (i = 0; headers[i] != NULL; i++) {
		APPEND(fetch->headers, headers[i]);
	}

	return fetch;

#undef APPEND

failed:
	if (fetch->host != NULL)
		lwc_string_unref(fetch->host);

	nsurl_unref(fetch->url);
	free(fetch->post_urlenc);
	if (fetch->post_multipart)
		curl_formfree(fetch->post_multipart);
	curl_slist_free_all(fetch->headers);
	free(fetch);
	return NULL;
}