Commit 334499e2 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Remove builtin HTTP client

parent b4635cd8
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -116,10 +116,6 @@ Zoom pictures to screen size in fullscreen
.It Cm -x , --borderless
Create borderless windows.
.
.It Cm -Q , --builtin
Use builtin HTTP client to grab remote files instead of
.Xr wget 1 .
.
.It Cm -P , --cache-thumbnails
Enable (experimental) thumbnail caching in
.Pa ~/.thumbnails .
@@ -993,10 +989,11 @@ binary
.Pq usually distributed in Qo libjpeg-progs Qc or similar
for lossless rotation.
.Pp
To view images from URLs such as http://, you need to have
.Cm wget
available or use the builtin HTTP client
.Pq see Cm --builtin .
To view images from URLs such as http://, you need
.Nm
compiled with libcurl support (enabled by default).  See the
.Sx VERSION
section.
.
.
.Sh BUGS
+0 −2
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ OPTIONS
 -D, --slideshow-delay NUM Set delay between automatically changing slides
     --cycle-once          Exit after one loop through the slideshow
 -R, --reload NUM          Reload images after NUM seconds
 -Q, --builtin             Use builtin http client instead of wget
 -k, --keep-http           Keep local copies when viewing HTTP/FTP files
 -K, --caption-path PATH   Path to caption directory, enables caption display
 -j, --output-dir          With -k: Output directory for saved files
@@ -49,7 +48,6 @@ OPTIONS
 -A, --action ACTION       Specify action to perform when pressing <return>.
                           Executed by /bin/sh, may contain FORMAT SPECIFIERS
     --action[1-9]         Extra actions triggered by pressing keys <1>to <9>
     --action-hold-slide   Do not change to next image after running an action
 -G, --draw-actions        Show the defined actions in the image window
 -m, --montage             Enable montage mode
 -c, --collage             Montage mode with randomly distributed thumbnails
+55 −242
Original line number Diff line number Diff line
@@ -233,8 +233,16 @@ int feh_load_image(Imlib_Image * im, feh_file * file)
	return(1);
}

#ifdef HAVE_LIBCURL

