void om_post_or_get(OmegleAccount *oma, OmegleMethod method, const gchar *host, const gchar *url, const gchar *postdata, OmegleProxyCallbackFunc callback_func, gpointer user_data, gboolean keepalive) { GString *request; gchar *cookies; OmegleConnection *omconn; gchar *real_url; gboolean is_proxy = FALSE; const gchar *user_agent; const gchar* const *languages; gchar *language_names; PurpleProxyInfo *proxy_info = NULL; gchar *proxy_auth; gchar *proxy_auth_base64; /* TODO: Fix keepalive and use it as much as possible */ keepalive = FALSE; if (host == NULL) host = purple_account_get_string(oma->account, "host", "bajor.omegle.com"); if (oma && oma->account && !(method & OM_METHOD_SSL)) { proxy_info = purple_proxy_get_setup(oma->account); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) proxy_info = purple_global_proxy_get_info(); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP) { is_proxy = TRUE; } } if (is_proxy == TRUE) { real_url = g_strdup_printf("http://%s%s", host, url); } else { real_url = g_strdup(url); } cookies = om_cookies_to_string(oma); user_agent = purple_account_get_string(oma->account, "user-agent", "Opera/9.50 (Windows NT 5.1; U; en-GB)"); if (method & OM_METHOD_POST && !postdata) postdata = ""; /* Build the request */ request = g_string_new(NULL); g_string_append_printf(request, "%s %s HTTP/1.0\r\n", (method & OM_METHOD_POST) ? "POST" : "GET", real_url); if (is_proxy == FALSE) g_string_append_printf(request, "Host: %s\r\n", host); g_string_append_printf(request, "Connection: %s\r\n", (keepalive ? "Keep-Alive" : "close")); g_string_append_printf(request, "User-Agent: %s\r\n", user_agent); if (method & OM_METHOD_POST) { g_string_append_printf(request, "Content-Type: application/x-www-form-urlencoded\r\n"); g_string_append_printf(request, "Content-length: %zu\r\n", strlen(postdata)); } g_string_append_printf(request, "Accept: application/json, text/html, */*\r\n"); g_string_append_printf(request, "Cookie: %s\r\n", cookies); g_string_append_printf(request, "Accept-Encoding: gzip\r\n"); if (is_proxy == TRUE) { if (purple_proxy_info_get_username(proxy_info) && purple_proxy_info_get_password(proxy_info)) { proxy_auth = g_strdup_printf("%s:%s", purple_proxy_info_get_username(proxy_info), purple_proxy_info_get_password(proxy_info)); proxy_auth_base64 = purple_base64_encode((guchar *)proxy_auth, strlen(proxy_auth)); g_string_append_printf(request, "Proxy-Authorization: Basic %s\r\n", proxy_auth_base64); g_free(proxy_auth_base64); g_free(proxy_auth); } } /* Tell the server what language we accept, so that we get error messages in our language (rather than our IP's) */ languages = g_get_language_names(); language_names = g_strjoinv(", ", (gchar **)languages); purple_util_chrreplace(language_names, '_', '-'); g_string_append_printf(request, "Accept-Language: %s\r\n", language_names); g_free(language_names); purple_debug_info("omegle", "getting url %s\n", url); g_string_append_printf(request, "\r\n"); if (method & OM_METHOD_POST) g_string_append_printf(request, "%s", postdata); /* If it needs to go over a SSL connection, we probably shouldn't print * it in the debug log. Without this condition a user's password is * printed in the debug log */ if (method == OM_METHOD_POST) purple_debug_info("omegle", "sending request data:\n%s\n", postdata); g_free(cookies); /* * Do a separate DNS lookup for the given host name and cache it * for next time. * * TODO: It would be better if we did this before we call * purple_proxy_connect(), so we could re-use the result. * Or even better: Use persistent HTTP connections for servers * that we access continually. * * TODO: This cache of the hostname<-->IP address does not respect * the TTL returned by the DNS server. We should expire things * from the cache after some amount of time. */ if (!is_proxy) { /* Don't do this for proxy connections, since proxies do the DNS lookup */ gchar *host_ip; host_ip = g_hash_table_lookup(oma->hostname_ip_cache, host); if (host_ip != NULL) { host = host_ip; } else if (oma->account && !oma->account->disconnecting) { GSList *host_lookup_list = NULL; PurpleDnsQueryData *query; host_lookup_list = g_slist_prepend( host_lookup_list, g_strdup(host)); host_lookup_list = g_slist_prepend( host_lookup_list, oma); query = purple_dnsquery_a(host, 80, om_host_lookup_cb, host_lookup_list); oma->dns_queries = g_slist_prepend(oma->dns_queries, query); host_lookup_list = g_slist_append(host_lookup_list, query); } } omconn = g_new0(OmegleConnection, 1); omconn->oma = oma; omconn->url = real_url; omconn->method = method; omconn->hostname = g_strdup(host); omconn->request = request; omconn->callback = callback_func; omconn->user_data = user_data; omconn->fd = -1; omconn->connection_keepalive = keepalive; omconn->request_time = time(NULL); oma->conns = g_slist_prepend(oma->conns, omconn); om_attempt_connection(omconn); }
void purple_initmodule() { struct prpl funcs; GList *prots; GString *help; char *dir; if( B_EV_IO_READ != PURPLE_INPUT_READ || B_EV_IO_WRITE != PURPLE_INPUT_WRITE ) { /* FIXME FIXME FIXME FIXME FIXME :-) */ exit( 1 ); } dir = g_strdup_printf( "%s/purple", global.conf->configdir ); purple_util_set_user_dir( dir ); g_free( dir ); purple_debug_set_enabled( FALSE ); purple_core_set_ui_ops( &bee_core_uiops ); purple_eventloop_set_ui_ops( &glib_eventloops ); if( !purple_core_init( "BitlBee") ) { /* Initializing the core failed. Terminate. */ fprintf( stderr, "libpurple initialization failed.\n" ); abort(); } if( proxytype != PROXY_NONE ) { PurpleProxyInfo *pi = purple_global_proxy_get_info(); switch( proxytype ) { case PROXY_SOCKS4: purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS4 ); break; case PROXY_SOCKS5: purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS5 ); break; case PROXY_HTTP: purple_proxy_info_set_type( pi, PURPLE_PROXY_HTTP ); break; } purple_proxy_info_set_host( pi, proxyhost ); purple_proxy_info_set_port( pi, proxyport ); purple_proxy_info_set_username( pi, proxyuser ); purple_proxy_info_set_password( pi, proxypass ); } purple_set_blist( purple_blist_new() ); /* No, really. So far there were ui_ops for everything, but now suddenly one needs to use signals for typing notification stuff. :-( */ purple_signal_connect( purple_conversations_get_handle(), "buddy-typing", &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL ); purple_signal_connect( purple_conversations_get_handle(), "buddy-typed", &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL ); purple_signal_connect( purple_conversations_get_handle(), "buddy-typing-stopped", &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL ); memset( &funcs, 0, sizeof( funcs ) ); funcs.login = purple_login; funcs.init = purple_init; funcs.logout = purple_logout; funcs.buddy_msg = purple_buddy_msg; funcs.away_states = purple_away_states; funcs.set_away = purple_set_away; funcs.add_buddy = purple_add_buddy; funcs.remove_buddy = purple_remove_buddy; funcs.add_permit = purple_add_permit; funcs.add_deny = purple_add_deny; funcs.rem_permit = purple_rem_permit; funcs.rem_deny = purple_rem_deny; funcs.get_info = purple_get_info; funcs.keepalive = purple_keepalive; funcs.send_typing = purple_send_typing; funcs.handle_cmp = g_strcasecmp; /* TODO(wilmer): Set these only for protocols that support them? */ funcs.chat_msg = purple_chat_msg; funcs.chat_with = purple_chat_with; funcs.chat_invite = purple_chat_invite; funcs.chat_leave = purple_chat_leave; funcs.chat_join = purple_chat_join; funcs.transfer_request = purple_transfer_request; help = g_string_new( "BitlBee libpurple module supports the following IM protocols:\n" ); /* Add a protocol entry to BitlBee's structures for every protocol supported by this libpurple instance. */ for( prots = purple_plugins_get_protocols(); prots; prots = prots->next ) { PurplePlugin *prot = prots->data; struct prpl *ret; /* If we already have this one (as a native module), don't add a libpurple duplicate. */ if( find_protocol( prot->info->id ) ) continue; ret = g_memdup( &funcs, sizeof( funcs ) ); ret->name = ret->data = prot->info->id; if( strncmp( ret->name, "prpl-", 5 ) == 0 ) ret->name += 5; register_protocol( ret ); g_string_append_printf( help, "\n* %s (%s)", ret->name, prot->info->name ); /* libpurple doesn't define a protocol called OSCAR, but we need it to be compatible with normal BitlBee. */ if( g_strcasecmp( prot->info->id, "prpl-aim" ) == 0 ) { ret = g_memdup( &funcs, sizeof( funcs ) ); ret->name = "oscar"; ret->data = prot->info->id; register_protocol( ret ); } } g_string_append( help, "\n\nFor used protocols, more information about available " "settings can be found using \x02help purple <protocol name>\x02 " "(create an account using that protocol first!)" ); /* Add a simple dynamically-generated help item listing all the supported protocols. */ help_add_mem( &global.help, "purple", help->str ); g_string_free( help, TRUE ); }
static void sevencup_attempt_connection(SevenCupConnection *scon) { gboolean is_proxy = FALSE; SevenCupAccount *sa = scon->sa; PurpleProxyInfo *proxy_info = NULL; if (sa && sa->account && !(scon->method & STEAM_METHOD_SSL)) { proxy_info = purple_proxy_get_setup(sa->account); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) proxy_info = purple_global_proxy_get_info(); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP) { is_proxy = TRUE; } } #if 0 /* Connection to attempt retries. This code doesn't work perfectly, but * remains here for future reference if needed */ if (time(NULL) - scon->request_time > 5) { /* We've continuously tried to remake this connection for a * bit now. It isn't happening, sadly. Time to die. */ purple_debug_error("7cups", "could not connect after retries\n"); sevencup_fatal_connection_cb(scon); return; } purple_debug_info("7cups", "making connection attempt\n"); /* TODO: If we're retrying the connection, consider clearing the cached * DNS value. This will require some juggling with the hostname param */ /* TODO/FIXME: This retries almost instantenously, which in some cases * runs at blinding speed. Slow it down. */ /* TODO/FIXME: this doesn't retry properly on non-ssl connections */ #endif sa->conns = g_slist_prepend(sa->conns, scon); /* * Do a separate DNS lookup for the given host name and cache it * for next time. * * TODO: It would be better if we did this before we call * purple_proxy_connect(), so we could re-use the result. * Or even better: Use persistent HTTP connections for servers * that we access continually. * * TODO: This cache of the hostname<-->IP address does not respect * the TTL returned by the DNS server. We should expire things * from the cache after some amount of time. */ if (!is_proxy && !(scon->method & STEAM_METHOD_SSL) && !g_hostname_is_ip_address(scon->hostname)) { /* Don't do this for proxy connections, since proxies do the DNS lookup */ gchar *host_ip; host_ip = g_hash_table_lookup(sa->hostname_ip_cache, scon->hostname); if (host_ip != NULL) { g_free(scon->hostname); scon->hostname = g_strdup(host_ip); } else if (sa->account && !sa->account->disconnecting) { GSList *host_lookup_list = NULL; PurpleDnsQueryData *query; host_lookup_list = g_slist_prepend( host_lookup_list, g_strdup(scon->hostname)); host_lookup_list = g_slist_prepend( host_lookup_list, sa); query = purple_dnsquery_a( #if PURPLE_VERSION_CHECK(3, 0, 0) scon->sa->account, #endif scon->hostname, 80, sevencup_host_lookup_cb, host_lookup_list); sa->dns_queries = g_slist_prepend(sa->dns_queries, query); host_lookup_list = g_slist_append(host_lookup_list, query); } } if (scon->method & STEAM_METHOD_SSL) { scon->ssl_conn = purple_ssl_connect(sa->account, scon->hostname, 443, sevencup_post_or_get_ssl_connect_cb, sevencup_ssl_connection_error, scon); } else { scon->connect_data = purple_proxy_connect(NULL, sa->account, scon->hostname, 80, sevencup_post_or_get_connect_cb, scon); } scon->timeout_watcher = purple_timeout_add_seconds(120, sevencup_connection_timedout, scon); return; }
SevenCupConnection * sevencup_post_or_get(SevenCupAccount *sa, SteamMethod method, const gchar *host, const gchar *url, const gchar *postdata, SteamProxyCallbackFunc callback_func, gpointer user_data, gboolean keepalive) { GString *request; gchar *cookies; SevenCupConnection *scon; gchar *real_url; gboolean is_proxy = FALSE; const gchar *user_agent; const gchar* const *languages; gchar *language_names; PurpleProxyInfo *proxy_info = NULL; gchar *proxy_auth; gchar *proxy_auth_base64; if (host == NULL) host = "www.7cupsoftea.com"; if (sa && sa->account) { if (purple_account_get_bool(sa->account, "use-https", TRUE)) method |= STEAM_METHOD_SSL; } if (sa && sa->account && !(method & STEAM_METHOD_SSL)) { proxy_info = purple_proxy_get_setup(sa->account); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) proxy_info = purple_global_proxy_get_info(); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP) { is_proxy = TRUE; } } if (is_proxy == TRUE) { real_url = g_strdup_printf("http://%s%s", host, url); } else { real_url = g_strdup(url); } cookies = sevencup_cookies_to_string(sa); user_agent = purple_account_get_string(sa->account, "user-agent", "Steam 1.2.0 / iPhone"); if (method & STEAM_METHOD_POST && !postdata) postdata = ""; /* Build the request */ request = g_string_new(NULL); g_string_append_printf(request, "%s %s HTTP/1.1\r\n", (method & STEAM_METHOD_POST) ? "POST" : "GET", real_url); if (is_proxy == FALSE) g_string_append_printf(request, "Host: %s\r\n", host); g_string_append_printf(request, "Connection: %s\r\n", (keepalive ? "Keep-Alive" : "close")); g_string_append_printf(request, "User-Agent: %s\r\n", user_agent); if (method & STEAM_METHOD_POST) { g_string_append_printf(request, "Content-Type: application/x-www-form-urlencoded\r\n"); g_string_append_printf(request, "Content-length: %zu\r\n", strlen(postdata)); } g_string_append_printf(request, "Accept: */*\r\n"); g_string_append_printf(request, "Cookie: %s\r\n", cookies); g_string_append_printf(request, "Accept-Encoding: gzip\r\n"); if (is_proxy == TRUE) { if (purple_proxy_info_get_username(proxy_info) && purple_proxy_info_get_password(proxy_info)) { proxy_auth = g_strdup_printf("%s:%s", purple_proxy_info_get_username(proxy_info), purple_proxy_info_get_password(proxy_info)); proxy_auth_base64 = purple_base64_encode((guchar *)proxy_auth, strlen(proxy_auth)); g_string_append_printf(request, "Proxy-Authorization: Basic %s\r\n", proxy_auth_base64); g_free(proxy_auth_base64); g_free(proxy_auth); } } /* Tell the server what language we accept, so that we get error messages in our language (rather than our IP's) */ languages = g_get_language_names(); language_names = g_strjoinv(", ", (gchar **)languages); purple_util_chrreplace(language_names, '_', '-'); g_string_append_printf(request, "Accept-Language: %s\r\n", language_names); g_free(language_names); purple_debug_info("7cups", "getting url %s\n", url); g_string_append_printf(request, "\r\n"); if (method & STEAM_METHOD_POST) g_string_append_printf(request, "%s", postdata); /* If it needs to go over a SSL connection, we probably shouldn't print * it in the debug log. Without this condition a user's password is * printed in the debug log */ if (method == STEAM_METHOD_POST) purple_debug_info("7cups", "sending request data:\n%s\n", postdata); g_free(cookies); scon = g_new0(SevenCupConnection, 1); scon->sa = sa; scon->url = real_url; scon->method = method; scon->hostname = g_strdup(host); scon->request = request; scon->callback = callback_func; scon->user_data = user_data; scon->fd = -1; scon->connection_keepalive = keepalive; scon->request_time = time(NULL); g_queue_push_head(sa->waiting_conns, scon); sevencup_next_connection(sa); return scon; }
SkypeWebConnection * skypeweb_post_or_get(SkypeWebAccount *sa, SkypeWebMethod method, const gchar *host, const gchar *url, const gchar *postdata, SkypeWebProxyCallbackFunc callback_func, gpointer user_data, gboolean keepalive) { GString *request; gchar *cookies; SkypeWebConnection *skypewebcon; gchar *real_url; gboolean is_proxy = FALSE; //const gchar *user_agent; const gchar* const *languages; gchar *language_names; PurpleProxyInfo *proxy_info = NULL; gchar *proxy_auth; gchar *proxy_auth_base64; /* TODO: Fix keepalive and use it as much as possible */ keepalive = FALSE; if (host == NULL) host = "api.skype.com"; if (sa && sa->account) { if (purple_account_get_bool(sa->account, "use-https", TRUE)) method |= SKYPEWEB_METHOD_SSL; } if (sa && sa->account && !(method & SKYPEWEB_METHOD_SSL)) { proxy_info = purple_proxy_get_setup(sa->account); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL) proxy_info = purple_global_proxy_get_info(); if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP) { is_proxy = TRUE; } } if (is_proxy == TRUE) { real_url = g_strdup_printf("http://%s%s", host, url); } else { real_url = g_strdup(url); } cookies = skypeweb_cookies_to_string(sa); //user_agent = purple_account_get_string(sa->account, "user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36"); if ((method & (SKYPEWEB_METHOD_POST | SKYPEWEB_METHOD_PUT)) && !postdata) postdata = ""; /* Build the request */ request = g_string_new(NULL); g_string_append_printf(request, "%s %s HTTP/1.0\r\n", ((method & SKYPEWEB_METHOD_POST) ? "POST" : ((method & SKYPEWEB_METHOD_PUT) ? "PUT" : ((method & SKYPEWEB_METHOD_DELETE) ? "DELETE" : "GET"))), real_url); if (is_proxy == FALSE) g_string_append_printf(request, "Host: %s\r\n", host); g_string_append_printf(request, "Connection: %s\r\n", (keepalive ? "Keep-Alive" : "close")); //g_string_append_printf(request, "User-Agent: %s\r\n", user_agent); if (method & (SKYPEWEB_METHOD_POST | SKYPEWEB_METHOD_PUT)) { if (postdata && (postdata[0] == '[' || postdata[0] == '{')) { g_string_append(request, "Content-Type: application/json\r\n"); // hax } else { g_string_append_printf(request, "Content-Type: application/x-www-form-urlencoded\r\n"); } g_string_append_printf(request, "Content-length: %zu\r\n", strlen(postdata)); } if (g_str_equal(host, SKYPEWEB_CONTACTS_HOST) || g_str_equal(host, SKYPEWEB_VIDEOMAIL_HOST)) { g_string_append_printf(request, "X-Skypetoken: %s\r\n", sa->skype_token); g_string_append(request, "X-Stratus-Caller: " SKYPEWEB_CLIENTINFO_NAME "\r\n"); g_string_append(request, "X-Stratus-Request: abcd1234\r\n"); g_string_append(request, "Origin: https://web.skype.com\r\n"); g_string_append(request, "Referer: https://web.skype.com/main\r\n"); g_string_append(request, "Accept: application/json; ver=1.0;\r\n"); } else if (g_str_equal(host, sa->messages_host)) { g_string_append_printf(request, "RegistrationToken: %s\r\n", sa->registration_token); g_string_append(request, "Referer: https://web.skype.com/main\r\n"); g_string_append(request, "Accept: application/json; ver=1.0;\r\n"); g_string_append(request, "ClientInfo: os=Windows; osVer=8.1; proc=Win32; lcid=en-us; deviceType=1; country=n/a; clientName=" SKYPEWEB_CLIENTINFO_NAME "; clientVer=" SKYPEWEB_CLIENTINFO_VERSION "\r\n"); } else { g_string_append_printf(request, "Accept: */*\r\n"); g_string_append_printf(request, "Cookie: %s\r\n", cookies); } g_string_append_printf(request, "Accept-Encoding: gzip\r\n"); if (is_proxy == TRUE) { if (purple_proxy_info_get_username(proxy_info) && purple_proxy_info_get_password(proxy_info)) { proxy_auth = g_strdup_printf("%s:%s", purple_proxy_info_get_username(proxy_info), purple_proxy_info_get_password(proxy_info)); proxy_auth_base64 = purple_base64_encode((guchar *)proxy_auth, strlen(proxy_auth)); g_string_append_printf(request, "Proxy-Authorization: Basic %s\r\n", proxy_auth_base64); g_free(proxy_auth_base64); g_free(proxy_auth); } } /* Tell the server what language we accept, so that we get error messages in our language (rather than our IP's) */ languages = g_get_language_names(); language_names = g_strjoinv(", ", (gchar **)languages); purple_util_chrreplace(language_names, '_', '-'); g_string_append_printf(request, "Accept-Language: %s\r\n", language_names); g_free(language_names); purple_debug_info("skypeweb", "getting url %s\n", url); g_string_append_printf(request, "\r\n"); if (method & (SKYPEWEB_METHOD_POST | SKYPEWEB_METHOD_PUT)) g_string_append_printf(request, "%s", postdata); /* If it needs to go over a SSL connection, we probably shouldn't print * it in the debug log. Without this condition a user's password is * printed in the debug log */ if (method == SKYPEWEB_METHOD_POST || method == SKYPEWEB_METHOD_PUT) purple_debug_info("skypeweb", "sending request data:\n%s\n", postdata); purple_debug_misc("skypeweb", "sending headers:\n%s\n", request->str); g_free(cookies); skypewebcon = g_new0(SkypeWebConnection, 1); skypewebcon->sa = sa; skypewebcon->url = real_url; skypewebcon->method = method; skypewebcon->hostname = g_strdup(host); skypewebcon->request = request; skypewebcon->callback = callback_func; skypewebcon->user_data = user_data; skypewebcon->fd = -1; skypewebcon->connection_keepalive = keepalive; skypewebcon->request_time = time(NULL); g_queue_push_head(sa->waiting_conns, skypewebcon); skypeweb_next_connection(sa); return skypewebcon; }
void fb_post_or_get(FacebookAccount *fba, FacebookMethod method, const gchar *host, const gchar *url, const gchar *postdata, FacebookProxyCallbackFunc callback_func, gpointer user_data, gboolean keepalive) { GString *request; gchar *cookies; FacebookConnection *fbconn; gchar *real_url; gboolean is_proxy = FALSE; const gchar *user_agent; /* TODO: Fix keepalive and use it as much as possible */ keepalive = FALSE; if (host == NULL) host = "www.facebook.com"; if (fba && fba->account && fba->account->proxy_info && (fba->account->proxy_info->type == PURPLE_PROXY_HTTP || (fba->account->proxy_info->type == PURPLE_PROXY_USE_GLOBAL && purple_global_proxy_get_info() && purple_global_proxy_get_info()->type == PURPLE_PROXY_HTTP))) { real_url = g_strdup_printf("http://%s%s", host, url); is_proxy = TRUE; } else { real_url = g_strdup(url); } cookies = fb_cookies_to_string(fba); user_agent = purple_account_get_string(fba->account, "user-agent", "Opera/9.50 (Windows NT 5.1; U; en-GB)"); /* Build the request */ request = g_string_new(NULL); g_string_append_printf(request, "%s %s HTTP/1.0\r\n", (method & FB_METHOD_POST) ? "POST" : "GET", real_url); g_string_append_printf(request, "Host: %s\r\n", host); g_string_append_printf(request, "Connection: %s\r\n", (keepalive ? "Keep-Alive" : "close")); g_string_append_printf(request, "User-Agent: %s\r\n", user_agent); if (method & FB_METHOD_POST) { g_string_append_printf(request, "Content-Type: application/x-www-form-urlencoded\r\n"); g_string_append_printf(request, "Content-length: %zu\r\n", strlen(postdata)); } g_string_append_printf(request, "Accept: */*\r\n"); g_string_append_printf(request, "Cookie: isfbe=false;%s\r\n", cookies); #ifdef HAVE_ZLIB if (zlib_inflate != NULL) g_string_append_printf(request, "Accept-Encoding: gzip\r\n"); #endif purple_debug_misc("facebook", "sending request headers:\n%s\n", request->str); g_string_append_printf(request, "\r\n"); if (method & FB_METHOD_POST) g_string_append_printf(request, "%s", postdata); /* If it needs to go over a SSL connection, we probably shouldn't print * it in the debug log. Without this condition a user's password is * printed in the debug log */ if (method == FB_METHOD_POST) purple_debug_misc("facebook", "sending request data:\n%s\n", postdata); g_free(cookies); g_free(real_url); /* * Do a separate DNS lookup for the given host name and cache it * for next time. * * TODO: It would be better if we did this before we call * purple_proxy_connect(), so we could re-use the result. * Or even better: Use persistent HTTP connections for servers * that we access continually. * * TODO: This cache of the hostname<-->IP address does not respect * the TTL returned by the DNS server. We should expire things * from the cache after some amount of time. */ if (!is_proxy) { /* Don't do this for proxy connections, since proxies do the DNS lookup */ gchar *host_ip; host_ip = g_hash_table_lookup(fba->hostname_ip_cache, host); if (host_ip != NULL) { purple_debug_info("facebook", "swapping original host %s with cached value of %s\n", host, host_ip); host = host_ip; } else if (fba->account && !fba->account->disconnecting) { GSList *host_lookup_list = NULL; PurpleDnsQueryData *query; host_lookup_list = g_slist_prepend( host_lookup_list, g_strdup(host)); host_lookup_list = g_slist_prepend( host_lookup_list, fba); query = purple_dnsquery_a(host, 80, fb_host_lookup_cb, host_lookup_list); fba->dns_queries = g_slist_prepend(fba->dns_queries, query); host_lookup_list = g_slist_append(host_lookup_list, query); } } fbconn = g_new0(FacebookConnection, 1); fbconn->fba = fba; fbconn->method = method; fbconn->hostname = g_strdup(host); fbconn->request = request; fbconn->callback = callback_func; fbconn->user_data = user_data; fbconn->fd = -1; fbconn->connection_keepalive = keepalive; fbconn->request_time = time(NULL); fba->conns = g_slist_prepend(fba->conns, fbconn); fb_attempt_connection(fbconn); }