Mercurial > pidgin
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, "<"); \ | 1296 if(xhtml) \ |
1295 plain = g_string_append_c(plain, '<'); \ | 1297 xhtml = g_string_append(xhtml, "<"); \ |
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, "<"); | 1376 if(xhtml) |
1362 plain = g_string_append_c(plain, '<'); | 1377 xhtml = g_string_append(xhtml, "<"); |
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, "<"); | 1653 if(xhtml) |
1625 plain = g_string_append_c(plain, '<'); | 1654 xhtml = g_string_append(xhtml, "<"); |
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 { |