comparison libpurple/util.c @ 18043:6b7b13adb9b1

propagate from branch 'im.pidgin.pidgin' (head ac83216c7b78e652b47f1fd0bcb91f1eaf2cdf36) to branch 'im.pidgin.pidgin.2.1.0' (head 30a48520e9bc26b0d3914edad456b063cd6cf9fe)
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Mon, 04 Jun 2007 23:48:54 +0000
parents 2188c95d0311 6608a7ab0fd9
children 58e28ccf08e6
comparison
equal deleted inserted replaced
18036:ee9f7ee0be66 18043:6b7b13adb9b1
44 char *page; 44 char *page;
45 45
46 } website; 46 } website;
47 47
48 char *url; 48 char *url;
49 int num_times_redirected;
49 gboolean full; 50 gboolean full;
50 char *user_agent; 51 char *user_agent;
51 gboolean http11; 52 gboolean http11;
52 char *request; 53 char *request;
53 gsize request_written; 54 gsize request_written;
1282 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \ 1283 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \
1283 pt->src_tag = x; \ 1284 pt->src_tag = x; \
1284 pt->dest_tag = y; \ 1285 pt->dest_tag = y; \
1285 tags = g_list_prepend(tags, pt); \ 1286 tags = g_list_prepend(tags, pt); \
1286 } \ 1287 } \
1287 xhtml = g_string_append(xhtml, "<" y); \ 1288 if(xhtml) { \
1288 c += strlen("<" x ); \ 1289 xhtml = g_string_append(xhtml, "<" y); \
1289 xhtml = g_string_append(xhtml, innards->str); \ 1290 xhtml = g_string_append(xhtml, innards->str); \
1290 xhtml = g_string_append_c(xhtml, '>'); \ 1291 xhtml = g_string_append_c(xhtml, '>'); \
1292 } \
1291 c = p + 1; \ 1293 c = p + 1; \
1292 } else { \ 1294 } else { \
1293 xhtml = g_string_append(xhtml, "&lt;"); \ 1295 if(xhtml) \
1294 plain = g_string_append_c(plain, '<'); \ 1296 xhtml = g_string_append(xhtml, "&lt;"); \
1297 if(plain) \
1298 plain = g_string_append_c(plain, '<'); \
1295 c++; \ 1299 c++; \
1296 } \ 1300 } \
1297 g_string_free(innards, TRUE); \ 1301 g_string_free(innards, TRUE); \
1298 continue; \ 1302 continue; \
1299 } \ 1303 } \
1300 if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \ 1304 if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \
1301 (*(c+strlen("<" x)) == '>' || \ 1305 (*(c+strlen("<" x)) == '>' || \
1302 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \ 1306 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \
1303 xhtml = g_string_append(xhtml, "<" y); \ 1307 if(xhtml) \
1308 xhtml = g_string_append(xhtml, "<" y); \
1304 c += strlen("<" x); \ 1309 c += strlen("<" x); \
1305 if(*c != '/') { \ 1310 if(*c != '/') { \
1306 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \ 1311 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \
1307 pt->src_tag = x; \ 1312 pt->src_tag = x; \
1308 pt->dest_tag = y; \ 1313 pt->dest_tag = y; \
1309 tags = g_list_prepend(tags, pt); \ 1314 tags = g_list_prepend(tags, pt); \
1310 xhtml = g_string_append_c(xhtml, '>'); \ 1315 if(xhtml) \
1316 xhtml = g_string_append_c(xhtml, '>'); \
1311 } else { \ 1317 } else { \
1312 xhtml = g_string_append(xhtml, "/>");\ 1318 if(xhtml) \
1319 xhtml = g_string_append(xhtml, "/>");\
1313 } \ 1320 } \
1314 c = strchr(c, '>') + 1; \ 1321 c = strchr(c, '>') + 1; \
1315 continue; \ 1322 continue; \
1316 } 1323 }
1317 #define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x) 1324 #define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x)
1318 void 1325 void
1319 purple_markup_html_to_xhtml(const char *html, char **xhtml_out, 1326 purple_markup_html_to_xhtml(const char *html, char **xhtml_out,
1320 char **plain_out) 1327 char **plain_out)
1321 { 1328 {
1322 GString *xhtml = g_string_new(""); 1329 GString *xhtml = NULL;
1323 GString *plain = g_string_new(""); 1330 GString *plain = NULL;
1324 GList *tags = NULL, *tag; 1331 GList *tags = NULL, *tag;
1325 const char *c = html; 1332 const char *c = html;
1333
1334 g_return_if_fail(xhtml_out != NULL || plain_out != NULL);
1335
1336 if(xhtml_out)
1337 xhtml = g_string_new("");
1338 if(plain_out)
1339 plain = g_string_new("");
1326 1340
1327 while(c && *c) { 1341 while(c && *c) {
1328 if(*c == '<') { 1342 if(*c == '<') {
1329 if(*(c+1) == '/') { /* closing tag */ 1343 if(*(c+1) == '/') { /* closing tag */
1330 tag = tags; 1344 tag = tags;
1337 tag = tag->next; 1351 tag = tag->next;
1338 } 1352 }
1339 if(tag) { 1353 if(tag) {
1340 while(tags) { 1354 while(tags) {
1341 struct purple_parse_tag *pt = tags->data; 1355 struct purple_parse_tag *pt = tags->data;
1342 g_string_append_printf(xhtml, "</%s>", pt->dest_tag); 1356 if(xhtml)
1357 g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
1343 if(tags == tag) 1358 if(tags == tag)
1344 break; 1359 break;
1345 tags = g_list_remove(tags, pt); 1360 tags = g_list_remove(tags, pt);
1346 g_free(pt); 1361 g_free(pt);
1347 } 1362 }
1355 while(*end && g_ascii_isalpha(*end)) 1370 while(*end && g_ascii_isalpha(*end))
1356 end++; 1371 end++;
1357 if(*end == '>') { 1372 if(*end == '>') {
1358 c = end+1; 1373 c = end+1;
1359 } else { 1374 } else {
1360 xhtml = g_string_append(xhtml, "&lt;"); 1375 if(xhtml)
1361 plain = g_string_append_c(plain, '<'); 1376 xhtml = g_string_append(xhtml, "&lt;");
1377 if(plain)
1378 plain = g_string_append_c(plain, '<');
1362 c++; 1379 c++;
1363 } 1380 }
1364 } 1381 }
1365 } else { /* opening tag */ 1382 } else { /* opening tag */
1366 ALLOW_TAG("a"); 1383 ALLOW_TAG("a");
1385 ALLOW_TAG("pre"); 1402 ALLOW_TAG("pre");
1386 ALLOW_TAG("q"); 1403 ALLOW_TAG("q");
1387 ALLOW_TAG("span"); 1404 ALLOW_TAG("span");
1388 ALLOW_TAG("strong"); 1405 ALLOW_TAG("strong");
1389 ALLOW_TAG("ul"); 1406 ALLOW_TAG("ul");
1390 1407 ALLOW_TAG("img");
1408
1391 /* we skip <HR> because it's not legal in XHTML-IM. However, 1409 /* we skip <HR> because it's not legal in XHTML-IM. However,
1392 * we still want to send something sensible, so we put a 1410 * we still want to send something sensible, so we put a
1393 * linebreak in its place. <BR> also needs special handling 1411 * linebreak in its place. <BR> also needs special handling
1394 * because putting a </BR> to close it would just be dumb. */ 1412 * because putting a </BR> to close it would just be dumb. */
1395 if((!g_ascii_strncasecmp(c, "<br", 3) 1413 if((!g_ascii_strncasecmp(c, "<br", 3)
1396 || !g_ascii_strncasecmp(c, "<hr", 3)) 1414 || !g_ascii_strncasecmp(c, "<hr", 3))
1397 && (*(c+3) == '>' || 1415 && (*(c+3) == '>' ||
1398 !g_ascii_strncasecmp(c+3, "/>", 2) || 1416 !g_ascii_strncasecmp(c+3, "/>", 2) ||
1399 !g_ascii_strncasecmp(c+3, " />", 3))) { 1417 !g_ascii_strncasecmp(c+3, " />", 3))) {
1400 c = strchr(c, '>') + 1; 1418 c = strchr(c, '>') + 1;
1401 xhtml = g_string_append(xhtml, "<br/>"); 1419 if(xhtml)
1402 if(*c != '\n') 1420 xhtml = g_string_append(xhtml, "<br/>");
1421 if(plain && *c != '\n')
1403 plain = g_string_append_c(plain, '\n'); 1422 plain = g_string_append_c(plain, '\n');
1404 continue; 1423 continue;
1405 } 1424 }
1406 if(!g_ascii_strncasecmp(c, "<b>", 3) || !g_ascii_strncasecmp(c, "<bold>", strlen("<bold>"))) { 1425 if(!g_ascii_strncasecmp(c, "<b>", 3) || !g_ascii_strncasecmp(c, "<bold>", strlen("<bold>"))) {
1407 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1426 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1408 pt->src_tag = *(c+2) == '>' ? "b" : "bold"; 1427 pt->src_tag = *(c+2) == '>' ? "b" : "bold";
1409 pt->dest_tag = "span"; 1428 pt->dest_tag = "span";
1410 tags = g_list_prepend(tags, pt); 1429 tags = g_list_prepend(tags, pt);
1411 c = strchr(c, '>') + 1; 1430 c = strchr(c, '>') + 1;
1412 xhtml = g_string_append(xhtml, "<span style='font-weight: bold;'>"); 1431 if(xhtml)
1432 xhtml = g_string_append(xhtml, "<span style='font-weight: bold;'>");
1413 continue; 1433 continue;
1414 } 1434 }
1415 if(!g_ascii_strncasecmp(c, "<u>", 3) || !g_ascii_strncasecmp(c, "<underline>", strlen("<underline>"))) { 1435 if(!g_ascii_strncasecmp(c, "<u>", 3) || !g_ascii_strncasecmp(c, "<underline>", strlen("<underline>"))) {
1416 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1436 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1417 pt->src_tag = *(c+2) == '>' ? "u" : "underline"; 1437 pt->src_tag = *(c+2) == '>' ? "u" : "underline";
1418 pt->dest_tag = "span"; 1438 pt->dest_tag = "span";
1419 tags = g_list_prepend(tags, pt); 1439 tags = g_list_prepend(tags, pt);
1420 c = strchr(c, '>') + 1; 1440 c = strchr(c, '>') + 1;
1421 xhtml = g_string_append(xhtml, "<span style='text-decoration: underline;'>"); 1441 if (xhtml)
1442 xhtml = g_string_append(xhtml, "<span style='text-decoration: underline;'>");
1422 continue; 1443 continue;
1423 } 1444 }
1424 if(!g_ascii_strncasecmp(c, "<s>", 3) || !g_ascii_strncasecmp(c, "<strike>", strlen("<strike>"))) { 1445 if(!g_ascii_strncasecmp(c, "<s>", 3) || !g_ascii_strncasecmp(c, "<strike>", strlen("<strike>"))) {
1425 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1446 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1426 pt->src_tag = *(c+2) == '>' ? "s" : "strike"; 1447 pt->src_tag = *(c+2) == '>' ? "s" : "strike";
1427 pt->dest_tag = "span"; 1448 pt->dest_tag = "span";
1428 tags = g_list_prepend(tags, pt); 1449 tags = g_list_prepend(tags, pt);
1429 c = strchr(c, '>') + 1; 1450 c = strchr(c, '>') + 1;
1430 xhtml = g_string_append(xhtml, "<span style='text-decoration: line-through;'>"); 1451 if(xhtml)
1452 xhtml = g_string_append(xhtml, "<span style='text-decoration: line-through;'>");
1431 continue; 1453 continue;
1432 } 1454 }
1433 if(!g_ascii_strncasecmp(c, "<sub>", 5)) { 1455 if(!g_ascii_strncasecmp(c, "<sub>", 5)) {
1434 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1456 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1435 pt->src_tag = "sub"; 1457 pt->src_tag = "sub";
1436 pt->dest_tag = "span"; 1458 pt->dest_tag = "span";
1437 tags = g_list_prepend(tags, pt); 1459 tags = g_list_prepend(tags, pt);
1438 c = strchr(c, '>') + 1; 1460 c = strchr(c, '>') + 1;
1439 xhtml = g_string_append(xhtml, "<span style='vertical-align:sub;'>"); 1461 if(xhtml)
1462 xhtml = g_string_append(xhtml, "<span style='vertical-align:sub;'>");
1440 continue; 1463 continue;
1441 } 1464 }
1442 if(!g_ascii_strncasecmp(c, "<sup>", 5)) { 1465 if(!g_ascii_strncasecmp(c, "<sup>", 5)) {
1443 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1466 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1444 pt->src_tag = "sup"; 1467 pt->src_tag = "sup";
1445 pt->dest_tag = "span"; 1468 pt->dest_tag = "span";
1446 tags = g_list_prepend(tags, pt); 1469 tags = g_list_prepend(tags, pt);
1447 c = strchr(c, '>') + 1; 1470 c = strchr(c, '>') + 1;
1448 xhtml = g_string_append(xhtml, "<span style='vertical-align:super;'>"); 1471 if(xhtml)
1472 xhtml = g_string_append(xhtml, "<span style='vertical-align:super;'>");
1449 continue; 1473 continue;
1450 } 1474 }
1451 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) { 1475 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) {
1452 const char *p = c; 1476 const char *p = c;
1453 GString *style = g_string_new(""); 1477 GString *style = g_string_new("");
1537 pt = g_new0(struct purple_parse_tag, 1); 1561 pt = g_new0(struct purple_parse_tag, 1);
1538 pt->src_tag = "font"; 1562 pt->src_tag = "font";
1539 pt->dest_tag = "span"; 1563 pt->dest_tag = "span";
1540 tags = g_list_prepend(tags, pt); 1564 tags = g_list_prepend(tags, pt);
1541 if(style->len) 1565 if(style->len)
1542 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str)); 1566 {
1567 if(xhtml)
1568 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str));
1569 }
1543 else 1570 else
1544 pt->ignore = TRUE; 1571 pt->ignore = TRUE;
1545 g_string_free(style, TRUE); 1572 g_string_free(style, TRUE);
1546 continue; 1573 continue;
1547 } 1574 }
1557 q++; 1584 q++;
1558 while(*q && *q != '\"' && *q != '\'' && *q != ' ') { 1585 while(*q && *q != '\"' && *q != '\'' && *q != ' ') {
1559 color = g_string_append_c(color, *q); 1586 color = g_string_append_c(color, *q);
1560 q++; 1587 q++;
1561 } 1588 }
1562 g_string_append_printf(xhtml, "<span style='background: %s;'>", g_strstrip(color->str)); 1589 if(xhtml)
1590 g_string_append_printf(xhtml, "<span style='background: %s;'>", g_strstrip(color->str));
1563 g_string_free(color, TRUE); 1591 g_string_free(color, TRUE);
1564 if ((c = strchr(c, '>')) != NULL) 1592 if ((c = strchr(c, '>')) != NULL)
1565 c++; 1593 c++;
1566 else 1594 else
1567 c = p; 1595 c = p;
1578 /* this has to come after the special case for bgcolor */ 1606 /* this has to come after the special case for bgcolor */
1579 ALLOW_TAG("body"); 1607 ALLOW_TAG("body");
1580 if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) { 1608 if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) {
1581 char *p = strstr(c + strlen("<!--"), "-->"); 1609 char *p = strstr(c + strlen("<!--"), "-->");
1582 if(p) { 1610 if(p) {
1583 xhtml = g_string_append(xhtml, "<!--"); 1611 if(xhtml)
1612 xhtml = g_string_append(xhtml, "<!--");
1584 c += strlen("<!--"); 1613 c += strlen("<!--");
1585 continue; 1614 continue;
1586 } 1615 }
1587 } 1616 }
1588 1617
1589 xhtml = g_string_append(xhtml, "&lt;"); 1618 if(xhtml)
1590 plain = g_string_append_c(plain, '<'); 1619 xhtml = g_string_append(xhtml, "&lt;");
1620 if(plain)
1621 plain = g_string_append_c(plain, '<');
1591 c++; 1622 c++;
1592 } 1623 }
1593 } else if(*c == '&') { 1624 } else if(*c == '&') {
1594 char buf[7]; 1625 char buf[7];
1595 const char *pln; 1626 const char *pln;
1598 if ((pln = purple_markup_unescape_entity(c, &len)) == NULL) { 1629 if ((pln = purple_markup_unescape_entity(c, &len)) == NULL) {
1599 len = 1; 1630 len = 1;
1600 g_snprintf(buf, sizeof(buf), "%c", *c); 1631 g_snprintf(buf, sizeof(buf), "%c", *c);
1601 pln = buf; 1632 pln = buf;
1602 } 1633 }
1603 xhtml = g_string_append_len(xhtml, c, len); 1634 if(xhtml)
1604 plain = g_string_append(plain, pln); 1635 xhtml = g_string_append_len(xhtml, c, len);
1636 if(plain)
1637 plain = g_string_append(plain, pln);
1605 c += len; 1638 c += len;
1606 } else { 1639 } else {
1607 xhtml = g_string_append_c(xhtml, *c); 1640 if(xhtml)
1608 plain = g_string_append_c(plain, *c); 1641 xhtml = g_string_append_c(xhtml, *c);
1642 if(plain)
1643 plain = g_string_append_c(plain, *c);
1609 c++; 1644 c++;
1610 } 1645 }
1611 } 1646 }
1612 tag = tags; 1647 if(xhtml) {
1613 while(tag) { 1648 for (tag = tags; tag ; tag = tag->next) {
1614 struct purple_parse_tag *pt = tag->data; 1649 struct purple_parse_tag *pt = tag->data;
1615 if(!pt->ignore) 1650 if(!pt->ignore)
1616 g_string_append_printf(xhtml, "</%s>", pt->dest_tag); 1651 g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
1617 tag = tag->next; 1652 }
1618 } 1653 }
1619 g_list_free(tags); 1654 g_list_free(tags);
1620 if(xhtml_out) 1655 if(xhtml_out)
1621 *xhtml_out = g_strdup(xhtml->str); 1656 *xhtml_out = g_string_free(xhtml, FALSE);
1622 if(plain_out) 1657 if(plain_out)
1623 *plain_out = g_strdup(plain->str); 1658 *plain_out = g_string_free(plain, FALSE);
1624 g_string_free(xhtml, TRUE);
1625 g_string_free(plain, TRUE);
1626 } 1659 }
1627 1660
1628 /* The following are probably reasonable changes: 1661 /* The following are probably reasonable changes:
1629 * - \n should be converted to a normal space 1662 * - \n should be converted to a normal space
1630 * - in addition to <br>, <p> and <div> etc. should also be converted into \n 1663 * - in addition to <br>, <p> and <div> etc. should also be converted into \n
3209 g_free(cmd); 3242 g_free(cmd);
3210 if (params) 3243 if (params)
3211 g_hash_table_destroy(params); 3244 g_hash_table_destroy(params);
3212 } 3245 }
3213 3246
3247 /*
3248 * TODO: Should probably add a "gboolean *ret_ishttps" parameter that
3249 * is set to TRUE if this URL is https, otherwise it is set to
3250 * FALSE. But that change will break the API.
3251 *
3252 * This is important for Yahoo! web messenger login. They now
3253 * force https login, and if you access the web messenger login
3254 * page via http then it redirects you to the https version, but
3255 * purple_util_fetch_url() ignores the "https" and attempts to
3256 * fetch the URL via http again, which gets redirected again.
3257 */
3214 gboolean 3258 gboolean
3215 purple_url_parse(const char *url, char **ret_host, int *ret_port, 3259 purple_url_parse(const char *url, char **ret_host, int *ret_port,
3216 char **ret_path, char **ret_user, char **ret_passwd) 3260 char **ret_path, char **ret_user, char **ret_passwd)
3217 { 3261 {
3218 char scan_info[255]; 3262 char scan_info[255];
3229 static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3273 static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3230 static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3274 static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3231 3275
3232 g_return_val_if_fail(url != NULL, FALSE); 3276 g_return_val_if_fail(url != NULL, FALSE);
3233 3277
3234 if ((turl = strstr(url, "http://")) != NULL || 3278 if ((turl = purple_strcasestr(url, "http://")) != NULL)
3235 (turl = strstr(url, "HTTP://")) != NULL)
3236 { 3279 {
3237 turl += 7; 3280 turl += 7;
3281 url = turl;
3282 }
3283 else if ((turl = purple_strcasestr(url, "https://")) != NULL)
3284 {
3285 turl += 8;
3238 url = turl; 3286 url = turl;
3239 } 3287 }
3240 3288
3241 /* parse out authentication information if supplied */ 3289 /* parse out authentication information if supplied */
3242 /* Only care about @ char BEFORE the first / */ 3290 /* Only care about @ char BEFORE the first / */
3314 static gboolean 3362 static gboolean
3315 parse_redirect(const char *data, size_t data_len, gint sock, 3363 parse_redirect(const char *data, size_t data_len, gint sock,
3316 PurpleUtilFetchUrlData *gfud) 3364 PurpleUtilFetchUrlData *gfud)
3317 { 3365 {
3318 gchar *s; 3366 gchar *s;
3319 3367 gchar *new_url, *temp_url, *end;
3320 if ((s = g_strstr_len(data, data_len, "Location: ")) != NULL) 3368 gboolean full;
3321 { 3369 int len;
3322 gchar *new_url, *temp_url, *end; 3370
3323 gboolean full; 3371 if ((s = g_strstr_len(data, data_len, "Location: ")) == NULL)
3324 int len; 3372 /* We're not being redirected */
3325 3373 return FALSE;
3326 s += strlen("Location: "); 3374
3327 end = strchr(s, '\r'); 3375 s += strlen("Location: ");
3328 3376 end = strchr(s, '\r');
3329 /* Just in case :) */ 3377
3330 if (end == NULL) 3378 /* Just in case :) */
3331 end = strchr(s, '\n'); 3379 if (end == NULL)
3332 3380 end = strchr(s, '\n');
3333 if (end == NULL) 3381
3334 return FALSE; 3382 if (end == NULL)
3335 3383 return FALSE;
3336 len = end - s; 3384
3337 3385 len = end - s;
3338 new_url = g_malloc(len + 1); 3386
3339 strncpy(new_url, s, len); 3387 new_url = g_malloc(len + 1);
3340 new_url[len] = '\0'; 3388 strncpy(new_url, s, len);
3341 3389 new_url[len] = '\0';
3342 full = gfud->full; 3390
3343 3391 full = gfud->full;
3344 if (*new_url == '/' || g_strstr_len(new_url, len, "://") == NULL) 3392
3345 { 3393 if (*new_url == '/' || g_strstr_len(new_url, len, "://") == NULL)
3346 temp_url = new_url; 3394 {
3347 3395 temp_url = new_url;
3348 new_url = g_strdup_printf("%s:%d%s", gfud->website.address, 3396
3349 gfud->website.port, temp_url); 3397 new_url = g_strdup_printf("%s:%d%s", gfud->website.address,
3350 3398 gfud->website.port, temp_url);
3351 g_free(temp_url); 3399
3352 3400 g_free(temp_url);
3353 full = FALSE; 3401
3354 } 3402 full = FALSE;
3355 3403 }
3356 purple_debug_info("util", "Redirecting to %s\n", new_url); 3404
3357 3405 purple_debug_info("util", "Redirecting to %s\n", new_url);
3358 /* 3406
3359 * Try again, with this new location. This code is somewhat 3407 gfud->num_times_redirected++;
3360 * ugly, but we need to reuse the gfud because whoever called 3408 if (gfud->num_times_redirected >= 5)
3361 * us is holding a reference to it. 3409 {
3362 */ 3410 purple_util_fetch_url_error(gfud,
3363 g_free(gfud->url); 3411 _("Could not open %s: Redirected too many times"),
3364 gfud->url = new_url; 3412 gfud->url);
3365 gfud->full = full;
3366 g_free(gfud->request);
3367 gfud->request = NULL;
3368
3369 purple_input_remove(gfud->inpa);
3370 gfud->inpa = 0;
3371 close(gfud->fd);
3372 gfud->fd = -1;
3373 gfud->request_written = 0;
3374 gfud->len = 0;
3375 gfud->data_len = 0;
3376
3377 g_free(gfud->website.user);
3378 g_free(gfud->website.passwd);
3379 g_free(gfud->website.address);
3380 g_free(gfud->website.page);
3381 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port,
3382 &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
3383
3384 gfud->connect_data = purple_proxy_connect(NULL, NULL,
3385 gfud->website.address, gfud->website.port,
3386 url_fetch_connect_cb, gfud);
3387
3388 if (gfud->connect_data == NULL)
3389 {
3390 purple_util_fetch_url_error(gfud, _("Unable to connect to %s"),
3391 gfud->website.address);
3392 }
3393
3394 return TRUE; 3413 return TRUE;
3395 } 3414 }
3396 3415
3397 return FALSE; 3416 /*
3417 * Try again, with this new location. This code is somewhat
3418 * ugly, but we need to reuse the gfud because whoever called
3419 * us is holding a reference to it.
3420 */
3421 g_free(gfud->url);
3422 gfud->url = new_url;
3423 gfud->full = full;
3424 g_free(gfud->request);
3425 gfud->request = NULL;
3426
3427 purple_input_remove(gfud->inpa);
3428 gfud->inpa = 0;
3429 close(gfud->fd);
3430 gfud->fd = -1;
3431 gfud->request_written = 0;
3432 gfud->len = 0;
3433 gfud->data_len = 0;
3434
3435 g_free(gfud->website.user);
3436 g_free(gfud->website.passwd);
3437 g_free(gfud->website.address);
3438 g_free(gfud->website.page);
3439 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port,
3440 &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
3441
3442 gfud->connect_data = purple_proxy_connect(NULL, NULL,
3443 gfud->website.address, gfud->website.port,
3444 url_fetch_connect_cb, gfud);
3445
3446 if (gfud->connect_data == NULL)
3447 {
3448 purple_util_fetch_url_error(gfud, _("Unable to connect to %s"),
3449 gfud->website.address);
3450 }
3451
3452 return TRUE;
3398 } 3453 }
3399 3454
3400 static size_t 3455 static size_t
3401 parse_content_len(const char *data, size_t data_len) 3456 parse_content_len(const char *data, size_t data_len)
3402 { 3457 {