Index: protocols/yahoo/yahoo_httplib.c
===================================================================
--- protocols/yahoo/yahoo_httplib.c	(revision fcc2da97bcfa5e0d704179fae9c4ed59cbaf79c5)
+++ protocols/yahoo/yahoo_httplib.c	(revision 03f38289e15c27b93f8fdecf22a03353e4d01096)
@@ -30,5 +30,5 @@
 #  define strrchr rindex
 # endif
-char *strchr (), *strrchr ();
+char *strchr(), *strrchr();
 # if !HAVE_MEMCPY
 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
@@ -36,5 +36,4 @@
 # endif
 #endif
-
 
 #include <errno.h>
@@ -63,5 +62,5 @@
 extern enum yahoo_log_level log_level;
 
-int yahoo_tcp_readline(char *ptr, int maxlen, int fd)
+int yahoo_tcp_readline(char *ptr, int maxlen, void *fd)
 {
 	int n, rc;
@@ -71,9 +70,9 @@
 
 		do {
-			rc = read(fd, &c, 1);
-		} while(rc == -1 && (errno == EINTR || errno == EAGAIN)); /* this is bad - it should be done asynchronously */
+			rc = YAHOO_CALLBACK(ext_yahoo_read) (fd, &c, 1);
+		} while (rc == -1 && (errno == EINTR || errno == EAGAIN));	/* this is bad - it should be done asynchronously */
 
 		if (rc == 1) {
-			if(c == '\r')			/* get rid of \r */
+			if (c == '\r')	/* get rid of \r */
 				continue;
 			*ptr = c;
@@ -83,7 +82,7 @@
 		} else if (rc == 0) {
 			if (n == 1)
-				return (0);		/* EOF, no data */
+				return (0);	/* EOF, no data */
 			else
-				break;			/* EOF, w/ data */
+				break;	/* EOF, w/ data */
 		} else {
 			return -1;
@@ -96,10 +95,10 @@
 
 static int url_to_host_port_path(const char *url,
-		char *host, int *port, char *path)
-{
-	char *urlcopy=NULL;
-	char *slash=NULL;
-	char *colon=NULL;
-	
+	char *host, int *port, char *path, int *ssl)
+{
+	char *urlcopy = NULL;
+	char *slash = NULL;
+	char *colon = NULL;
+
 	/*
 	 * http://hostname
@@ -111,8 +110,12 @@
 	 * http://hostname:port/path
 	 * http://hostname:port/path:foo
+	 * and https:// variants of the above
 	 */
 
-	if(strstr(url, "http://") == url) {
-		urlcopy = strdup(url+7);
+	if (strstr(url, "http://") == url) {
+		urlcopy = strdup(url + 7);
+	} else if (strstr(url, "https://") == url) {
+		urlcopy = strdup(url + 8);
+		*ssl = 1;
 	} else {
 		WARNING(("Weird url - unknown protocol: %s", url));
@@ -123,12 +126,15 @@
 	colon = strchr(urlcopy, ':');
 
-	if(!colon || (slash && slash < colon)) {
-		*port = 80;
+	if (!colon || (slash && slash < colon)) {
+		if (*ssl)
+			*port = 443;
+		else
+			*port = 80;
 	} else {
 		*colon = 0;
-		*port = atoi(colon+1);
-	}
-
-	if(!slash) {
+		*port = atoi(colon + 1);
+	}
+
+	if (!slash) {
 		strcpy(path, "/");
 	} else {
@@ -138,5 +144,5 @@
 
 	strcpy(host, urlcopy);
-	
+
 	FREE(urlcopy);
 
@@ -146,31 +152,31 @@
 static int isurlchar(unsigned char c)
 {
-	return (isalnum(c) || '-' == c || '_' == c);
+	return (isalnum(c));
 }
 
 char *yahoo_urlencode(const char *instr)
 {
-	int ipos=0, bpos=0;
+	int ipos = 0, bpos = 0;
 	char *str = NULL;
 	int len = strlen(instr);
 
-	if(!(str = y_new(char, 3*len + 1) ))
-		return "";
-
-	while(instr[ipos]) {
-		while(isurlchar(instr[ipos]))
+	if (!(str = y_new(char, 3 *len + 1)))
+		 return "";
+
+	while (instr[ipos]) {
+		while (isurlchar(instr[ipos]))
 			str[bpos++] = instr[ipos++];
-		if(!instr[ipos])
+		if (!instr[ipos])
 			break;
-		
-		snprintf(&str[bpos], 4, "%%%.2x", instr[ipos]);
-		bpos+=3;
+
+		snprintf(&str[bpos], 4, "%%%02x", instr[ipos] & 0xff);
+		bpos += 3;
 		ipos++;
 	}
-	str[bpos]='\0';
+	str[bpos] = '\0';
 
 	/* free extra alloc'ed mem. */
 	len = strlen(str);
-	str = y_renew(char, str, len+1);
+	str = y_renew(char, str, len + 1);
 
 	return (str);
@@ -179,27 +185,27 @@
 char *yahoo_urldecode(const char *instr)
 {
-	int ipos=0, bpos=0;
+	int ipos = 0, bpos = 0;
 	char *str = NULL;
-	char entity[3]={0,0,0};
+	char entity[3] = { 0, 0, 0 };
 	unsigned dec;
 	int len = strlen(instr);
 
-	if(!(str = y_new(char, len+1) ))
-		return "";
-
-	while(instr[ipos]) {
-		while(instr[ipos] && instr[ipos]!='%')
-			if(instr[ipos]=='+') {
-				str[bpos++]=' ';
+	if (!(str = y_new(char, len + 1)))
+		 return "";
+
+	while (instr[ipos]) {
+		while (instr[ipos] && instr[ipos] != '%')
+			if (instr[ipos] == '+') {
+				str[bpos++] = ' ';
 				ipos++;
 			} else
 				str[bpos++] = instr[ipos++];
-		if(!instr[ipos])
+		if (!instr[ipos])
 			break;
-		
-		if(instr[ipos+1] && instr[ipos+2]) {
+
+		if (instr[ipos + 1] && instr[ipos + 2]) {
 			ipos++;
-			entity[0]=instr[ipos++];
-			entity[1]=instr[ipos++];
+			entity[0] = instr[ipos++];
+			entity[1] = instr[ipos++];
 			sscanf(entity, "%2x", &dec);
 			str[bpos++] = (char)dec;
@@ -208,9 +214,9 @@
 		}
 	}
-	str[bpos]='\0';
+	str[bpos] = '\0';
 
 	/* free extra alloc'ed mem. */
 	len = strlen(str);
-	str = y_renew(char, str, len+1);
+	str = y_renew(char, str, len + 1);
 
 	return (str);
@@ -219,12 +225,12 @@
 char *yahoo_xmldecode(const char *instr)
 {
-	int ipos=0, bpos=0, epos=0;
+	int ipos = 0, bpos = 0, epos = 0;
 	char *str = NULL;
-	char entity[4]={0,0,0,0};
-	char *entitymap[5][2]={
-		{"amp;",  "&"}, 
+	char entity[4] = { 0, 0, 0, 0 };
+	char *entitymap[5][2] = {
+		{"amp;", "&"},
 		{"quot;", "\""},
-		{"lt;",   "<"}, 
-		{"gt;",   "<"}, 
+		{"lt;", "<"},
+		{"gt;", "<"},
 		{"nbsp;", " "}
 	};
@@ -232,23 +238,23 @@
 	int len = strlen(instr);
 
-	if(!(str = y_new(char, len+1) ))
-		return "";
-
-	while(instr[ipos]) {
-		while(instr[ipos] && instr[ipos]!='&')
-			if(instr[ipos]=='+') {
-				str[bpos++]=' ';
+	if (!(str = y_new(char, len + 1)))
+		 return "";
+
+	while (instr[ipos]) {
+		while (instr[ipos] && instr[ipos] != '&')
+			if (instr[ipos] == '+') {
+				str[bpos++] = ' ';
 				ipos++;
 			} else
 				str[bpos++] = instr[ipos++];
-		if(!instr[ipos] || !instr[ipos+1])
+		if (!instr[ipos] || !instr[ipos + 1])
 			break;
 		ipos++;
 
-		if(instr[ipos] == '#') {
+		if (instr[ipos] == '#') {
 			ipos++;
-			epos=0;
-			while(instr[ipos] != ';')
-				entity[epos++]=instr[ipos++];
+			epos = 0;
+			while (instr[ipos] != ';')
+				entity[epos++] = instr[ipos++];
 			sscanf(entity, "%u", &dec);
 			str[bpos++] = (char)dec;
@@ -256,8 +262,8 @@
 		} else {
 			int i;
-			for (i=0; i<5; i++) 
-				if(!strncmp(instr+ipos, entitymap[i][0], 
-					       strlen(entitymap[i][0]))) {
-				       	str[bpos++] = entitymap[i][1][0];
+			for (i = 0; i < 5; i++)
+				if (!strncmp(instr + ipos, entitymap[i][0],
+						strlen(entitymap[i][0]))) {
+					str[bpos++] = entitymap[i][1][0];
 					ipos += strlen(entitymap[i][0]);
 					break;
@@ -265,14 +271,14 @@
 		}
 	}
-	str[bpos]='\0';
+	str[bpos] = '\0';
 
 	/* free extra alloc'ed mem. */
 	len = strlen(str);
-	str = y_renew(char, str, len+1);
+	str = y_renew(char, str, len + 1);
 
 	return (str);
 }
 
-typedef void (*http_connected)(int id, int fd, int error);
+typedef void (*http_connected) (int id, void *fd, int error);
 
 struct callback_data {
@@ -283,28 +289,30 @@
 };
 
-static void connect_complete(int fd, int error, void *data)
+static void connect_complete(void *fd, int error, void *data)
 {
 	struct callback_data *ccd = data;
-	if(error == 0 && fd > 0)
-		write(fd, ccd->request, strlen(ccd->request));
-	FREE(ccd->request);
+	if (error == 0)
+		YAHOO_CALLBACK(ext_yahoo_write) (fd, ccd->request,
+			strlen(ccd->request));
+	free(ccd->request);
 	ccd->callback(ccd->id, fd, error, ccd->user_data);
 	FREE(ccd);
 }
 
-static void yahoo_send_http_request(int id, char *host, int port, char *request, 
-		yahoo_get_fd_callback callback, void *data)
-{
-	struct callback_data *ccd=y_new0(struct callback_data, 1);
+static void yahoo_send_http_request(int id, char *host, int port, char *request,
+	yahoo_get_fd_callback callback, void *data, int use_ssl)
+{
+	struct callback_data *ccd = y_new0(struct callback_data, 1);
 	ccd->callback = callback;
 	ccd->id = id;
 	ccd->request = strdup(request);
 	ccd->user_data = data;
-	
-	YAHOO_CALLBACK(ext_yahoo_connect_async)(id, host, port, connect_complete, ccd);
-}
-
-void yahoo_http_post(int id, const char *url, const char *cookies, long content_length,
-		yahoo_get_fd_callback callback, void *data)
+
+	YAHOO_CALLBACK(ext_yahoo_connect_async) (id, host, port,
+		connect_complete, ccd, use_ssl);
+}
+
+void yahoo_http_post(int id, const char *url, const char *cookies,
+	long content_length, yahoo_get_fd_callback callback, void *data)
 {
 	char host[255];
@@ -312,120 +320,85 @@
 	char path[255];
 	char buff[1024];
-	
-	if(!url_to_host_port_path(url, host, &port, path))
+	int ssl = 0;
+
+	if (!url_to_host_port_path(url, host, &port, path, &ssl))
 		return;
 
-	snprintf(buff, sizeof(buff), 
-			"POST %s HTTP/1.0\r\n"
-			"Content-length: %ld\r\n"
-			"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n"
-			"Host: %s:%d\r\n"
-			"Cookie: %s\r\n"
-			"\r\n",
-			path, content_length, 
-			host, port,
-			cookies);
-
-	yahoo_send_http_request(id, host, port, buff, callback, data);
-}
-
-void yahoo_http_get(int id, const char *url, const char *cookies,
-		yahoo_get_fd_callback callback, void *data)
+	/* thanks to kopete dumpcap */
+	snprintf(buff, sizeof(buff),
+		"POST %s HTTP/1.1\r\n"
+		"Cookie: %s\r\n"
+		"User-Agent: Mozilla/5.0\r\n"
+		"Host: %s\r\n"
+		"Content-Length: %ld\r\n"
+		"Cache-Control: no-cache\r\n"
+		"\r\n", path, cookies, host, content_length);
+
+	yahoo_send_http_request(id, host, port, buff, callback, data, ssl);
+}
+
+void yahoo_http_get(int id, const char *url, const char *cookies, int http11,
+	int keepalive, yahoo_get_fd_callback callback, void *data)
 {
 	char host[255];
 	int port = 80;
 	char path[255];
-	char buff[1024];
-	
-	if(!url_to_host_port_path(url, host, &port, path))
+	char buff[2048];
+	char cookiebuff[1024];
+	int ssl = 0;
+
+	if (!url_to_host_port_path(url, host, &port, path, &ssl))
 		return;
 
-	snprintf(buff, sizeof(buff), 
-			"GET %s HTTP/1.0\r\n"
-			"Host: %s:%d\r\n"
-			"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n"
-			"Cookie: %s\r\n"
-			"\r\n",
-			path, host, port, cookies);
-
-	yahoo_send_http_request(id, host, port, buff, callback, data);
-}
-
-struct url_data {
-	yahoo_get_url_handle_callback callback;
-	void *user_data;
-};
-
-static void yahoo_got_url_fd(int id, int fd, int error, void *data)
-{
-	char *tmp=NULL;
-	char buff[1024];
-	unsigned long filesize=0;
-	char *filename=NULL;
-	int n;
-
-	struct url_data *ud = data;
-
-	if(error || fd < 0) {
-		ud->callback(id, fd, error, filename, filesize, ud->user_data);
-		FREE(ud);
+	/* Allow cases when we don't need to send a cookie */
+	if (cookies)
+		snprintf(cookiebuff, sizeof(cookiebuff), "Cookie: %s\r\n",
+			cookies);
+	else
+		cookiebuff[0] = '\0';
+
+	snprintf(buff, sizeof(buff),
+		"GET %s HTTP/1.%s\r\n"
+		"%sHost: %s\r\n"
+		"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n"
+		"Accept: */*\r\n"
+		"%s" "\r\n", path, http11?"1":"0", cookiebuff, host,
+		keepalive? "Connection: Keep-Alive\r\n":"Connection: close\r\n");
+
+	yahoo_send_http_request(id, host, port, buff, callback, data, ssl);
+}
+
+void yahoo_http_head(int id, const char *url, const char *cookies, int len,
+	char *payload, yahoo_get_fd_callback callback, void *data)
+{
+	char host[255];
+	int port = 80;
+	char path[255];
+	char buff[2048];
+	char cookiebuff[1024];
+	int ssl = 0;
+
+	if (!url_to_host_port_path(url, host, &port, path, &ssl))
 		return;
-	}
-
-	while((n=yahoo_tcp_readline(buff, sizeof(buff), fd)) > 0) {
-		LOG(("Read:%s:\n", buff));
-		if(!strcmp(buff, ""))
-			break;
-
-		if( !strncasecmp(buff, "Content-length:", 
-				strlen("Content-length:")) ) {
-			tmp = strrchr(buff, ' ');
-			if(tmp)
-				filesize = atol(tmp);
-		}
-
-		if( !strncasecmp(buff, "Content-disposition:", 
-				strlen("Content-disposition:")) ) {
-			tmp = strstr(buff, "name=");
-			if(tmp) {
-				tmp+=strlen("name=");
-				if(tmp[0] == '"') {
-					char *tmp2;
-					tmp++;
-					tmp2 = strchr(tmp, '"');
-					if(tmp2)
-						*tmp2 = '\0';
-				} else {
-					char *tmp2;
-					tmp2 = strchr(tmp, ';');
-					if(!tmp2)
-						tmp2 = strchr(tmp, '\r');
-					if(!tmp2)
-						tmp2 = strchr(tmp, '\n');
-					if(tmp2)
-						*tmp2 = '\0';
-				}
-
-				filename = strdup(tmp);
-			}
-		}
-	}
-
-	LOG(("n == %d\n", n));
-	LOG(("Calling callback, filename:%s, size: %ld\n", filename, filesize));
-	ud->callback(id, fd, error, filename, filesize, ud->user_data);
-	FREE(ud);
-	FREE(filename);
-}
-
-void yahoo_get_url_fd(int id, const char *url, const struct yahoo_data *yd,
-		yahoo_get_url_handle_callback callback, void *data)
-{
-	char buff[1024];
-	struct url_data *ud = y_new0(struct url_data, 1);
-	snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);
-	ud->callback = callback;
-	ud->user_data = data;
-	yahoo_http_get(id, url, buff, yahoo_got_url_fd, ud);
-}
-
+
+	/* Allow cases when we don't need to send a cookie */
+	if (cookies)
+		snprintf(cookiebuff, sizeof(cookiebuff), "Cookie: %s\r\n",
+			cookies);
+	else
+		cookiebuff[0] = '\0';
+
+	snprintf(buff, sizeof(buff),
+		"HEAD %s HTTP/1.0\r\n"
+		"Accept: */*\r\n"
+		"Host: %s:%d\r\n"
+		"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n"
+		"%s"
+		"Content-Length: %d\r\n"
+		"Cache-Control: no-cache\r\n"
+		"\r\n%s", path, host, port, cookiebuff, len,
+		payload?payload:"");
+
+	yahoo_send_http_request(id, host, port, buff, callback, data, ssl);
+}
+
