Mercurial > pidgin
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, "<"); \ | 1295 if(xhtml) \ |
1294 plain = g_string_append_c(plain, '<'); \ | 1296 xhtml = g_string_append(xhtml, "<"); \ |
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, "<"); | 1375 if(xhtml) |
1361 plain = g_string_append_c(plain, '<'); | 1376 xhtml = g_string_append(xhtml, "<"); |
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, "<"); | 1618 if(xhtml) |
1590 plain = g_string_append_c(plain, '<'); | 1619 xhtml = g_string_append(xhtml, "<"); |
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 { |