1
/* vim: set expandtab ts=8 sw=4: */
3
/* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Library General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
#include <sys/socket.h>
27
#include <netinet/in.h>
28
#include <sys/types.h>
33
#include <libxfce4util/libxfce4util.h>
34
#include <libxfce4panel/xfce-panel-macros.h>
36
#include "http_client.h"
49
gchar *request_buffer;
58
keep_receiving (gpointer data);
62
http_connect (gchar *hostname,
65
struct sockaddr_in dest_host;
66
struct hostent *host_address;
69
if ((host_address = gethostbyname(hostname)) == NULL)
72
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
75
dest_host.sin_family = AF_INET;
76
dest_host.sin_port = htons(port);
77
dest_host.sin_addr = *((struct in_addr *)host_address->h_addr);
78
memset(&(dest_host.sin_zero), '\0', 8);
79
fcntl(fd, F_SETFL, O_NONBLOCK);
81
if ((connect(fd, (struct sockaddr *)&dest_host, sizeof(struct sockaddr)) == -1)
82
&& errno != EINPROGRESS)
84
perror("http_connect()");
93
request_free (struct request_data *request)
95
if (request->request_buffer)
96
g_free(request->request_buffer);
98
if (request->save_filename)
99
g_free(request->save_filename);
101
if (request->save_fp)
102
fclose(request->save_fp);
107
panel_slice_free (struct request_data, request);
111
request_save (struct request_data *request,
114
DBG ("Request Save");
116
if (request->save_filename)
117
if (!request->save_fp &&
118
(request->save_fp = fopen(request->save_filename, "w"))
122
fwrite(buffer, sizeof(char), strlen(buffer),
126
if (*request->save_buffer)
128
gchar *newbuff = g_strconcat(*request->save_buffer,
130
g_free(*request->save_buffer);
131
*request->save_buffer = newbuff;
134
*request->save_buffer = g_strdup(buffer);
139
keep_sending (gpointer data)
141
struct request_data *request = (struct request_data *)data;
146
DBG ("keep_sending(): empty request data");
150
if ((n = send(request->fd, request->request_buffer + request->offset,
151
request->size - request->offset,
154
request->offset += n;
156
DBG ("now at offset: %d", request->offset);
157
DBG ("now at byte: %d", n);
159
if (request->offset == request->size)
161
DBG ("keep_sending(): ok data sent");
162
g_idle_add(keep_receiving, (gpointer) request);
166
else if (errno != EAGAIN) /* some other error happened */
169
perror("keep_sending()");
172
DBG ("file desc: %d", request->fd);
174
request_free(request);
182
keep_receiving (gpointer data)
184
struct request_data *request = (struct request_data *)data;
185
gchar recvbuffer[1024];
192
DBG ("keep_receiving(): empty request data ");
196
if ((n = recv(request->fd, recvbuffer, sizeof(recvbuffer) -
197
sizeof(char), 0)) > 0)
199
recvbuffer[n] = '\0';
201
DBG ("keep_receiving(): bytes recv: %d", n);
203
if (!request->has_header)
205
if (request->last_chars != '\0')
206
str = g_strconcat(request->last_chars,
209
if ((p = strstr(str, "\r\n\r\n")))
211
request_save(request, p + 4);
212
request->has_header = TRUE;
213
DBG ("keep_receiving(): got header");
217
DBG ("keep_receiving(): no header yet\n\n%s\n..\n",
219
memcpy(request->last_chars, recvbuffer + (n - 4),
226
request_save(request, recvbuffer);
230
CB_TYPE callback = request->cb_function;
231
gpointer data = request->cb_data;
232
DBG ("keep_receiving(): ending with succes");
233
request_free(request);
235
callback(TRUE, data);
238
else if (errno != EAGAIN)
240
perror("keep_receiving()");
241
request->cb_function(FALSE, request->cb_data);
242
request_free(request);
252
http_get (gchar *url,
261
struct request_data *request = panel_slice_new0 (struct request_data);
266
perror("http_get(): empty request");
271
request->has_header = FALSE;
272
request->cb_function = callback;
273
request->cb_data = data;
277
DBG ("using proxy %s", proxy_host);
278
request->fd = http_connect(proxy_host, proxy_port);
282
DBG ("Not USING PROXY");
283
request->fd = http_connect(hostname, 80);
286
if (request->fd == -1)
288
DBG ("http_get(): fd = -1 returned");
289
request_free(request);
294
request->request_buffer = g_strdup_printf(
295
"GET http://%s%s HTTP/1.0\r\n\r\n",
298
request->request_buffer = g_strdup_printf("GET %s HTTP/1.0\r\n"
299
"Host: %s\r\n\r\n", url, hostname);
301
if (request->request_buffer == NULL)
304
perror("http_get(): empty request buffer\n");
307
panel_slice_free(struct request_data, request);
311
request->size = strlen (request->request_buffer);
314
request->save_filename = g_strdup (*fname_buff);
316
request->save_buffer = fname_buff;
318
DBG ("http_get(): adding idle function");
320
(void)g_idle_add ((GSourceFunc)keep_sending, (gpointer)request);
322
DBG ("http_get(): request added");
328
http_get_file (gchar *url,
336
return http_get (url, hostname, TRUE, &filename, proxy_host, proxy_port,
341
http_get_buffer (gchar *url,
349
return http_get (url, hostname, FALSE, buffer, proxy_host, proxy_port,