comparison libpurple/util.c @ 18041:678d78b7fa34

propagate from branch 'im.pidgin.pidgin' (head a58972b72c7aa0fa0899c5a6b96e51cd6c427ab4) to branch 'im.pidgin.pidgin.2.1.0' (head 03df10bd904eed59317242a557aed2b8430d9630)
author Richard Laager <rlaager@wiktel.com>
date Mon, 04 Jun 2007 05:55:13 +0000
parents c588a4a9d287 6608a7ab0fd9
children 25819c54a963
comparison
equal deleted inserted replaced
18040:541a6b0112c6 18041:678d78b7fa34
45 char *page; 45 char *page;
46 46
47 } website; 47 } website;
48 48
49 char *url; 49 char *url;
50 int num_times_redirected;
50 gboolean full; 51 gboolean full;
51 char *user_agent; 52 char *user_agent;
52 gboolean http11; 53 gboolean http11;
53 char *request; 54 char *request;
54 gsize request_written; 55 gsize request_written;
1283 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \ 1284 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \
1284 pt->src_tag = x; \ 1285 pt->src_tag = x; \
1285 pt->dest_tag = y; \ 1286 pt->dest_tag = y; \
1286 tags = g_list_prepend(tags, pt); \ 1287 tags = g_list_prepend(tags, pt); \
1287 } \ 1288 } \
1288 xhtml = g_string_append(xhtml, "<" y); \ 1289 if(xhtml) { \
1289 c += strlen("<" x ); \ 1290 xhtml = g_string_append(xhtml, "<" y); \
1290 xhtml = g_string_append(xhtml, innards->str); \ 1291 xhtml = g_string_append(xhtml, innards->str); \
1291 xhtml = g_string_append_c(xhtml, '>'); \ 1292 xhtml = g_string_append_c(xhtml, '>'); \
1293 } \
1292 c = p + 1; \ 1294 c = p + 1; \
1293 } else { \ 1295 } else { \
1294 xhtml = g_string_append(xhtml, "&lt;"); \ 1296 if(xhtml) \
1295 plain = g_string_append_c(plain, '<'); \ 1297 xhtml = g_string_append(xhtml, "&lt;"); \
1298 if(plain) \
1299 plain = g_string_append_c(plain, '<'); \
1296 c++; \ 1300 c++; \
1297 } \ 1301 } \
1298 g_string_free(innards, TRUE); \ 1302 g_string_free(innards, TRUE); \
1299 continue; \ 1303 continue; \
1300 } \ 1304 } \
1301 if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \ 1305 if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \
1302 (*(c+strlen("<" x)) == '>' || \ 1306 (*(c+strlen("<" x)) == '>' || \
1303 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \ 1307 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \
1304 xhtml = g_string_append(xhtml, "<" y); \ 1308 if(xhtml) \
1309 xhtml = g_string_append(xhtml, "<" y); \
1305 c += strlen("<" x); \ 1310 c += strlen("<" x); \
1306 if(*c != '/') { \ 1311 if(*c != '/') { \
1307 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \ 1312 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \
1308 pt->src_tag = x; \ 1313 pt->src_tag = x; \
1309 pt->dest_tag = y; \ 1314 pt->dest_tag = y; \
1310 tags = g_list_prepend(tags, pt); \ 1315 tags = g_list_prepend(tags, pt); \
1311 xhtml = g_string_append_c(xhtml, '>'); \ 1316 if(xhtml) \
1317 xhtml = g_string_append_c(xhtml, '>'); \
1312 } else { \ 1318 } else { \
1313 xhtml = g_string_append(xhtml, "/>");\ 1319 if(xhtml) \
1320 xhtml = g_string_append(xhtml, "/>");\
1314 } \ 1321 } \
1315 c = strchr(c, '>') + 1; \ 1322 c = strchr(c, '>') + 1; \
1316 continue; \ 1323 continue; \
1317 } 1324 }
1318 #define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x) 1325 #define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x)
1319 void 1326 void
1320 purple_markup_html_to_xhtml(const char *html, char **xhtml_out, 1327 purple_markup_html_to_xhtml(const char *html, char **xhtml_out,
1321 char **plain_out) 1328 char **plain_out)
1322 { 1329 {
1323 GString *xhtml = g_string_new(""); 1330 GString *xhtml = NULL;
1324 GString *plain = g_string_new(""); 1331 GString *plain = NULL;
1325 GList *tags = NULL, *tag; 1332 GList *tags = NULL, *tag;
1326 const char *c = html; 1333 const char *c = html;
1334
1335 g_return_if_fail(xhtml_out != NULL || plain_out != NULL);
1336
1337 if(xhtml_out)
1338 xhtml = g_string_new("");
1339 if(plain_out)
1340 plain = g_string_new("");
1327 1341
1328 while(c && *c) { 1342 while(c && *c) {
1329 if(*c == '<') { 1343 if(*c == '<') {
1330 if(*(c+1) == '/') { /* closing tag */ 1344 if(*(c+1) == '/') { /* closing tag */
1331 tag = tags; 1345 tag = tags;
1338 tag = tag->next; 1352 tag = tag->next;
1339 } 1353 }
1340 if(tag) { 1354 if(tag) {
1341 while(tags) { 1355 while(tags) {
1342 struct purple_parse_tag *pt = tags->data; 1356 struct purple_parse_tag *pt = tags->data;
1343 g_string_append_printf(xhtml, "</%s>", pt->dest_tag); 1357 if(xhtml)
1358 g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
1344 if(tags == tag) 1359 if(tags == tag)
1345 break; 1360 break;
1346 tags = g_list_remove(tags, pt); 1361 tags = g_list_remove(tags, pt);
1347 g_free(pt); 1362 g_free(pt);
1348 } 1363 }
1356 while(*end && g_ascii_isalpha(*end)) 1371 while(*end && g_ascii_isalpha(*end))
1357 end++; 1372 end++;
1358 if(*end == '>') { 1373 if(*end == '>') {
1359 c = end+1; 1374 c = end+1;
1360 } else { 1375 } else {
1361 xhtml = g_string_append(xhtml, "&lt;"); 1376 if(xhtml)
1362 plain = g_string_append_c(plain, '<'); 1377 xhtml = g_string_append(xhtml, "&lt;");
1378 if(plain)
1379 plain = g_string_append_c(plain, '<');
1363 c++; 1380 c++;
1364 } 1381 }
1365 } 1382 }
1366 } else { /* opening tag */ 1383 } else { /* opening tag */
1367 ALLOW_TAG("a"); 1384 ALLOW_TAG("a");
1386 ALLOW_TAG("pre"); 1403 ALLOW_TAG("pre");
1387 ALLOW_TAG("q"); 1404 ALLOW_TAG("q");
1388 ALLOW_TAG("span"); 1405 ALLOW_TAG("span");
1389 ALLOW_TAG("strong"); 1406 ALLOW_TAG("strong");
1390 ALLOW_TAG("ul"); 1407 ALLOW_TAG("ul");
1391 1408 ALLOW_TAG("img");
1409
1392 /* we skip <HR> because it's not legal in XHTML-IM. However, 1410 /* we skip <HR> because it's not legal in XHTML-IM. However,
1393 * we still want to send something sensible, so we put a 1411 * we still want to send something sensible, so we put a
1394 * linebreak in its place. <BR> also needs special handling 1412 * linebreak in its place. <BR> also needs special handling
1395 * because putting a </BR> to close it would just be dumb. */ 1413 * because putting a </BR> to close it would just be dumb. */
1396 if((!g_ascii_strncasecmp(c, "<br", 3) 1414 if((!g_ascii_strncasecmp(c, "<br", 3)
1397 || !g_ascii_strncasecmp(c, "<hr", 3)) 1415 || !g_ascii_strncasecmp(c, "<hr", 3))
1398 && (*(c+3) == '>' || 1416 && (*(c+3) == '>' ||
1399 !g_ascii_strncasecmp(c+3, "/>", 2) || 1417 !g_ascii_strncasecmp(c+3, "/>", 2) ||
1400 !g_ascii_strncasecmp(c+3, " />", 3))) { 1418 !g_ascii_strncasecmp(c+3, " />", 3))) {
1401 c = strchr(c, '>') + 1; 1419 c = strchr(c, '>') + 1;
1402 xhtml = g_string_append(xhtml, "<br/>"); 1420 if(xhtml)
1403 if(*c != '\n') 1421 xhtml = g_string_append(xhtml, "<br/>");
1422 if(plain && *c != '\n')
1404 plain = g_string_append_c(plain, '\n'); 1423 plain = g_string_append_c(plain, '\n');
1405 continue; 1424 continue;
1406 } 1425 }
1407 if(!g_ascii_strncasecmp(c, "<img", 4) && (*(c+4) == '>' || *(c+4) == ' ')) { 1426 if(!g_ascii_strncasecmp(c, "<img", 4) && (*(c+4) == '>' || *(c+4) == ' ')) {
1408 const char *p = c; 1427 const char *p = c;
1442 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1461 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1443 pt->src_tag = *(c+2) == '>' ? "b" : "bold"; 1462 pt->src_tag = *(c+2) == '>' ? "b" : "bold";
1444 pt->dest_tag = "span"; 1463 pt->dest_tag = "span";
1445 tags = g_list_prepend(tags, pt); 1464 tags = g_list_prepend(tags, pt);
1446 c = strchr(c, '>') + 1; 1465 c = strchr(c, '>') + 1;
1447 xhtml = g_string_append(xhtml, "<span style='font-weight: bold;'>"); 1466 if(xhtml)
1467 xhtml = g_string_append(xhtml, "<span style='font-weight: bold;'>");
1448 continue; 1468 continue;
1449 } 1469 }
1450 if(!g_ascii_strncasecmp(c, "<u>", 3) || !g_ascii_strncasecmp(c, "<underline>", strlen("<underline>"))) { 1470 if(!g_ascii_strncasecmp(c, "<u>", 3) || !g_ascii_strncasecmp(c, "<underline>", strlen("<underline>"))) {
1451 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1471 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1452 pt->src_tag = *(c+2) == '>' ? "u" : "underline"; 1472 pt->src_tag = *(c+2) == '>' ? "u" : "underline";
1453 pt->dest_tag = "span"; 1473 pt->dest_tag = "span";
1454 tags = g_list_prepend(tags, pt); 1474 tags = g_list_prepend(tags, pt);
1455 c = strchr(c, '>') + 1; 1475 c = strchr(c, '>') + 1;
1456 xhtml = g_string_append(xhtml, "<span style='text-decoration: underline;'>"); 1476 if (xhtml)
1477 xhtml = g_string_append(xhtml, "<span style='text-decoration: underline;'>");
1457 continue; 1478 continue;
1458 } 1479 }
1459 if(!g_ascii_strncasecmp(c, "<s>", 3) || !g_ascii_strncasecmp(c, "<strike>", strlen("<strike>"))) { 1480 if(!g_ascii_strncasecmp(c, "<s>", 3) || !g_ascii_strncasecmp(c, "<strike>", strlen("<strike>"))) {
1460 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1481 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1461 pt->src_tag = *(c+2) == '>' ? "s" : "strike"; 1482 pt->src_tag = *(c+2) == '>' ? "s" : "strike";
1462 pt->dest_tag = "span"; 1483 pt->dest_tag = "span";
1463 tags = g_list_prepend(tags, pt); 1484 tags = g_list_prepend(tags, pt);
1464 c = strchr(c, '>') + 1; 1485 c = strchr(c, '>') + 1;
1465 xhtml = g_string_append(xhtml, "<span style='text-decoration: line-through;'>"); 1486 if(xhtml)
1487 xhtml = g_string_append(xhtml, "<span style='text-decoration: line-through;'>");
1466 continue; 1488 continue;
1467 } 1489 }
1468 if(!g_ascii_strncasecmp(c, "<sub>", 5)) { 1490 if(!g_ascii_strncasecmp(c, "<sub>", 5)) {
1469 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1491 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1470 pt->src_tag = "sub"; 1492 pt->src_tag = "sub";
1471 pt->dest_tag = "span"; 1493 pt->dest_tag = "span";
1472 tags = g_list_prepend(tags, pt); 1494 tags = g_list_prepend(tags, pt);
1473 c = strchr(c, '>') + 1; 1495 c = strchr(c, '>') + 1;
1474 xhtml = g_string_append(xhtml, "<span style='vertical-align:sub;'>"); 1496 if(xhtml)
1497 xhtml = g_string_append(xhtml, "<span style='vertical-align:sub;'>");
1475 continue; 1498 continue;
1476 } 1499 }
1477 if(!g_ascii_strncasecmp(c, "<sup>", 5)) { 1500 if(!g_ascii_strncasecmp(c, "<sup>", 5)) {
1478 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); 1501 struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
1479 pt->src_tag = "sup"; 1502 pt->src_tag = "sup";
1480 pt->dest_tag = "span"; 1503 pt->dest_tag = "span";
1481 tags = g_list_prepend(tags, pt); 1504 tags = g_list_prepend(tags, pt);
1482 c = strchr(c, '>') + 1; 1505 c = strchr(c, '>') + 1;
1483 xhtml = g_string_append(xhtml, "<span style='vertical-align:super;'>"); 1506 if(xhtml)
1507 xhtml = g_string_append(xhtml, "<span style='vertical-align:super;'>");
1484 continue; 1508 continue;
1485 } 1509 }
1486 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) { 1510 if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) {
1487 const char *p = c; 1511 const char *p = c;
1488 GString *style = g_string_new(""); 1512 GString *style = g_string_new("");
1572 pt = g_new0(struct purple_parse_tag, 1); 1596 pt = g_new0(struct purple_parse_tag, 1);
1573 pt->src_tag = "font"; 1597 pt->src_tag = "font";
1574 pt->dest_tag = "span"; 1598 pt->dest_tag = "span";
1575 tags = g_list_prepend(tags, pt); 1599 tags = g_list_prepend(tags, pt);
1576 if(style->len) 1600 if(style->len)
1577 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str)); 1601 {
1602 if(xhtml)
1603 g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str));
1604 }
1578 else 1605 else
1579 pt->ignore = TRUE; 1606 pt->ignore = TRUE;
1580 g_string_free(style, TRUE); 1607 g_string_free(style, TRUE);
1581 continue; 1608 continue;
1582 } 1609 }
1592 q++; 1619 q++;
1593 while(*q && *q != '\"' && *q != '\'' && *q != ' ') { 1620 while(*q && *q != '\"' && *q != '\'' && *q != ' ') {
1594 color = g_string_append_c(color, *q); 1621 color = g_string_append_c(color, *q);
1595 q++; 1622 q++;
1596 } 1623 }
1597 g_string_append_printf(xhtml, "<span style='background: %s;'>", g_strstrip(color->str)); 1624 if(xhtml)
1625 g_string_append_printf(xhtml, "<span style='background: %s;'>", g_strstrip(color->str));
1598 g_string_free(color, TRUE); 1626 g_string_free(color, TRUE);
1599 if ((c = strchr(c, '>')) != NULL) 1627 if ((c = strchr(c, '>')) != NULL)
1600 c++; 1628 c++;
1601 else 1629 else
1602 c = p; 1630 c = p;
1613 /* this has to come after the special case for bgcolor */ 1641 /* this has to come after the special case for bgcolor */
1614 ALLOW_TAG("body"); 1642 ALLOW_TAG("body");
1615 if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) { 1643 if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) {
1616 char *p = strstr(c + strlen("<!--"), "-->"); 1644 char *p = strstr(c + strlen("<!--"), "-->");
1617 if(p) { 1645 if(p) {
1618 xhtml = g_string_append(xhtml, "<!--"); 1646 if(xhtml)
1647 xhtml = g_string_append(xhtml, "<!--");
1619 c += strlen("<!--"); 1648 c += strlen("<!--");
1620 continue; 1649 continue;
1621 } 1650 }
1622 } 1651 }
1623 1652
1624 xhtml = g_string_append(xhtml, "&lt;"); 1653 if(xhtml)
1625 plain = g_string_append_c(plain, '<'); 1654 xhtml = g_string_append(xhtml, "&lt;");
1655 if(plain)
1656 plain = g_string_append_c(plain, '<');
1626 c++; 1657 c++;
1627 } 1658 }
1628 } else if(*c == '&') { 1659 } else if(*c == '&') {
1629 char buf[7]; 1660 char buf[7];
1630 const char *pln; 1661 const char *pln;
1633 if ((pln = purple_markup_unescape_entity(c, &len)) == NULL) { 1664 if ((pln = purple_markup_unescape_entity(c, &len)) == NULL) {
1634 len = 1; 1665 len = 1;
1635 g_snprintf(buf, sizeof(buf), "%c", *c); 1666 g_snprintf(buf, sizeof(buf), "%c", *c);
1636 pln = buf; 1667 pln = buf;
1637 } 1668 }
1638 xhtml = g_string_append_len(xhtml, c, len); 1669 if(xhtml)
1639 plain = g_string_append(plain, pln); 1670 xhtml = g_string_append_len(xhtml, c, len);
1671 if(plain)
1672 plain = g_string_append(plain, pln);
1640 c += len; 1673 c += len;
1641 } else { 1674 } else {
1642 xhtml = g_string_append_c(xhtml, *c); 1675 if(xhtml)
1643 plain = g_string_append_c(plain, *c); 1676 xhtml = g_string_append_c(xhtml, *c);
1677 if(plain)
1678 plain = g_string_append_c(plain, *c);
1644 c++; 1679 c++;
1645 } 1680 }
1646 } 1681 }
1647 tag = tags; 1682 if(xhtml) {
1648 while(tag) { 1683 for (tag = tags; tag ; tag = tag->next) {
1649 struct purple_parse_tag *pt = tag->data; 1684 struct purple_parse_tag *pt = tag->data;
1650 if(!pt->ignore) 1685 if(!pt->ignore)
1651 g_string_append_printf(xhtml, "</%s>", pt->dest_tag); 1686 g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
1652 tag = tag->next; 1687 }
1653 } 1688 }
1654 g_list_free(tags); 1689 g_list_free(tags);
1655 if(xhtml_out) 1690 if(xhtml_out)
1656 *xhtml_out = g_strdup(xhtml->str); 1691 *xhtml_out = g_string_free(xhtml, FALSE);
1657 if(plain_out) 1692 if(plain_out)
1658 *plain_out = g_strdup(plain->str); 1693 *plain_out = g_string_free(plain, FALSE);
1659 g_string_free(xhtml, TRUE);
1660 g_string_free(plain, TRUE);
1661 } 1694 }
1662 1695
1663 /* The following are probably reasonable changes: 1696 /* The following are probably reasonable changes:
1664 * - \n should be converted to a normal space 1697 * - \n should be converted to a normal space
1665 * - in addition to <br>, <p> and <div> etc. should also be converted into \n 1698 * - in addition to <br>, <p> and <div> etc. should also be converted into \n
3271 g_free(cmd); 3304 g_free(cmd);
3272 if (params) 3305 if (params)
3273 g_hash_table_destroy(params); 3306 g_hash_table_destroy(params);
3274 } 3307 }
3275 3308
3309 /*
3310 * TODO: Should probably add a "gboolean *ret_ishttps" parameter that
3311 * is set to TRUE if this URL is https, otherwise it is set to
3312 * FALSE. But that change will break the API.
3313 *
3314 * This is important for Yahoo! web messenger login. They now
3315 * force https login, and if you access the web messenger login
3316 * page via http then it redirects you to the https version, but
3317 * purple_util_fetch_url() ignores the "https" and attempts to
3318 * fetch the URL via http again, which gets redirected again.
3319 */
3276 gboolean 3320 gboolean
3277 purple_url_parse(const char *url, char **ret_host, int *ret_port, 3321 purple_url_parse(const char *url, char **ret_host, int *ret_port,
3278 char **ret_path, char **ret_user, char **ret_passwd) 3322 char **ret_path, char **ret_user, char **ret_passwd)
3279 { 3323 {
3280 char scan_info[255]; 3324 char scan_info[255];
3291 static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3335 static char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3292 static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; 3336 static char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-";
3293 3337
3294 g_return_val_if_fail(url != NULL, FALSE); 3338 g_return_val_if_fail(url != NULL, FALSE);
3295 3339
3296 if ((turl = strstr(url, "http://")) != NULL || 3340 if ((turl = purple_strcasestr(url, "http://")) != NULL)
3297 (turl = strstr(url, "HTTP://")) != NULL)
3298 { 3341 {
3299 turl += 7; 3342 turl += 7;
3343 url = turl;
3344 }
3345 else if ((turl = purple_strcasestr(url, "https://")) != NULL)
3346 {
3347 turl += 8;
3300 url = turl; 3348 url = turl;
3301 } 3349 }
3302 3350
3303 /* parse out authentication information if supplied */ 3351 /* parse out authentication information if supplied */
3304 /* Only care about @ char BEFORE the first / */ 3352 /* Only care about @ char BEFORE the first / */
3376 static gboolean 3424 static gboolean
3377 parse_redirect(const char *data, size_t data_len, gint sock, 3425 parse_redirect(const char *data, size_t data_len, gint sock,
3378 PurpleUtilFetchUrlData *gfud) 3426 PurpleUtilFetchUrlData *gfud)
3379 { 3427 {
3380 gchar *s; 3428 gchar *s;
3381 3429 gchar *new_url, *temp_url, *end;
3382 if ((s = g_strstr_len(data, data_len, "Location: ")) != NULL) 3430 gboolean full;
3383 { 3431 int len;
3384 gchar *new_url, *temp_url, *end; 3432
3385 gboolean full; 3433 if ((s = g_strstr_len(data, data_len, "Location: ")) == NULL)
3386 int len; 3434 /* We're not being redirected */
3387 3435 return FALSE;
3388 s += strlen("Location: "); 3436
3389 end = strchr(s, '\r'); 3437 s += strlen("Location: ");
3390 3438 end = strchr(s, '\r');
3391 /* Just in case :) */ 3439
3392 if (end == NULL) 3440 /* Just in case :) */
3393 end = strchr(s, '\n'); 3441 if (end == NULL)
3394 3442 end = strchr(s, '\n');
3395 if (end == NULL) 3443
3396 return FALSE; 3444 if (end == NULL)
3397 3445 return FALSE;
3398 len = end - s; 3446
3399 3447 len = end - s;
3400 new_url = g_malloc(len + 1); 3448
3401 strncpy(new_url, s, len); 3449 new_url = g_malloc(len + 1);
3402 new_url[len] = '\0'; 3450 strncpy(new_url, s, len);
3403 3451 new_url[len] = '\0';
3404 full = gfud->full; 3452
3405 3453 full = gfud->full;
3406 if (*new_url == '/' || g_strstr_len(new_url, len, "://") == NULL) 3454
3407 { 3455 if (*new_url == '/' || g_strstr_len(new_url, len, "://") == NULL)
3408 temp_url = new_url; 3456 {
3409 3457 temp_url = new_url;
3410 new_url = g_strdup_printf("%s:%d%s", gfud->website.address, 3458
3411 gfud->website.port, temp_url); 3459 new_url = g_strdup_printf("%s:%d%s", gfud->website.address,
3412 3460 gfud->website.port, temp_url);
3413 g_free(temp_url); 3461
3414 3462 g_free(temp_url);
3415 full = FALSE; 3463
3416 } 3464 full = FALSE;
3417 3465 }
3418 purple_debug_info("util", "Redirecting to %s\n", new_url); 3466
3419 3467 purple_debug_info("util", "Redirecting to %s\n", new_url);
3420 /* 3468
3421 * Try again, with this new location. This code is somewhat 3469 gfud->num_times_redirected++;
3422 * ugly, but we need to reuse the gfud because whoever called 3470 if (gfud->num_times_redirected >= 5)
3423 * us is holding a reference to it. 3471 {
3424 */ 3472 purple_util_fetch_url_error(gfud,
3425 g_free(gfud->url); 3473 _("Could not open %s: Redirected too many times"),
3426 gfud->url = new_url; 3474 gfud->url);
3427 gfud->full = full;
3428 g_free(gfud->request);
3429 gfud->request = NULL;
3430
3431 purple_input_remove(gfud->inpa);
3432 gfud->inpa = 0;
3433 close(gfud->fd);
3434 gfud->fd = -1;
3435 gfud->request_written = 0;
3436 gfud->len = 0;
3437 gfud->data_len = 0;
3438
3439 g_free(gfud->website.user);
3440 g_free(gfud->website.passwd);
3441 g_free(gfud->website.address);
3442 g_free(gfud->website.page);
3443 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port,
3444 &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
3445
3446 gfud->connect_data = purple_proxy_connect(NULL, NULL,
3447 gfud->website.address, gfud->website.port,
3448 url_fetch_connect_cb, gfud);
3449
3450 if (gfud->connect_data == NULL)
3451 {
3452 purple_util_fetch_url_error(gfud, _("Unable to connect to %s"),
3453 gfud->website.address);
3454 }
3455
3456 return TRUE; 3475 return TRUE;
3457 } 3476 }
3458 3477
3459 return FALSE; 3478 /*
3479 * Try again, with this new location. This code is somewhat
3480 * ugly, but we need to reuse the gfud because whoever called
3481 * us is holding a reference to it.
3482 */
3483 g_free(gfud->url);
3484 gfud->url = new_url;
3485 gfud->full = full;
3486 g_free(gfud->request);
3487 gfud->request = NULL;
3488
3489 purple_input_remove(gfud->inpa);
3490 gfud->inpa = 0;
3491 close(gfud->fd);
3492 gfud->fd = -1;
3493 gfud->request_written = 0;
3494 gfud->len = 0;
3495 gfud->data_len = 0;
3496
3497 g_free(gfud->website.user);
3498 g_free(gfud->website.passwd);
3499 g_free(gfud->website.address);
3500 g_free(gfud->website.page);
3501 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port,
3502 &gfud->website.page, &gfud->website.user, &gfud->website.passwd);
3503
3504 gfud->connect_data = purple_proxy_connect(NULL, NULL,
3505 gfud->website.address, gfud->website.port,
3506 url_fetch_connect_cb, gfud);
3507
3508 if (gfud->connect_data == NULL)
3509 {
3510 purple_util_fetch_url_error(gfud, _("Unable to connect to %s"),
3511 gfud->website.address);
3512 }
3513
3514 return TRUE;
3460 } 3515 }
3461 3516
3462 static size_t 3517 static size_t
3463 parse_content_len(const char *data, size_t data_len) 3518 parse_content_len(const char *data, size_t data_len)
3464 { 3519 {