source: protocols/twitter/twitter_http.c @ 63825d6

Last change on this file since 63825d6 was bbff22d, checked in by dequis <dx@…>, at 2015-10-09T02:41:01Z

twitter: Fix some nitpicky issues reported by coverity

Mostly minor rare leaks that happen in error conditions, and one
dereference before null check in twitter_logout (the null check is
probably the wrong one there, but it doesn't hurt to keep it)

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[1b221e0]1/***************************************************************************\
2*                                                                           *
3*  BitlBee - An IRC to IM gateway                                           *
4*  Simple module to facilitate twitter functionality.                       *
5*                                                                           *
6*  Copyright 2009 Geert Mulders <g.c.w.m.mulders@gmail.com>                 *
7*                                                                           *
8*  This library is free software; you can redistribute it and/or            *
9*  modify it under the terms of the GNU Lesser General Public               *
10*  License as published by the Free Software Foundation, version            *
11*  2.1.                                                                     *
12*                                                                           *
13*  This library is distributed in the hope that it will be useful,          *
14*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
15*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
16*  Lesser General Public License for more details.                          *
17*                                                                           *
18*  You should have received a copy of the GNU Lesser General Public License *
19*  along with this library; if not, write to the Free Software Foundation,  *
20*  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA           *
21*                                                                           *
22****************************************************************************/
23
24/***************************************************************************\
25*                                                                           *
[e88fe7da]26*  Some functions within this file have been copied from other files within  *
[1b221e0]27*  BitlBee.                                                                 *
28*                                                                           *
[5983eca]29****************************************************************************/
[1b221e0]30
31#include "twitter.h"
32#include "bitlbee.h"
33#include "url.h"
34#include "misc.h"
35#include "base64.h"
[508c340]36#include "oauth.h"
[1b221e0]37#include <ctype.h>
38#include <errno.h>
39
[c2ecadc]40#include "twitter_http.h"
41
[1b221e0]42
[5983eca]43static char *twitter_url_append(char *url, char *key, char *value);
[1b221e0]44
45/**
46 * Do a request.
47 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c
48 */
[ddc2de5]49struct http_request *twitter_http(struct im_connection *ic, char *url_string, http_input_function func,
[5ebff60]50                                  gpointer data, int is_post, char **arguments, int arguments_len)
[1b221e0]51{
[bb5ce4d1]52        struct twitter_data *td = ic->proto_data;
[1b221e0]53        char *tmp;
[bb5ce4d1]54        GString *request = g_string_new("");
[bbff22d]55        void *ret = NULL;
[1b221e0]56        char *url_arguments;
[ddc2de5]57        url_t *base_url = NULL;
[1b221e0]58
[bb5ce4d1]59        url_arguments = g_strdup("");
[1b221e0]60
61        // Construct the url arguments.
[5983eca]62        if (arguments_len != 0) {
[1b221e0]63                int i;
[5983eca]64                for (i = 0; i < arguments_len; i += 2) {
65                        tmp = twitter_url_append(url_arguments, arguments[i], arguments[i + 1]);
[1b221e0]66                        g_free(url_arguments);
67                        url_arguments = tmp;
68                }
69        }
[5ebff60]70
[ddc2de5]71        if (strstr(url_string, "://")) {
72                base_url = g_new0(url_t, 1);
73                if (!url_set(base_url, url_string)) {
[bbff22d]74                        goto error;
[ddc2de5]75                }
76        }
[5ebff60]77
[1b221e0]78        // Make the request.
[dd7b931]79        g_string_printf(request, "%s %s%s%s%s HTTP/1.1\r\n"
[5ebff60]80                        "Host: %s\r\n"
81                        "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n",
82                        is_post ? "POST" : "GET",
83                        base_url ? base_url->file : td->url_path,
84                        base_url ? "" : url_string,
85                        is_post ? "" : "?", is_post ? "" : url_arguments,
86                        base_url ? base_url->host : td->url_host);
[1b221e0]87
88        // If a pass and user are given we append them to the request.
[5983eca]89        if (td->oauth_info) {
[508c340]90                char *full_header;
[bb5ce4d1]91                char *full_url;
[5983eca]92
[5ebff60]93                if (base_url) {
[ddc2de5]94                        full_url = g_strdup(url_string);
[5ebff60]95                } else {
[ddc2de5]96                        full_url = g_strconcat(set_getstr(&ic->acc->set, "base_url"), url_string, NULL);
[5ebff60]97                }
[bb5ce4d1]98                full_header = oauth_http_header(td->oauth_info, is_post ? "POST" : "GET",
[5ebff60]99                                                full_url, url_arguments);
[5983eca]100
[bb5ce4d1]101                g_string_append_printf(request, "Authorization: %s\r\n", full_header);
[508c340]102                g_free(full_header);
[bb5ce4d1]103                g_free(full_url);
[5983eca]104        } else {
105                char userpass[strlen(ic->acc->user) + 2 + strlen(ic->acc->pass)];
[bb5ce4d1]106                char *userpass_base64;
[5983eca]107
[bb5ce4d1]108                g_snprintf(userpass, sizeof(userpass), "%s:%s", ic->acc->user, ic->acc->pass);
[5983eca]109                userpass_base64 = base64_encode((unsigned char *) userpass, strlen(userpass));
[bb5ce4d1]110                g_string_append_printf(request, "Authorization: Basic %s\r\n", userpass_base64);
[5983eca]111                g_free(userpass_base64);
[1b221e0]112        }
113
114        // Do POST stuff..
[5983eca]115        if (is_post) {
[1b221e0]116                // Append the Content-Type and url-encoded arguments.
[bb5ce4d1]117                g_string_append_printf(request,
[5ebff60]118                                       "Content-Type: application/x-www-form-urlencoded\r\n"
119                                       "Content-Length: %zd\r\n\r\n%s",
120                                       strlen(url_arguments), url_arguments);
[1b221e0]121        } else {
122                // Append an extra \r\n to end the request...
[bb5ce4d1]123                g_string_append(request, "\r\n");
[1b221e0]124        }
125
[5ebff60]126        if (base_url) {
127                ret = http_dorequest(base_url->host, base_url->port, base_url->proto == PROTO_HTTPS, request->str, func,
128                                     data);
129        } else {
[ddc2de5]130                ret = http_dorequest(td->url_host, td->url_port, td->url_ssl, request->str, func, data);
[5ebff60]131        }
[1b221e0]132
[bbff22d]133error:
[5983eca]134        g_free(url_arguments);
135        g_string_free(request, TRUE);
[ddc2de5]136        g_free(base_url);
[1b221e0]137        return ret;
138}
139
[b235228]140struct http_request *twitter_http_f(struct im_connection *ic, char *url_string, http_input_function func,
[5ebff60]141                                    gpointer data, int is_post, char **arguments, int arguments_len,
142                                    twitter_http_flags_t flags)
[b235228]143{
144        struct http_request *ret = twitter_http(ic, url_string, func, data, is_post, arguments, arguments_len);
[5ebff60]145
146        if (ret) {
[b235228]147                ret->flags |= flags;
[5ebff60]148        }
[b235228]149        return ret;
150}
151
[5983eca]152static char *twitter_url_append(char *url, char *key, char *value)
[1b221e0]153{
[2abceca]154        char *key_encoded = g_strndup(key, 3 * strlen(key));
[5ebff60]155
[2abceca]156        http_encode(key_encoded);
157        char *value_encoded = g_strndup(value, 3 * strlen(value));
158        http_encode(value_encoded);
159
[1b221e0]160        char *retval;
[5ebff60]161        if (strlen(url) != 0) {
[1b221e0]162                retval = g_strdup_printf("%s&%s=%s", url, key_encoded, value_encoded);
[5ebff60]163        } else {
[1b221e0]164                retval = g_strdup_printf("%s=%s", key_encoded, value_encoded);
[5ebff60]165        }
[1b221e0]166
167        g_free(key_encoded);
168        g_free(value_encoded);
169
170        return retval;
171}
Note: See TracBrowser for help on using the repository browser.