source: protocols/twitter/twitter_http.c @ 1b221e0

Last change on this file since 1b221e0 was 1b221e0, checked in by Geert Mulders <g.c.w.m.mulders@…>, at 2009-12-01T21:08:02Z

Added twitter-module.

  • Property mode set to 100644
File size: 6.6 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 <ctype.h>
38#include <errno.h>
39
40
41char *twitter_urlencode(const char *instr);
42char *twitter_url_append(char *url, char *key, char* value);
43static int isurlchar(unsigned char c);
44
45/**
46 * Do a request.
47 * This is actually pretty generic function... Perhaps it should move to the lib/http_client.c
48 */
49void *twitter_http(char *url_string, http_input_function func, gpointer data, int is_post, char* user, char* pass, char** arguments, int arguments_len)
50{
51        url_t *url = g_new0( url_t, 1 );
52        char *tmp;
53        char *request;
54        void *ret;
55        char *userpass = NULL;
56        char *userpass_base64;
57        char *url_arguments;
58
59        // Fill the url structure.
60        if( !url_set( url, url_string ) )
61        {
62                g_free( url );
63                return NULL;
64        }
65
66        if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS )
67        {
68                g_free( url );
69                return NULL;
70        }
71
72        // Concatenate user and pass
73        if (user && pass) {
74                userpass = g_strdup_printf("%s:%s", user, pass);
75                userpass_base64 = base64_encode((unsigned char*)userpass, strlen(userpass));
76        } else {
77                userpass_base64 = NULL;
78        }
79
80        url_arguments = g_malloc(1);
81        url_arguments[0] = '\0';
82
83        // Construct the url arguments.
84        if (arguments_len != 0)
85        {
86                int i;
87                for (i=0; i<arguments_len; i+=2) 
88                {
89                        tmp = twitter_url_append(url_arguments, arguments[i], arguments[i+1]);
90                        g_free(url_arguments);
91                        url_arguments = tmp;
92                }
93        }
94
95        // Do GET stuff...
96        if (!is_post)
97        {
98                // Find the char-pointer of the end of the string.
99                tmp = url->file + strlen(url->file);
100                tmp[0] = '?';
101                // append the url_arguments to the end of the url->file.
102                // TODO GM: Check the length?
103                g_stpcpy (tmp+1, url_arguments);
104        }
105
106
107        // Make the request.
108        request = g_strdup_printf(  "%s %s HTTP/1.0\r\n"
109                                                                "Host: %s\r\n"
110                                                                "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n",
111                                                                is_post ? "POST" : "GET", url->file, url->host );
112
113        // If a pass and user are given we append them to the request.
114        if (userpass_base64)
115        {
116                tmp = g_strdup_printf("%sAuthorization: Basic %s\r\n", request, userpass_base64);
117                g_free(request);
118                request = tmp;
119        }
120
121        // Do POST stuff..
122        if (is_post)
123        {
124                // Append the Content-Type and url-encoded arguments.
125                tmp = g_strdup_printf("%sContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\n%s", 
126                                                                request, strlen(url_arguments), url_arguments);
127                g_free(request);
128                request = tmp;
129        } else {
130                // Append an extra \r\n to end the request...
131                tmp = g_strdup_printf("%s\r\n", request);
132                g_free(request);
133                request = tmp;
134        }
135
136        ret = http_dorequest( url->host, url->port,     url->proto == PROTO_HTTPS, request, func, data );
137
138        g_free( url );
139        g_free( userpass );
140        g_free( userpass_base64 );
141        g_free( url_arguments );
142        g_free( request );
143        return ret;
144}
145
146char *twitter_url_append(char *url, char *key, char* value)
147{
148        char *key_encoded = twitter_urlencode(key);
149        char *value_encoded = twitter_urlencode(value);
150        char *retval;
151        if (strlen(url) != 0)
152                retval = g_strdup_printf("%s&%s=%s", url, key_encoded, value_encoded);
153        else
154                retval = g_strdup_printf("%s=%s", key_encoded, value_encoded);
155
156        g_free(key_encoded);
157        g_free(value_encoded);
158
159        return retval;
160}
161
162char *twitter_urlencode(const char *instr)
163{
164        int ipos=0, bpos=0;
165        char *str = NULL;
166        int len = strlen(instr);
167
168        if(!(str = g_new(char, 3*len + 1) ))
169                return "";
170
171        while(instr[ipos]) {
172                while(isurlchar(instr[ipos]))
173                        str[bpos++] = instr[ipos++];
174                if(!instr[ipos])
175                        break;
176
177                g_snprintf(&str[bpos], 4, "%%%.2x", instr[ipos]);
178                bpos+=3;
179                ipos++;
180        }
181        str[bpos]='\0';
182
183        /* free extra alloc'ed mem. */
184        len = strlen(str);
185        str = g_renew(char, str, len+1);
186
187        return (str);
188}
189
190
191char *twitter_urldecode(const char *instr)
192{
193        int ipos=0, bpos=0;
194        char *str = NULL;
195        char entity[3]={0,0,0};
196        unsigned dec;
197        int len = strlen(instr);
198
199        if(!(str = g_new(char, len+1) ))
200                return "";
201
202        while(instr[ipos]) {
203                while(instr[ipos] && instr[ipos]!='%')
204                        if(instr[ipos]=='+') {
205                                str[bpos++]=' ';
206                                ipos++;
207                        } else
208                                str[bpos++] = instr[ipos++];
209                        if(!instr[ipos])
210                                break;
211
212                        if(instr[ipos+1] && instr[ipos+2]) {
213                                ipos++;
214                                entity[0]=instr[ipos++];
215                                entity[1]=instr[ipos++];
216                                sscanf(entity, "%2x", &dec);
217                                str[bpos++] = (char)dec;
218                        } else {
219                                str[bpos++] = instr[ipos++];
220                        }
221                }
222        str[bpos]='\0';
223
224        /* free extra alloc'ed mem. */
225        len = strlen(str);
226        str = g_renew(char, str, len+1);
227
228        return (str);
229}
230
231static int isurlchar(unsigned char c)
232{
233        return (isalnum(c) || '-' == c || '_' == c);
234}
235
Note: See TracBrowser for help on using the repository browser.