char *feh_http_load_image(char *url)
{
	CURL *curl;
	CURLcode res;
	char *sfn;
	FILE *sfp;
	int fd = -1;
	char *ebuff;
	char *tmpname;
	char *basename;
	char *path = NULL;
@@ -250,205 +258,6 @@ char *feh_http_load_image(char *url)
	basename = strrchr(url, '/') + 1;
	tmpname = feh_unique_filename(path, basename);

	if (opt.builtin_http) {
		/* state for HTTP header parser */
#define SAW_NONE    1
#define SAW_ONE_CM  2
#define SAW_ONE_CJ  3
#define SAW_TWO_CM  4
#define IN_BODY     5

#define OUR_BUF_SIZE 1024
#define EOL "\015\012"

		int sockno = 0;
		int size;
		int body = SAW_NONE;
		struct addrinfo hints;
		struct addrinfo *result, *rp;
		char *hostname;
		char *get_string;
		char *host_string;
		char *query_string;
		char *get_url;
		static char buf[OUR_BUF_SIZE];
		char ua_string[] = "User-Agent: feh image viewer";
		char accept_string[] = "Accept: image/*";
		FILE *fp;

		D(("using builtin http collection\n"));
		fp = fopen(tmpname, "w");
		if (!fp) {
			weprintf("couldn't write to file %s:", tmpname);
			free(tmpname);
			return(NULL);
		}

		hostname = feh_strip_hostname(url);
		if (!hostname) {
			weprintf("couldn't work out hostname from %s:", url);
			fclose(fp);
			unlink(tmpname);
			free(tmpname);
			return(NULL);
		}

		D(("trying hostname %s\n", hostname));

		memset(&hints, 0, sizeof(struct addrinfo));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_flags = AI_NUMERICSERV;
		hints.ai_protocol = 0;
		if (getaddrinfo(hostname, "80", &hints, &result) != 0) {
			weprintf("error resolving host %s:", hostname);
			fclose(fp);
			unlink(tmpname);
			free(hostname);
			free(tmpname);
			return(NULL);
		}
		for (rp = result; rp != NULL; rp = rp->ai_next) {
			sockno = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
			if (sockno == -1) {
				continue;
			}
			if (connect(sockno, rp->ai_addr, rp->ai_addrlen) != -1) {
				break;
			}
			close(sockno);
		}
		if (rp == NULL) {
			weprintf("error connecting socket:");
			freeaddrinfo(result);
			fclose(fp);
			unlink(tmpname);
			free(tmpname);
			free(hostname);
			return(NULL);
		}
		freeaddrinfo(result);

		get_url = strchr(url, '/') + 2;
		get_url = strchr(get_url, '/');

		get_string = estrjoin(" ", "GET", get_url, "HTTP/1.0", NULL);
		host_string = estrjoin(" ", "Host:", hostname, NULL);
		query_string = estrjoin(EOL, get_string, host_string, accept_string, ua_string, "", "", NULL);
		/* At this point query_string looks something like
		 **
		 **    GET /dir/foo.jpg?123456 HTTP/1.0^M^J
		 **    Host: www.example.com^M^J
		 **    Accept: image/ *^M^J
		 **    User-Agent: feh image viewer^M^J
		 **    ^M^J
		 **
		 ** Host: is required by HTTP/1.1 and very important for some sites,
		 ** even with HTTP/1.0
		 **
		 ** -- BEG
		 */
		if ((send(sockno, query_string, strlen(query_string), 0)) == -1) {
			free(get_string);
			free(host_string);
			free(query_string);
			free(tmpname);
			free(hostname);
			weprintf("error sending over socket:");
			return(NULL);
		}
		free(get_string);
		free(host_string);
		free(query_string);
		free(hostname);

		while ((size = read(sockno, &buf, OUR_BUF_SIZE))) {
			if (body == IN_BODY) {
				fwrite(buf, 1, size, fp);
			} else {
				int i;

				for (i = 0; i < size; i++) {
					/* We are looking for ^M^J^M^J, but will accept
					 ** ^J^J from broken servers. Stray ^Ms will be
					 ** ignored.
					 **
					 ** TODO:
					 ** Checking the headers for a
					 **    Content-Type: image/ *
					 ** header would help detect problems with results.
					 ** Maybe look at the response code too? But there is
					 ** no fundamental reason why a 4xx or 5xx response
					 ** could not return an image, it is just the 3xx
					 ** series we need to worry about.
					 **
					 ** Also, grabbing the size from the Content-Length
					 ** header and killing the connection after that
					 ** many bytes where read would speed up closing the
					 ** socket.
					 ** -- BEG
					 */

					switch (body) {

					case IN_BODY:
						fwrite(buf + i, 1, size - i, fp);
						i = size;
						break;

					case SAW_ONE_CM:
						if (buf[i] == '\012') {
							body = SAW_ONE_CJ;
						} else {
							body = SAW_NONE;
						}
						break;

					case SAW_ONE_CJ:
						if (buf[i] == '\015') {
							body = SAW_TWO_CM;
						} else {
							if (buf[i] == '\012') {
								body = IN_BODY;
							} else {
								body = SAW_NONE;
							}
						}
						break;

					case SAW_TWO_CM:
						if (buf[i] == '\012') {
							body = IN_BODY;
						} else {
							body = SAW_NONE;
						}
						break;

					case SAW_NONE:
						if (buf[i] == '\015') {
							body = SAW_ONE_CM;
						} else {
							if (buf[i] == '\012') {
								body = SAW_ONE_CJ;
							}
						}
						break;

					}	/* switch */
				}	/* for i */
			}
		}		/* while read */
		close(sockno);
		fclose(fp);
#ifdef HAVE_LIBCURL
	} else {
		CURL *curl;
		CURLcode res;
		char *sfn;
		FILE *sfp;
		int fd = -1;
		char *ebuff;

	curl = curl_easy_init();
	if (!curl) {
		weprintf("open url: libcurl initialization failure");
@@ -493,15 +302,19 @@ char *feh_http_load_image(char *url)
	curl_easy_cleanup(curl);
	return NULL;
}
#else
	} else {
		weprintf("Please compile feh with curl=1 to enable http support");

#else				/* HAVE_LIBCURL */

char *feh_http_load_image(char *url)
{
	weprintf(
		"Cannot load image %s\n Please recompile with libcurl support",
		url
	);
	return NULL;
}
#endif

	return(tmpname);
}
#endif				/* HAVE_LIBCURL */

char *feh_strip_hostname(char *url)
{
+1 −7
Original line number Diff line number Diff line
@@ -81,8 +81,6 @@ void init_parse_options(int argc, char **argv)
	opt.start_list_at = NULL;
	opt.jump_on_resort = 1;

	opt.builtin_http = 0;

	opt.xinerama = 0;
	opt.screen_clip = 1;
#ifdef HAVE_LIBXINERAMA
@@ -324,7 +322,7 @@ static void feh_getopt_theme(int argc, char **argv)
static void feh_parse_option_array(int argc, char **argv)
{
	static char stropts[] =
		"a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqQrR:sS:tT:uUvVwW:xXy:YzZ"
		"a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:J:kK:lL:mM:nNo:O:pPqrR:sS:tT:uUvVwW:xXy:YzZ"
		"0:1:2:4:5:8:9:.@:^:~:):|:+:";

	/* (*name, has_arg, *flag, val) See: struct option in getopts.h */
@@ -355,7 +353,6 @@ static void feh_parse_option_array(int argc, char **argv)
		{"preload"       , 0, 0, 'p'},
		{"reverse"       , 0, 0, 'n'},
		{"thumbnails"    , 0, 0, 't'},
		{"builtin"       , 0, 0, 'Q'},
		{"scale-down"    , 0, 0, '.'},
		{"no-jump-on-resort", 0, 0, 220},
		{"hide-pointer"  , 0, 0, 'Y'},
@@ -470,9 +467,6 @@ static void feh_parse_option_array(int argc, char **argv)
			opt.list = 1;
			opt.display = 0;
			break;
		case 'Q':
			opt.builtin_http = 1;
			break;
		case 'L':
			opt.customlist = estrdup(optarg);
			opt.display = 0;
+0 −2
Original line number Diff line number Diff line
@@ -63,8 +63,6 @@ struct __fehoptions {
	unsigned char reverse;
	unsigned char no_menus;
	unsigned char scale_down;
	unsigned char builtin_http;
	unsigned char libcurl_http;
	unsigned char bgmode;
	unsigned char xinerama;
	unsigned char screen_clip;
Loading