source: protocols/twitter/twitter_http.c @ acba168

Last change on this file since acba168 was 508c340, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-04-26T00:42:37Z

Successfully posted a tweet!

Twitter's tricky. It returns vars (user_id, screen_name) in the access token
that, the way I read the spec, should be included in all subsequent queries.
However, stuff only started to work when I dropped those vars.

This code's definitely not pretty ATM. Need to clean up now that it actually
works.

  • Property mode set to 100644
File size: 5.7 KB
Line 
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*                                                                           *
26*  Some funtions within this file have been copied from other files within  *
27*  BitlBee.                                                                 *
28*                                                                           *
29****************************************************************************/ 
30
31#include "twitter_http.h"
32#include "twitter.h"
33#include "bitlbee.h"
34#include "url.h"
35#include "misc.h"
36#include "base64.h"
37#include "oauth.h"
38#include <ctype.h>
39#include <errno.h>
40
41
42char *twitter_url_append(char *url, char *key, char* value);
43
44/**
45 * Do a request.
46 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c
47 */
48void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char* oauth_token, char** arguments, int arguments_len)
49{
50        url_t *url = g_new0( url_t, 1 );
51        char *tmp;
52        char *request;
53        void *ret;
54        char *userpass = NULL;
55        char *userpass_base64;
56        char *url_arguments;
57
58        // Fill the url structure.
59        if( !url_set( url, url_string ) )
60        {
61                g_free( url );
62                return NULL;
63        }
64
65        if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS )
66        {
67                g_free( url );
68                return NULL;
69        }
70
71        // Concatenate user and pass
72        if (user && pass) {
73                userpass = g_strdup_printf("%s:%s", user, pass);
74                userpass_base64 = base64_encode((unsigned char*)userpass, strlen(userpass));
75        } else {
76                userpass_base64 = NULL;
77        }
78
79        url_arguments = g_malloc(1);
80        url_arguments[0] = '\0';
81
82        // Construct the url arguments.
83        if (arguments_len != 0)
84        {
85                int i;
86                for (i=0; i<arguments_len; i+=2) 
87                {
88                        tmp = twitter_url_append(url_arguments, arguments[i], arguments[i+1]);
89                        g_free(url_arguments);
90                        url_arguments = tmp;
91                }
92        }
93
94        // Do GET stuff...
95        if (!is_post)
96        {
97                // Find the char-pointer of the end of the string.
98                tmp = url->file + strlen(url->file);
99                tmp[0] = '?';
100                // append the url_arguments to the end of the url->file.
101                // TODO GM: Check the length?
102                g_stpcpy (tmp+1, url_arguments);
103        }
104
105
106        // Make the request.
107        request = g_strdup_printf(  "%s %s HTTP/1.0\r\n"
108                                    "Host: %s\r\n"
109                                    "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n",
110                                    is_post ? "POST" : "GET", url->file, url->host );
111
112        // If a pass and user are given we append them to the request.
113        if (oauth_token)
114        {
115                char *full_header;
116               
117                full_header = oauth_http_header(oauth_token,
118                                                is_post ? "POST" : "GET",
119                                                url_string, url_arguments);
120               
121                tmp = g_strdup_printf("%sAuthorization: %s\r\n", request, full_header);
122                g_free(request);
123                g_free(full_header);
124                request = tmp;
125        }
126        else if (userpass_base64)
127        {
128                tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64);
129                g_free(request);
130                request = tmp;
131        }
132
133        // Do POST stuff..
134        if (is_post)
135        {
136                // Append the Content-Type and url-encoded arguments.
137                tmp = g_strdup_printf("%sContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %zd\r\n\r\n%s", 
138                                                                request, strlen(url_arguments), url_arguments);
139                g_free(request);
140                request = tmp;
141        } else {
142                // Append an extra \r\n to end the request...
143                tmp = g_strdup_printf("%s\r\n", request);
144                g_free(request);
145                request = tmp;
146        }
147
148        ret = http_dorequest( url->host, url->port,     url->proto == PROTO_HTTPS, request, func, data );
149
150        g_free( url );
151        g_free( userpass );
152        g_free( userpass_base64 );
153        g_free( url_arguments );
154        g_free( request );
155        return ret;
156}
157
158char *twitter_url_append(char *url, char *key, char* value)
159{
160        char *key_encoded = g_strndup(key, 3 * strlen(key));
161        http_encode(key_encoded);
162        char *value_encoded = g_strndup(value, 3 * strlen(value));
163        http_encode(value_encoded);
164
165        char *retval;
166        if (strlen(url) != 0)
167                retval = g_strdup_printf("%s&%s=%s", url, key_encoded, value_encoded);
168        else
169                retval = g_strdup_printf("%s=%s", key_encoded, value_encoded);
170
171        g_free(key_encoded);
172        g_free(value_encoded);
173
174        return retval;
175}
Note: See TracBrowser for help on using the repository browser.