Mercurial > pidgin
comparison libpurple/util.c @ 30578:0accc8adb18a
merge of '2f6318bd834113559a405ec68cdb178f2180b680'
and '64e02b98551e11e093e4649f1516f3aceaa321e2'
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Sun, 26 Sep 2010 20:16:15 +0000 |
parents | 839f3d63acab |
children | 1b67c62c1051 |
comparison
equal
deleted
inserted
replaced
30577:7b761c8601f7 | 30578:0accc8adb18a |
---|---|
26 #include "cipher.h" | 26 #include "cipher.h" |
27 #include "conversation.h" | 27 #include "conversation.h" |
28 #include "core.h" | 28 #include "core.h" |
29 #include "debug.h" | 29 #include "debug.h" |
30 #include "notify.h" | 30 #include "notify.h" |
31 #include "ntlm.h" | |
31 #include "prpl.h" | 32 #include "prpl.h" |
32 #include "prefs.h" | 33 #include "prefs.h" |
33 #include "util.h" | 34 #include "util.h" |
34 | 35 |
35 struct _PurpleUtilFetchUrlData | 36 struct _PurpleUtilFetchUrlData |
67 char *webdata; | 68 char *webdata; |
68 gsize len; | 69 gsize len; |
69 unsigned long data_len; | 70 unsigned long data_len; |
70 gssize max_len; | 71 gssize max_len; |
71 gboolean chunked; | 72 gboolean chunked; |
73 PurpleAccount *account; | |
72 }; | 74 }; |
73 | 75 |
74 static char *custom_user_dir = NULL; | 76 static char *custom_user_dir = NULL; |
75 static char *user_dir = NULL; | 77 static char *user_dir = NULL; |
76 | 78 |
2051 return TRUE; | 2053 return TRUE; |
2052 } | 2054 } |
2053 return FALSE; | 2055 return FALSE; |
2054 } | 2056 } |
2055 | 2057 |
2058 static const char * | |
2059 process_link(GString *ret, | |
2060 const char *start, const char *c, | |
2061 int matchlen, | |
2062 const char *urlprefix, | |
2063 int inside_paren) | |
2064 { | |
2065 char *url_buf, *tmpurlbuf; | |
2066 const char *t; | |
2067 | |
2068 for (t = c;; t++) { | |
2069 if (!badchar(*t) && !badentity(t)) | |
2070 continue; | |
2071 | |
2072 if (t - c == matchlen) | |
2073 break; | |
2074 | |
2075 if (*t == ',' && *(t + 1) != ' ') { | |
2076 continue; | |
2077 } | |
2078 | |
2079 if (t > start && *(t - 1) == '.') | |
2080 t--; | |
2081 if (t > start && *(t - 1) == ')' && inside_paren > 0) | |
2082 t--; | |
2083 | |
2084 url_buf = g_strndup(c, t - c); | |
2085 tmpurlbuf = purple_unescape_html(url_buf); | |
2086 g_string_append_printf(ret, "<A HREF=\"%s%s\">%s</A>", | |
2087 urlprefix, | |
2088 tmpurlbuf, url_buf); | |
2089 g_free(tmpurlbuf); | |
2090 g_free(url_buf); | |
2091 return t; | |
2092 } | |
2093 | |
2094 return c; | |
2095 } | |
2096 | |
2056 char * | 2097 char * |
2057 purple_markup_linkify(const char *text) | 2098 purple_markup_linkify(const char *text) |
2058 { | 2099 { |
2059 const char *c, *t, *q = NULL; | 2100 const char *c, *t, *q = NULL; |
2060 char *tmpurlbuf, *url_buf; | 2101 char *tmpurlbuf, *url_buf; |
2098 c++; | 2139 c++; |
2099 if (!(*c)) | 2140 if (!(*c)) |
2100 break; | 2141 break; |
2101 } | 2142 } |
2102 } | 2143 } |
2103 } else if ((*c=='h') && (!g_ascii_strncasecmp(c, "http://", 7) || | 2144 } else if (!g_ascii_strncasecmp(c, "http://", 7)) { |
2104 (!g_ascii_strncasecmp(c, "https://", 8)))) { | 2145 c = process_link(ret, text, c, 7, "", inside_paren); |
2105 t = c; | 2146 } else if (!g_ascii_strncasecmp(c, "https://", 8)) { |
2106 while (1) { | 2147 c = process_link(ret, text, c, 8, "", inside_paren); |
2107 if (badchar(*t) || badentity(t)) { | 2148 } else if (!g_ascii_strncasecmp(c, "ftp://", 6)) { |
2108 | 2149 c = process_link(ret, text, c, 6, "", inside_paren); |
2109 if ((!g_ascii_strncasecmp(c, "http://", 7) && (t - c == 7)) || | 2150 } else if (!g_ascii_strncasecmp(c, "sftp://", 7)) { |
2110 (!g_ascii_strncasecmp(c, "https://", 8) && (t - c == 8))) { | 2151 c = process_link(ret, text, c, 7, "", inside_paren); |
2111 break; | 2152 } else if (!g_ascii_strncasecmp(c, "file://", 7)) { |
2112 } | 2153 c = process_link(ret, text, c, 7, "", inside_paren); |
2113 | 2154 } else if (!g_ascii_strncasecmp(c, "www.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) { |
2114 if (*(t) == ',' && (*(t + 1) != ' ')) { | 2155 c = process_link(ret, text, c, 4, "http://", inside_paren); |
2115 t++; | 2156 } else if (!g_ascii_strncasecmp(c, "ftp.", 4) && c[4] != '.' && (c == text || badchar(c[-1]) || badentity(c-1))) { |
2116 continue; | 2157 c = process_link(ret, text, c, 4, "ftp://", inside_paren); |
2117 } | 2158 } else if (!g_ascii_strncasecmp(c, "xmpp:", 5) && (c == text || badchar(c[-1]) || badentity(c-1))) { |
2118 | 2159 c = process_link(ret, text, c, 5, "", inside_paren); |
2119 if (*(t - 1) == '.') | |
2120 t--; | |
2121 if ((*(t - 1) == ')' && (inside_paren > 0))) { | |
2122 t--; | |
2123 } | |
2124 | |
2125 url_buf = g_strndup(c, t - c); | |
2126 tmpurlbuf = purple_unescape_html(url_buf); | |
2127 g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>", | |
2128 tmpurlbuf, url_buf); | |
2129 g_free(url_buf); | |
2130 g_free(tmpurlbuf); | |
2131 c = t; | |
2132 break; | |
2133 } | |
2134 t++; | |
2135 | |
2136 } | |
2137 } else if (!g_ascii_strncasecmp(c, "www.", 4) && (c == text || badchar(c[-1]) || badentity(c-1))) { | |
2138 if (c[4] != '.') { | |
2139 t = c; | |
2140 while (1) { | |
2141 if (badchar(*t) || badentity(t)) { | |
2142 if (t - c == 4) { | |
2143 break; | |
2144 } | |
2145 | |
2146 if (*(t) == ',' && (*(t + 1) != ' ')) { | |
2147 t++; | |
2148 continue; | |
2149 } | |
2150 | |
2151 if (*(t - 1) == '.') | |
2152 t--; | |
2153 if ((*(t - 1) == ')' && (inside_paren > 0))) { | |
2154 t--; | |
2155 } | |
2156 url_buf = g_strndup(c, t - c); | |
2157 tmpurlbuf = purple_unescape_html(url_buf); | |
2158 g_string_append_printf(ret, | |
2159 "<A HREF=\"http://%s\">%s</A>", tmpurlbuf, | |
2160 url_buf); | |
2161 g_free(url_buf); | |
2162 g_free(tmpurlbuf); | |
2163 c = t; | |
2164 break; | |
2165 } | |
2166 t++; | |
2167 } | |
2168 } | |
2169 } else if (!g_ascii_strncasecmp(c, "ftp://", 6) || !g_ascii_strncasecmp(c, "sftp://", 7)) { | |
2170 t = c; | |
2171 while (1) { | |
2172 if (badchar(*t) || badentity(t)) { | |
2173 | |
2174 if ((!g_ascii_strncasecmp(c, "ftp://", 6) && (t - c == 6)) || | |
2175 (!g_ascii_strncasecmp(c, "sftp://", 7) && (t - c == 7))) { | |
2176 break; | |
2177 } | |
2178 | |
2179 if (*(t - 1) == '.') | |
2180 t--; | |
2181 if ((*(t - 1) == ')' && (inside_paren > 0))) { | |
2182 t--; | |
2183 } | |
2184 url_buf = g_strndup(c, t - c); | |
2185 tmpurlbuf = purple_unescape_html(url_buf); | |
2186 g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>", | |
2187 tmpurlbuf, url_buf); | |
2188 g_free(url_buf); | |
2189 g_free(tmpurlbuf); | |
2190 c = t; | |
2191 break; | |
2192 } | |
2193 if (!t) | |
2194 break; | |
2195 t++; | |
2196 | |
2197 } | |
2198 } else if (!g_ascii_strncasecmp(c, "ftp.", 4) && (c == text || badchar(c[-1]) || badentity(c-1))) { | |
2199 if (c[4] != '.') { | |
2200 t = c; | |
2201 while (1) { | |
2202 if (badchar(*t) || badentity(t)) { | |
2203 if (t - c == 4) { | |
2204 break; | |
2205 } | |
2206 if (*(t - 1) == '.') | |
2207 t--; | |
2208 if ((*(t - 1) == ')' && (inside_paren > 0))) { | |
2209 t--; | |
2210 } | |
2211 url_buf = g_strndup(c, t - c); | |
2212 tmpurlbuf = purple_unescape_html(url_buf); | |
2213 g_string_append_printf(ret, | |
2214 "<A HREF=\"ftp://%s\">%s</A>", tmpurlbuf, | |
2215 url_buf); | |
2216 g_free(url_buf); | |
2217 g_free(tmpurlbuf); | |
2218 c = t; | |
2219 break; | |
2220 } | |
2221 if (!t) | |
2222 break; | |
2223 t++; | |
2224 } | |
2225 } | |
2226 } else if (!g_ascii_strncasecmp(c, "mailto:", 7)) { | 2160 } else if (!g_ascii_strncasecmp(c, "mailto:", 7)) { |
2227 t = c; | 2161 t = c; |
2228 while (1) { | 2162 while (1) { |
2229 if (badchar(*t) || badentity(t)) { | 2163 if (badchar(*t) || badentity(t)) { |
2230 char *d; | 2164 char *d; |
2231 if (t - c == 7) { | 2165 if (t - c == 7) { |
2232 break; | 2166 break; |
2233 } | 2167 } |
2234 if (*(t - 1) == '.') | 2168 if (t > text && *(t - 1) == '.') |
2235 t--; | 2169 t--; |
2236 if ((d = strstr(c + 7, "?")) != NULL && d < t) | 2170 if ((d = strstr(c + 7, "?")) != NULL && d < t) |
2237 url_buf = g_strndup(c + 7, d - c - 7); | 2171 url_buf = g_strndup(c + 7, d - c - 7); |
2238 else | 2172 else |
2239 url_buf = g_strndup(c + 7, t - c - 7); | 2173 url_buf = g_strndup(c + 7, t - c - 7); |
2249 g_free(url_buf); | 2183 g_free(url_buf); |
2250 g_free(tmpurlbuf); | 2184 g_free(tmpurlbuf); |
2251 c = t; | 2185 c = t; |
2252 break; | 2186 break; |
2253 } | 2187 } |
2254 if (!t) | |
2255 break; | |
2256 t++; | 2188 t++; |
2257 | |
2258 } | |
2259 } else if ((*c=='x') && (!g_ascii_strncasecmp(c, "xmpp:", 5)) && | |
2260 (c == text || badchar(c[-1]) || badentity(c-1))) { | |
2261 t = c; | |
2262 while (1) { | |
2263 if (badchar(*t) || badentity(t)) { | |
2264 | |
2265 if (t - c == 5) { | |
2266 break; | |
2267 } | |
2268 | |
2269 if (*(t) == ',' && (*(t + 1) != ' ')) { | |
2270 t++; | |
2271 continue; | |
2272 } | |
2273 | |
2274 if (*(t - 1) == '.') | |
2275 t--; | |
2276 if ((*(t - 1) == ')' && (inside_paren > 0))) { | |
2277 t--; | |
2278 } | |
2279 | |
2280 url_buf = g_strndup(c, t - c); | |
2281 tmpurlbuf = purple_unescape_html(url_buf); | |
2282 g_string_append_printf(ret, "<A HREF=\"%s\">%s</A>", | |
2283 tmpurlbuf, url_buf); | |
2284 g_free(url_buf); | |
2285 g_free(tmpurlbuf); | |
2286 c = t; | |
2287 break; | |
2288 } | |
2289 t++; | |
2290 | |
2291 } | 2189 } |
2292 } else if (c != text && (*c == '@')) { | 2190 } else if (c != text && (*c == '@')) { |
2293 int flag; | 2191 int flag; |
2294 GString *gurl_buf = NULL; | 2192 GString *gurl_buf = NULL; |
2295 const char illegal_chars[] = "!@#$%^&*()[]{}/|\\<>\":;\r\n \0"; | 2193 const char illegal_chars[] = "!@#$%^&*()[]{}/|\\<>\":;\r\n \0"; |
2912 } | 2810 } |
2913 | 2811 |
2914 progname = g_find_program_in_path(argv[0]); | 2812 progname = g_find_program_in_path(argv[0]); |
2915 is_valid = (progname != NULL); | 2813 is_valid = (progname != NULL); |
2916 | 2814 |
2815 if(purple_debug_is_verbose()) | |
2816 purple_debug_info("program_is_valid", "Tested program %s. %s.\n", program, | |
2817 is_valid ? "Valid" : "Invalid"); | |
2818 | |
2917 g_strfreev(argv); | 2819 g_strfreev(argv); |
2918 g_free(progname); | 2820 g_free(progname); |
2919 | 2821 |
2920 return is_valid; | 2822 return is_valid; |
2921 } | 2823 } |
3215 | 3117 |
3216 for (i = 0, j = 0; text[i]; i++) | 3118 for (i = 0, j = 0; text[i]; i++) |
3217 if (text[i] != thechar) | 3119 if (text[i] != thechar) |
3218 text[j++] = text[i]; | 3120 text[j++] = text[i]; |
3219 | 3121 |
3220 text[j++] = '\0'; | 3122 text[j] = '\0'; |
3221 } | 3123 } |
3222 | 3124 |
3223 void | 3125 void |
3224 purple_util_chrreplace(char *string, char delimiter, | 3126 purple_util_chrreplace(char *string, char delimiter, |
3225 char replacement) | 3127 char replacement) |
3523 gboolean | 3425 gboolean |
3524 purple_url_parse(const char *url, char **ret_host, int *ret_port, | 3426 purple_url_parse(const char *url, char **ret_host, int *ret_port, |
3525 char **ret_path, char **ret_user, char **ret_passwd) | 3427 char **ret_path, char **ret_user, char **ret_passwd) |
3526 { | 3428 { |
3527 gboolean is_https = FALSE; | 3429 gboolean is_https = FALSE; |
3528 char scan_info[255]; | 3430 const char * scan_info; |
3529 char port_str[6]; | 3431 char port_str[6]; |
3530 int f; | 3432 int f; |
3531 const char *at, *slash; | 3433 const char *at, *slash; |
3532 const char *turl; | 3434 const char *turl; |
3533 char host[256], path[256], user[256], passwd[256]; | 3435 char host[256], path[256], user[256], passwd[256]; |
3534 int port = 0; | 3436 int port = 0; |
3535 /* hyphen at end includes it in control set */ | 3437 /* hyphen at end includes it in control set */ |
3536 static const char addr_ctrl[] = "A-Za-z0-9.-"; | 3438 |
3537 static const char port_ctrl[] = "0-9"; | 3439 #define ADDR_CTRL "A-Za-z0-9.-" |
3538 static const char page_ctrl[] = "A-Za-z0-9.~_/:*!@&%%?=+^-"; | 3440 #define PORT_CTRL "0-9" |
3539 static const char user_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; | 3441 #define PAGE_CTRL "A-Za-z0-9.~_/:*!@&%%?=+^-" |
3540 static const char passwd_ctrl[] = "A-Za-z0-9.~_/*!&%%?=+^-"; | 3442 #define USER_CTRL "A-Za-z0-9.~_/*!&%%?=+^-" |
3443 #define PASSWD_CTRL "A-Za-z0-9.~_/*!&%%?=+^-" | |
3541 | 3444 |
3542 g_return_val_if_fail(url != NULL, FALSE); | 3445 g_return_val_if_fail(url != NULL, FALSE); |
3543 | 3446 |
3544 if ((turl = purple_strcasestr(url, "http://")) != NULL) | 3447 if ((turl = purple_strcasestr(url, "http://")) != NULL) |
3545 { | 3448 { |
3555 | 3458 |
3556 /* parse out authentication information if supplied */ | 3459 /* parse out authentication information if supplied */ |
3557 /* Only care about @ char BEFORE the first / */ | 3460 /* Only care about @ char BEFORE the first / */ |
3558 at = strchr(url, '@'); | 3461 at = strchr(url, '@'); |
3559 slash = strchr(url, '/'); | 3462 slash = strchr(url, '/'); |
3560 if ((at != NULL) && | 3463 f = 0; |
3561 (((slash != NULL) && (strlen(at) > strlen(slash))) || | 3464 if (at && (!slash || at < slash)) { |
3562 (slash == NULL))) { | 3465 scan_info = "%255[" USER_CTRL "]:%255[" PASSWD_CTRL "]^@"; |
3563 g_snprintf(scan_info, sizeof(scan_info), | |
3564 "%%255[%s]:%%255[%s]^@", user_ctrl, passwd_ctrl); | |
3565 f = sscanf(url, scan_info, user, passwd); | 3466 f = sscanf(url, scan_info, user, passwd); |
3566 | 3467 |
3567 if (f ==1 ) { | 3468 if (f == 1) { |
3568 /* No passwd, possibly just username supplied */ | 3469 /* No passwd, possibly just username supplied */ |
3569 g_snprintf(scan_info, sizeof(scan_info), | 3470 scan_info = "%255[" USER_CTRL "]^@"; |
3570 "%%255[%s]^@", user_ctrl); | |
3571 f = sscanf(url, scan_info, user); | 3471 f = sscanf(url, scan_info, user); |
3572 *passwd = '\0'; | |
3573 } | 3472 } |
3574 | 3473 |
3575 url = at+1; /* move pointer after the @ char */ | 3474 url = at+1; /* move pointer after the @ char */ |
3576 } else { | 3475 } |
3476 | |
3477 if (f < 1) { | |
3577 *user = '\0'; | 3478 *user = '\0'; |
3578 *passwd = '\0'; | 3479 *passwd = '\0'; |
3579 } | 3480 } else if (f == 1) |
3580 | 3481 *passwd = '\0'; |
3581 g_snprintf(scan_info, sizeof(scan_info), | 3482 |
3582 "%%255[%s]:%%5[%s]/%%255[%s]", addr_ctrl, port_ctrl, page_ctrl); | 3483 scan_info = "%255[" ADDR_CTRL "]:%5[" PORT_CTRL "]/%255[" PAGE_CTRL "]"; |
3583 | |
3584 f = sscanf(url, scan_info, host, port_str, path); | 3484 f = sscanf(url, scan_info, host, port_str, path); |
3585 | 3485 |
3586 if (f == 1) | 3486 if (f == 1) |
3587 { | 3487 { |
3588 g_snprintf(scan_info, sizeof(scan_info), | 3488 scan_info = "%255[" ADDR_CTRL "]/%255[" PAGE_CTRL "]"; |
3589 "%%255[%s]/%%255[%s]", | |
3590 addr_ctrl, page_ctrl); | |
3591 f = sscanf(url, scan_info, host, path); | 3489 f = sscanf(url, scan_info, host, path); |
3592 /* Use the default port */ | 3490 /* Use the default port */ |
3593 if (is_https) | 3491 if (is_https) |
3594 g_snprintf(port_str, sizeof(port_str), "443"); | 3492 g_snprintf(port_str, sizeof(port_str), "443"); |
3595 else | 3493 else |
3609 if (ret_path != NULL) *ret_path = g_strdup(path); | 3507 if (ret_path != NULL) *ret_path = g_strdup(path); |
3610 if (ret_user != NULL) *ret_user = g_strdup(user); | 3508 if (ret_user != NULL) *ret_user = g_strdup(user); |
3611 if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd); | 3509 if (ret_passwd != NULL) *ret_passwd = g_strdup(passwd); |
3612 | 3510 |
3613 return ((*host != '\0') ? TRUE : FALSE); | 3511 return ((*host != '\0') ? TRUE : FALSE); |
3512 | |
3513 #undef ADDR_CTRL | |
3514 #undef PORT_CTRL | |
3515 #undef PAGE_CTRL | |
3516 #undef USER_CTRL | |
3517 #undef PASSWD_CTRL | |
3614 } | 3518 } |
3615 | 3519 |
3616 /** | 3520 /** |
3617 * The arguments to this function are similar to printf. | 3521 * The arguments to this function are similar to printf. |
3618 */ | 3522 */ |
3721 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port, | 3625 purple_url_parse(new_url, &gfud->website.address, &gfud->website.port, |
3722 &gfud->website.page, &gfud->website.user, &gfud->website.passwd); | 3626 &gfud->website.page, &gfud->website.user, &gfud->website.passwd); |
3723 | 3627 |
3724 if (purple_strcasestr(new_url, "https://") != NULL) { | 3628 if (purple_strcasestr(new_url, "https://") != NULL) { |
3725 gfud->is_ssl = TRUE; | 3629 gfud->is_ssl = TRUE; |
3726 gfud->ssl_connection = purple_ssl_connect(NULL, | 3630 gfud->ssl_connection = purple_ssl_connect(gfud->account, |
3727 gfud->website.address, gfud->website.port, | 3631 gfud->website.address, gfud->website.port, |
3728 ssl_url_fetch_connect_cb, ssl_url_fetch_error_cb, gfud); | 3632 ssl_url_fetch_connect_cb, ssl_url_fetch_error_cb, gfud); |
3729 } else { | 3633 } else { |
3730 gfud->connect_data = purple_proxy_connect(NULL, NULL, | 3634 gfud->connect_data = purple_proxy_connect(NULL, gfud->account, |
3731 gfud->website.address, gfud->website.port, | 3635 gfud->website.address, gfud->website.port, |
3732 url_fetch_connect_cb, gfud); | 3636 url_fetch_connect_cb, gfud); |
3733 } | 3637 } |
3734 | 3638 |
3735 if (gfud->ssl_connection == NULL && gfud->connect_data == NULL) | 3639 if (gfud->ssl_connection == NULL && gfud->connect_data == NULL) |
4017 PurpleUtilFetchUrlData *gfud; | 3921 PurpleUtilFetchUrlData *gfud; |
4018 int len, total_len; | 3922 int len, total_len; |
4019 | 3923 |
4020 gfud = data; | 3924 gfud = data; |
4021 | 3925 |
4022 if (gfud->request == NULL) | 3926 if (gfud->request == NULL) { |
4023 { | 3927 |
3928 PurpleProxyInfo *gpi = purple_proxy_get_setup(gfud->account); | |
3929 GString *request_str = g_string_new(NULL); | |
3930 | |
3931 g_string_append_printf(request_str, "GET %s%s HTTP/%s\r\n" | |
3932 "Connection: close\r\n", | |
3933 (gfud->full ? "" : "/"), | |
3934 (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), | |
3935 (gfud->http11 ? "1.1" : "1.0")); | |
3936 | |
3937 if (gfud->user_agent) | |
3938 g_string_append_printf(request_str, "User-Agent: %s\r\n", gfud->user_agent); | |
3939 | |
4024 /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1 | 3940 /* Host header is not forbidden in HTTP/1.0 requests, and HTTP/1.1 |
4025 * clients must know how to handle the "chunked" transfer encoding. | 3941 * clients must know how to handle the "chunked" transfer encoding. |
4026 * Purple doesn't know how to handle "chunked", so should always send | 3942 * Purple doesn't know how to handle "chunked", so should always send |
4027 * the Host header regardless, to get around some observed problems | 3943 * the Host header regardless, to get around some observed problems |
4028 */ | 3944 */ |
4029 if (gfud->user_agent) { | 3945 g_string_append_printf(request_str, "Accept: */*\r\n" |
4030 gfud->request = g_strdup_printf( | 3946 "Host: %s\r\n", |
4031 "GET %s%s HTTP/%s\r\n" | 3947 (gfud->website.address ? gfud->website.address : "")); |
4032 "Connection: close\r\n" | 3948 |
4033 "User-Agent: %s\r\n" | 3949 if (purple_proxy_info_get_username(gpi) != NULL |
4034 "Accept: */*\r\n" | 3950 && (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR |
4035 "Host: %s\r\n\r\n", | 3951 || purple_proxy_info_get_type(gpi) == PURPLE_PROXY_HTTP)) { |
4036 (gfud->full ? "" : "/"), | 3952 /* This chunk of code was copied from proxy.c http_start_connect_tunneling() |
4037 (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), | 3953 * This is really a temporary hack - we need a more complete proxy handling solution, |
4038 (gfud->http11 ? "1.1" : "1.0"), | 3954 * so I didn't think it was worthwhile to refactor for reuse |
4039 (gfud->user_agent ? gfud->user_agent : ""), | 3955 */ |
4040 (gfud->website.address ? gfud->website.address : "")); | 3956 char *t1, *t2, *ntlm_type1; |
4041 } else { | 3957 char hostname[256]; |
4042 gfud->request = g_strdup_printf( | 3958 int ret; |
4043 "GET %s%s HTTP/%s\r\n" | 3959 |
4044 "Connection: close\r\n" | 3960 ret = gethostname(hostname, sizeof(hostname)); |
4045 "Accept: */*\r\n" | 3961 hostname[sizeof(hostname) - 1] = '\0'; |
4046 "Host: %s\r\n\r\n", | 3962 if (ret < 0 || hostname[0] == '\0') { |
4047 (gfud->full ? "" : "/"), | 3963 purple_debug_warning("util", "proxy - gethostname() failed -- is your hostname set?"); |
4048 (gfud->full ? (gfud->url ? gfud->url : "") : (gfud->website.page ? gfud->website.page : "")), | 3964 strcpy(hostname, "localhost"); |
4049 (gfud->http11 ? "1.1" : "1.0"), | 3965 } |
4050 (gfud->website.address ? gfud->website.address : "")); | 3966 |
4051 } | 3967 t1 = g_strdup_printf("%s:%s", |
3968 purple_proxy_info_get_username(gpi), | |
3969 purple_proxy_info_get_password(gpi) ? | |
3970 purple_proxy_info_get_password(gpi) : ""); | |
3971 t2 = purple_base64_encode((const guchar *)t1, strlen(t1)); | |
3972 g_free(t1); | |
3973 | |
3974 ntlm_type1 = purple_ntlm_gen_type1(hostname, ""); | |
3975 | |
3976 g_string_append_printf(request_str, | |
3977 "Proxy-Authorization: Basic %s\r\n" | |
3978 "Proxy-Authorization: NTLM %s\r\n" | |
3979 "Proxy-Connection: Keep-Alive\r\n", | |
3980 t2, ntlm_type1); | |
3981 g_free(ntlm_type1); | |
3982 g_free(t2); | |
3983 } | |
3984 | |
3985 g_string_append(request_str, "\r\n"); | |
3986 | |
3987 gfud->request = g_string_free(request_str, FALSE); | |
4052 } | 3988 } |
4053 | 3989 |
4054 if(purple_debug_is_unsafe()) | 3990 if(purple_debug_is_unsafe()) |
4055 purple_debug_misc("util", "Request: '%s'\n", gfud->request); | 3991 purple_debug_misc("util", "Request: '%s'\n", gfud->request); |
4056 else | 3992 else |
4185 gfud->full = full; | 4121 gfud->full = full; |
4186 gfud->request = g_strdup(request); | 4122 gfud->request = g_strdup(request); |
4187 gfud->include_headers = include_headers; | 4123 gfud->include_headers = include_headers; |
4188 gfud->fd = -1; | 4124 gfud->fd = -1; |
4189 gfud->max_len = max_len; | 4125 gfud->max_len = max_len; |
4126 gfud->account = account; | |
4190 | 4127 |
4191 purple_url_parse(url, &gfud->website.address, &gfud->website.port, | 4128 purple_url_parse(url, &gfud->website.address, &gfud->website.port, |
4192 &gfud->website.page, &gfud->website.user, &gfud->website.passwd); | 4129 &gfud->website.page, &gfud->website.user, &gfud->website.passwd); |
4193 | 4130 |
4194 if (purple_strcasestr(url, "https://") != NULL) { | 4131 if (purple_strcasestr(url, "https://") != NULL) { |
4338 const char *c, *domain; | 4275 const char *c, *domain; |
4339 static char *rfc822_specials = "()<>@,;:\\\"[]"; | 4276 static char *rfc822_specials = "()<>@,;:\\\"[]"; |
4340 | 4277 |
4341 g_return_val_if_fail(address != NULL, FALSE); | 4278 g_return_val_if_fail(address != NULL, FALSE); |
4342 | 4279 |
4280 if (*address == '.') return FALSE; | |
4281 | |
4343 /* first we validate the name portion (name@domain) (rfc822)*/ | 4282 /* first we validate the name portion (name@domain) (rfc822)*/ |
4344 for (c = address; *c; c++) { | 4283 for (c = address; *c; c++) { |
4345 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) { | 4284 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) { |
4346 while (*++c) { | 4285 while (*++c) { |
4347 if (*c == '\\') { | 4286 if (*c == '\\') { |
4371 /* next we validate the domain portion (name@domain) (rfc1035 & rfc1011) */ | 4310 /* next we validate the domain portion (name@domain) (rfc1035 & rfc1011) */ |
4372 if (!*(domain = ++c)) return FALSE; | 4311 if (!*(domain = ++c)) return FALSE; |
4373 do { | 4312 do { |
4374 if (*c == '.' && (c == domain || *(c - 1) == '.' || *(c - 1) == '-')) | 4313 if (*c == '.' && (c == domain || *(c - 1) == '.' || *(c - 1) == '-')) |
4375 return FALSE; | 4314 return FALSE; |
4376 if (*c == '-' && *(c - 1) == '.') return FALSE; | 4315 if (*c == '-' && (*(c - 1) == '.' || *(c - 1) == '@')) return FALSE; |
4377 if ((*c < '0' && *c != '-' && *c != '.') || (*c > '9' && *c < 'A') || | 4316 if ((*c < '0' && *c != '-' && *c != '.') || (*c > '9' && *c < 'A') || |
4378 (*c > 'Z' && *c < 'a') || (*c > 'z')) return FALSE; | 4317 (*c > 'Z' && *c < 'a') || (*c > 'z')) return FALSE; |
4379 } while (*++c); | 4318 } while (*++c); |
4380 | 4319 |
4381 if (*(c - 1) == '-') return FALSE; | 4320 if (*(c - 1) == '-') return FALSE; |
4958 sprintf(buf + j, "%%%02x", utf_char[i] & 0xff); | 4897 sprintf(buf + j, "%%%02x", utf_char[i] & 0xff); |
4959 j += 3; | 4898 j += 3; |
4960 } | 4899 } |
4961 } | 4900 } |
4962 } | 4901 } |
4963 | 4902 #ifdef _WIN32 |
4903 /* File/Directory names in windows cannot end in periods/spaces. | |
4904 * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx | |
4905 */ | |
4906 while (j > 0 && (buf[j - 1] == '.' || buf[j - 1] == ' ')) | |
4907 j--; | |
4908 #endif | |
4964 buf[j] = '\0'; | 4909 buf[j] = '\0'; |
4965 | 4910 |
4966 return buf; | 4911 return buf; |
4967 } | 4912 } |
4968 | 4913 |