[svn r269] Changed structure from gmyth_http to use *libcurl*.
1.1 --- a/gmyth/configure.ac Fri Jan 12 11:58:01 2007 +0000
1.2 +++ b/gmyth/configure.ac Fri Jan 12 21:26:30 2007 +0000
1.3 @@ -142,6 +142,18 @@
1.4 AC_SUBST(LIBXML_CFLAGS)
1.5 AC_SUBST(LIBXML_LIBS)
1.6
1.7 +# Check for libcurl
1.8 +PKG_CHECK_MODULES(LIBCURL, libcurl, HAVE_LIBCRUL=yes, HAVE_LIBCURL=no)
1.9 +
1.10 +# Give error and exit if we don't have libcurl
1.11 +if test "x$HAVE_LIBCURL" = "xno"; then
1.12 + AC_MSG_ERROR(you need libcurl installed)
1.13 +fi
1.14 +
1.15 +# make LIBCURL_CFLAGS and LIBCURL_LIBS available
1.16 +AC_SUBST(LIBCURL_CFLAGS)
1.17 +AC_SUBST(LIBCURL_LIBS)
1.18 +
1.19
1.20 # check for gstreamer development files
1.21 GST_REQUIRED=0.10
2.1 --- a/gmyth/src/gmyth_http.c Fri Jan 12 11:58:01 2007 +0000
2.2 +++ b/gmyth/src/gmyth_http.c Fri Jan 12 21:26:30 2007 +0000
2.3 @@ -39,232 +39,122 @@
2.4 #include "gmyth_debug.h"
2.5 #include "gmyth_socket.h"
2.6
2.7 -static void gmyth_http_class_init (GMythHttpClass *klass);
2.8 -static void gmyth_http_init (GMythHttp *object);
2.9 +struct MemoryStruct
2.10 +{
2.11 + char *memory;
2.12 + size_t size;
2.13 +};
2.14
2.15 -static void gmyth_http_dispose (GObject *object);
2.16 -static void gmyth_http_finalize (GObject *object);
2.17 -
2.18 -G_DEFINE_TYPE(GMythHttp, gmyth_http, G_TYPE_OBJECT)
2.19 -
2.20 -
2.21 -static void gmyth_http_class_init (GMythHttpClass *klass)
2.22 +/* Aux functions got from libcurl */
2.23 +void *myrealloc(void *ptr, size_t size)
2.24 {
2.25 - GObjectClass *gobject_class;
2.26 -
2.27 - gobject_class = (GObjectClass *) klass;
2.28 - gobject_class->dispose = gmyth_http_dispose;
2.29 - gobject_class->finalize = gmyth_http_finalize;
2.30 + /* There might be a realloc() out there that doesn't like reallocing
2.31 + NULL pointers, so we take care of it here */
2.32 + if(ptr)
2.33 + return realloc(ptr, size);
2.34 + else
2.35 + return malloc(size);
2.36 }
2.37
2.38 -static void gmyth_http_init (GMythHttp *gmyth_http)
2.39 +size_t
2.40 +WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
2.41 {
2.42 - gmyth_http->backend_info = NULL;
2.43 - gmyth_http->socket = gmyth_socket_new (MYTH_PORT_STATUS);
2.44 -
2.45 + size_t realsize = size * nmemb;
2.46 + struct MemoryStruct *mem = (struct MemoryStruct *)data;
2.47 +
2.48 + mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
2.49 + if (mem->memory) {
2.50 + memcpy(&(mem->memory[mem->size]), ptr, realsize);
2.51 + mem->size += realsize;
2.52 + mem->memory[mem->size] = 0;
2.53 + }
2.54 + return realsize;
2.55 }
2.56
2.57 -static void gmyth_http_dispose (GObject *object)
2.58 +/** Create a String containing the URL with the command
2.59 + *
2.60 + * @param command A string with the command
2.61 + * @param variables Vars to use with their values \
2.62 + * MUST FINISH WITH NULL!!!
2.63 + * @return The response
2.64 + */
2.65 +GString* gmyth_http_create_command(GString *command, ...)
2.66 {
2.67 - GMythHttp *gmyth_http = GMYTH_HTTP (object);
2.68 -
2.69 - if (gmyth_http->backend_info)
2.70 - g_object_unref (gmyth_http->backend_info);
2.71 + va_list args;
2.72 + va_start(args, command);
2.73 + char* s = NULL;
2.74
2.75 - if (gmyth_http->socket)
2.76 - g_object_unref (gmyth_http->socket);
2.77 -
2.78 - G_OBJECT_CLASS (gmyth_http_parent_class)->dispose (object);
2.79 + g_string_append(command, "?");
2.80 +
2.81 + while ( (s = va_arg(args, char *)) != NULL )
2.82 + {
2.83 + g_string_append(command, s);
2.84 + g_string_append(command, "=");
2.85 + s = va_arg(args, char *);
2.86 + g_string_append(command, s);
2.87 + g_string_append(command, "&");
2.88 + }
2.89 +
2.90 +
2.91 + /* TODO: erase this */
2.92 + printf("Comando: %s\n", command);
2.93 + free(s);
2.94 +
2.95 + va_end(args);
2.96 +
2.97 + return command;
2.98 }
2.99
2.100 -static void gmyth_http_finalize (GObject *object)
2.101 -{
2.102 - g_signal_handlers_destroy (object);
2.103 - G_OBJECT_CLASS (gmyth_http_parent_class)->finalize (object);
2.104 -}
2.105 -
2.106 -/** Creates a new instance of GMythHttp.
2.107 - *
2.108 - * @return a new instance of GMythHttp.
2.109 +/** Send HTTP Command and receives the result of it
2.110 + *
2.111 + * @return A string with the response from the server
2.112 */
2.113 -GMythHttp* gmyth_http_new ()
2.114 -{
2.115 - GMythHttp *http = GMYTH_HTTP (g_object_new(GMYTH_HTTP_TYPE, NULL));
2.116 - return http;
2.117 -}
2.118 -
2.119 -/** Creates the Header of the packet.
2.120 - *
2.121 - * @param command The string of the command to be sent
2.122 - * @return String with the header appended to the command
2.123 - */
2.124 -GString * gmyth_http_create_header (GString *command)
2.125 +GString
2.126 +*gmyth_http_request (GMythBackendInfo *backend_info, GString *command)
2.127 {
2.128
2.129 - /* secure len to avoid buffer overflows */
2.130 - /* len must be big enough to support the command */
2.131 - gsize len = command->len + 2048;
2.132 - gchar *new_command = g_new0 (gchar, command->len + 2048);
2.133 -
2.134 - g_snprintf(new_command, len,
2.135 - "GET /%s HTTP/1.1\r\n"
2.136 - "Host: 127.0.0.1:6544\r\n"
2.137 - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.8) "
2.138 - "Gecko/20061025 Firefox/1.5.0.8\r\n"
2.139 - "Accept: text/xml,application/xml,application/xhtml+xml,text/html;"
2.140 - "q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
2.141 - "Accept-Language: en-us,en;q=0.5\r\n"
2.142 - "Accept-Encoding: gzip,deflate\r\n"
2.143 - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
2.144 - "Keep-Alive: 300\r\n"
2.145 - "Connection: keep-alive\r\n"
2.146 - "\r\n"
2.147 - , command->str);
2.148 + size_t size = strlen(backend_info->hostname) + strlen(command->str) + 13;
2.149 + char *URL = malloc(sizeof(char)*size);
2.150 + snprintf(URL, size+1, "http://%s:6544/%s", backend_info->hostname, command->str);
2.151
2.152 - GString *new = g_string_new(new_command);
2.153 - return new;
2.154 + CURL *curl_handle;
2.155 +
2.156 + struct MemoryStruct chunk;
2.157 +
2.158 + chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
2.159 + chunk.size = 0; /* no data at this point */
2.160 +
2.161 + curl_global_init(CURL_GLOBAL_ALL);
2.162 +
2.163 + /* init the curl session */
2.164 + curl_handle = curl_easy_init();
2.165 +
2.166 + /* specify URL to get */
2.167 + curl_easy_setopt(curl_handle, CURLOPT_URL, URL);
2.168 +
2.169 + /* send all data to this function */
2.170 + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
2.171 +
2.172 + /* we pass our 'chunk' struct to the callback function */
2.173 + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
2.174 +
2.175 + /* some servers don't like requests that are made without a user-agent
2.176 + field, so we provide one */
2.177 + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
2.178 +
2.179 + /* get it! */
2.180 + curl_easy_perform(curl_handle);
2.181 +
2.182 + /* cleanup curl stuff */
2.183 + curl_easy_cleanup(curl_handle);
2.184 +
2.185 + GString *response = NULL;
2.186
2.187 -}
2.188 -
2.189 -/** Removes the Header of the packet.
2.190 - *
2.191 - * @param packet The string of the packet
2.192 - * @return String without the header
2.193 - */
2.194 -GString * gmyth_http_remove_header (GString *packet)
2.195 -{
2.196 -}
2.197 -
2.198 -/** Sends a command to the backend.
2.199 - *
2.200 - * @param gmyth_socket the GMythSocket instance.
2.201 - * @param command The string command to be sent.
2.202 - * @return gboolean If everything went ok
2.203 - */
2.204 -gboolean gmyth_http_send_command(GMythSocket *gmyth_socket, GString *command)
2.205 -{
2.206 - gboolean ret = TRUE;
2.207 -
2.208 - GIOStatus io_status = G_IO_STATUS_NORMAL;
2.209 - GError* error = NULL;
2.210 -
2.211 - gsize bytes_written = 0;
2.212 -
2.213 - if( command == NULL || ( command->len <= 0 ) || command->str == NULL )
2.214 + if(chunk.memory)
2.215 {
2.216 - g_warning ("[%s] Invalid NULL command parameter!\n", __FUNCTION__);
2.217 - return FALSE;
2.218 + response = g_string_new(chunk.memory);
2.219 + free(chunk.memory);
2.220 }
2.221
2.222 - gmyth_debug ("[%s] Sending command to Myth_HTTP_Server: %s\n", \
2.223 - __FUNCTION__, command->str);
2.224 -
2.225 - /* write bytes to socket */
2.226 - io_status = g_io_channel_write_chars( gmyth_socket->sd_io_ch, \
2.227 - command->str, command->len, &bytes_written, &error );
2.228 -
2.229 - /* try to catch errors */
2.230 - if( (io_status == G_IO_STATUS_ERROR) || ( bytes_written <= 0 ) )
2.231 - {
2.232 - g_warning ("[%s] Error while writing to socket", __FUNCTION__);
2.233 - ret = FALSE;
2.234 - } else if ( bytes_written < command->len )
2.235 - {
2.236 - g_warning ("[%s] Not all data was written socket", __FUNCTION__);
2.237 - ret = FALSE;
2.238 - }
2.239 -
2.240 - io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error );
2.241 -
2.242 - /* not all bytes were sent */
2.243 - if ( ( bytes_written != command->len ) || ( io_status == G_IO_STATUS_ERROR ) )
2.244 - {
2.245 - g_warning ("[%s] Problems when sending data to the socket\n", __FUNCTION__);
2.246 - ret = TRUE;
2.247 - }
2.248 -
2.249 - if ( error != NULL )
2.250 - {
2.251 - g_printerr( "Error found reading data from IO channel");
2.252 - ret = FALSE;
2.253 - g_error_free( error );
2.254 - }
2.255 -
2.256 - return ret;
2.257 + return response;
2.258 }
2.259 -
2.260 -
2.261 -/** Receives an http answer after a gmyth_socket_send_command ().
2.262 - *
2.263 - * @param gmyth_socket The GMythSocket instance.
2.264 - * @return The response received, or NULL if error or nothing was received.
2.265 - */
2.266 -GString* gmyth_http_receive_response(GMythSocket *gmyth_socket)
2.267 -{
2.268 - GIOStatus io_status = G_IO_STATUS_NORMAL;
2.269 - GError* error = NULL;
2.270 - GString *str = NULL;
2.271 - gchar *buff = NULL;
2.272 - GIOCondition io_cond;
2.273 -
2.274 - gsize bytes_read = -1;
2.275 -
2.276 - /* if gmyth_socket == NULL, return NULL */
2.277 - if ( gmyth_socket != NULL )
2.278 - {
2.279 -
2.280 - /* verify if there is data to read */
2.281 - io_cond = g_io_channel_get_buffer_condition (gmyth_socket->sd_io_ch);
2.282 -
2.283 - if ( io_cond == G_IO_OUT )
2.284 - {
2.285 - /* read all data in the buffer */
2.286 - g_io_channel_read_to_end( gmyth_socket->sd_io_ch, &buff, &bytes_read, &error);
2.287 - str = g_string_new(buff);
2.288 - gmyth_debug ( "[%s] Bytes read = %d\n", __FUNCTION__, bytes_read );
2.289 - }
2.290 -
2.291 - if ( ( bytes_read < 0 ) || ( io_status == G_IO_STATUS_ERROR ) || ( error != NULL ))
2.292 - {
2.293 - g_free (buff);
2.294 - g_free (str);
2.295 - g_error_free (error);
2.296 - g_printerr( "[%s] Error found receiving response from the IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message );
2.297 - return NULL;
2.298 - }
2.299 -
2.300 - }
2.301 -
2.302 - /* everything went allright */
2.303 - return str;
2.304 -}
2.305 -
2.306 -/** Send HTTP Command
2.307 - *
2.308 - * @return true or false
2.309 - */
2.310 -GString* gmyth_http_request (GMythHttp *gmyth_http, GString *command)
2.311 -{
2.312 - gmyth_socket_connect (gmyth_http->socket, gmyth_http->backend_info->hostname, 6544);
2.313 -
2.314 - GString *result = NULL;
2.315 - gchar *buffer = NULL;
2.316 -
2.317 - buffer = g_strnfill( BUFLEN, ' ');
2.318 -
2.319 - /* creates header */
2.320 - GString *new_command = gmyth_http_create_header(command);
2.321 -
2.322 - /* sends the command throught the socket */
2.323 - gmyth_http_send_command (gmyth_http->socket, new_command);
2.324 -
2.325 - result = gmyth_http_receive_response (gmyth_http->socket);
2.326 -
2.327 - //if (result != NULL)
2.328 - // gmyth_debug ("[%s] Response received from Myth_HTTP_Server: %s", __FUNCTION__, result->str);
2.329 -
2.330 - gmyth_socket_close_connection (gmyth_http->socket);
2.331 - g_string_free (command, TRUE);
2.332 -
2.333 - return result;
2.334 -}
3.1 --- a/gmyth/src/gmyth_http.h Fri Jan 12 11:58:01 2007 +0000
3.2 +++ b/gmyth/src/gmyth_http.h Fri Jan 12 21:26:30 2007 +0000
3.3 @@ -31,49 +31,34 @@
3.4
3.5 #include <glib-object.h>
3.6
3.7 -#include "gmyth_socket.h"
3.8 +#include <stdio.h>
3.9 +#include <stdlib.h>
3.10 +#include <string.h>
3.11 +#include <stdarg.h>
3.12 +
3.13 #include "gmyth_backendinfo.h"
3.14
3.15 -#define BUFLEN 1024
3.16 +#include <curl/curl.h>
3.17 +#include <curl/types.h>
3.18 +#include <curl/easy.h>
3.19
3.20 G_BEGIN_DECLS
3.21
3.22 -#define GMYTH_HTTP_TYPE (gmyth_http_get_type ())
3.23 -#define GMYTH_HTTP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_HTTP_TYPE, GMythHttp))
3.24 -#define GMYTH_HTTP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_HTTP_TYPE, GMythHttpClass))
3.25 -#define IS_GMYTH_HTTP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_HTTP_TYPE))
3.26 -#define IS_GMYTH_HTTP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_HTTP_TYPE))
3.27 -#define GMYTH_HTTP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_HTTP_TYPE, GMythHttpClass))
3.28 +#define MYTH_PORT_STATUS 6544
3.29 +#define BUFLEN 2048
3.30 +#define TYPE_TEXT_XML 0
3.31 +#define TYPE_FORM_URLENCODED 1
3.32
3.33 -#define MYTH_PORT_STATUS 6544
3.34 +typedef struct _GMythPacket GMythPacket;
3.35
3.36 -typedef struct _GMythHttp GMythHttp;
3.37 -typedef struct _GMythHttpClass GMythHttpClass;
3.38 -
3.39 -struct _GMythHttpClass
3.40 +struct _GMythPacket
3.41 {
3.42 - GObjectClass parent_class;
3.43 -
3.44 - /* callbacks */
3.45 - /* no one for now */
3.46 + GString *response;
3.47 + int type;
3.48 };
3.49
3.50 -struct _GMythHttp
3.51 -{
3.52 - GObject parent;
3.53 -
3.54 - GMythBackendInfo *backend_info;
3.55 - GMythSocket *socket;
3.56 -
3.57 - GString *opt_socket_name; /* socket name (use built-in value) */
3.58 - unsigned int opt_flags; /* connection flags (none) */
3.59 -};
3.60 -
3.61 -
3.62 -GType gmyth_http_get_type (void);
3.63 -
3.64 -GMythHttp* gmyth_http_new ();
3.65 -GString* gmyth_http_request (GMythHttp *gmyth_http, GString *command);
3.66 +GString* gmyth_http_create_command(GString *command, ...);
3.67 +GString *gmyth_http_request (GMythBackendInfo *backend_info, GString *command);
3.68
3.69 G_END_DECLS
3.70
4.1 --- a/gmyth/tests/http.c Fri Jan 12 11:58:01 2007 +0000
4.2 +++ b/gmyth/tests/http.c Fri Jan 12 21:26:30 2007 +0000
4.3 @@ -13,12 +13,10 @@
4.4 gmyth_backend_info_set_hostname (backend_info, "localhost");
4.5 gmyth_backend_info_set_port (backend_info, 6543);
4.6
4.7 - GMythHttp *gmyth_http = gmyth_http_new();
4.8 - gmyth_http->backend_info = backend_info;
4.9 -
4.10 GString *command = g_string_new(argv[1]);
4.11
4.12 - GString *result = gmyth_http_request(gmyth_http, command);
4.13 + GString *new_command = gmyth_http_create_command(command, "ChanId", "1001", "StartTime", "2006-12-20T00:05:00", NULL);
4.14 + GString *result = gmyth_http_request(backend_info, new_command);
4.15
4.16 printf("%s", result->str);
4.17
5.1 --- a/maemo-ui/src/mmyth_epg_grid_widget.c Fri Jan 12 11:58:01 2007 +0000
5.2 +++ b/maemo-ui/src/mmyth_epg_grid_widget.c Fri Jan 12 21:26:30 2007 +0000
5.3 @@ -109,7 +109,7 @@
5.4
5.5 private->DISPLAY_CHANS = MAX_DISPLAY_CHANS;
5.6
5.7 - private->backend_info = gmyth_backend_info_new_full ( "192.168.1.109", "mythtv",
5.8 + private->backend_info = gmyth_backend_info_new_full ( "localhost", "mythtv",
5.9 "mythtv", "mythconverg", 6543 );
5.10
5.11 // TODO: Close the epg and unref it in dispose call
6.1 --- a/maemo-ui/src/mmyth_ui.c Fri Jan 12 11:58:01 2007 +0000
6.2 +++ b/maemo-ui/src/mmyth_ui.c Fri Jan 12 21:26:30 2007 +0000
6.3 @@ -56,7 +56,7 @@
6.4
6.5 mmyth_ui = g_new0 (MMythUi, 1);
6.6
6.7 - mmyth_ui->backend_info = gmyth_backend_info_new_full( "192.168.1.109", "mythtv", "mythtv", "mythconverg", 6543 );
6.8 + mmyth_ui->backend_info = gmyth_backend_info_new_full( "localhost", "mythtv", "mythtv", "mythconverg", 6543 );
6.9
6.10 mmyth_ui->main_window = main_window;
6.11 mmyth_ui->videow = NULL;
7.1 --- a/maemo-ui/src/mmyth_uisettings.c Fri Jan 12 11:58:01 2007 +0000
7.2 +++ b/maemo-ui/src/mmyth_uisettings.c Fri Jan 12 21:26:30 2007 +0000
7.3 @@ -34,7 +34,7 @@
7.4 GtkWidget *label_hostname, *label_dbname;
7.5 GtkWidget *label_username, *label_passwd, *label_port;
7.6
7.7 - backend_info = gmyth_backend_info_new_full( "192.168.1.109", "mythtv",
7.8 + backend_info = gmyth_backend_info_new_full( "localhost", "mythtv",
7.9 "mythtv", "mythconverg", 6543 );
7.10
7.11 settings_dialog = gtk_dialog_new_with_buttons ("Settings",