# HG changeset patch # User morphbr # Date 1168637190 0 # Node ID 91eb7e03b1b13c0edfe5ad89e4dd587308b44409 # Parent 55e1c59ed983e66264de34b35d43c27c865ce9be [svn r269] Changed structure from gmyth_http to use *libcurl*. diff -r 55e1c59ed983 -r 91eb7e03b1b1 gmyth/configure.ac --- a/gmyth/configure.ac Fri Jan 12 11:58:01 2007 +0000 +++ b/gmyth/configure.ac Fri Jan 12 21:26:30 2007 +0000 @@ -142,6 +142,18 @@ AC_SUBST(LIBXML_CFLAGS) AC_SUBST(LIBXML_LIBS) +# Check for libcurl +PKG_CHECK_MODULES(LIBCURL, libcurl, HAVE_LIBCRUL=yes, HAVE_LIBCURL=no) + +# Give error and exit if we don't have libcurl +if test "x$HAVE_LIBCURL" = "xno"; then + AC_MSG_ERROR(you need libcurl installed) +fi + +# make LIBCURL_CFLAGS and LIBCURL_LIBS available +AC_SUBST(LIBCURL_CFLAGS) +AC_SUBST(LIBCURL_LIBS) + # check for gstreamer development files GST_REQUIRED=0.10 diff -r 55e1c59ed983 -r 91eb7e03b1b1 gmyth/src/gmyth_http.c --- a/gmyth/src/gmyth_http.c Fri Jan 12 11:58:01 2007 +0000 +++ b/gmyth/src/gmyth_http.c Fri Jan 12 21:26:30 2007 +0000 @@ -39,232 +39,122 @@ #include "gmyth_debug.h" #include "gmyth_socket.h" -static void gmyth_http_class_init (GMythHttpClass *klass); -static void gmyth_http_init (GMythHttp *object); +struct MemoryStruct +{ + char *memory; + size_t size; +}; -static void gmyth_http_dispose (GObject *object); -static void gmyth_http_finalize (GObject *object); - -G_DEFINE_TYPE(GMythHttp, gmyth_http, G_TYPE_OBJECT) - - -static void gmyth_http_class_init (GMythHttpClass *klass) +/* Aux functions got from libcurl */ +void *myrealloc(void *ptr, size_t size) { - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - gobject_class->dispose = gmyth_http_dispose; - gobject_class->finalize = gmyth_http_finalize; + /* There might be a realloc() out there that doesn't like reallocing + NULL pointers, so we take care of it here */ + if(ptr) + return realloc(ptr, size); + else + return malloc(size); } -static void gmyth_http_init (GMythHttp *gmyth_http) +size_t +WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) { - gmyth_http->backend_info = NULL; - gmyth_http->socket = gmyth_socket_new (MYTH_PORT_STATUS); - + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)data; + + mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1); + if (mem->memory) { + memcpy(&(mem->memory[mem->size]), ptr, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + } + return realsize; } -static void gmyth_http_dispose (GObject *object) +/** Create a String containing the URL with the command + * + * @param command A string with the command + * @param variables Vars to use with their values \ + * MUST FINISH WITH NULL!!! + * @return The response + */ +GString* gmyth_http_create_command(GString *command, ...) { - GMythHttp *gmyth_http = GMYTH_HTTP (object); - - if (gmyth_http->backend_info) - g_object_unref (gmyth_http->backend_info); + va_list args; + va_start(args, command); + char* s = NULL; - if (gmyth_http->socket) - g_object_unref (gmyth_http->socket); - - G_OBJECT_CLASS (gmyth_http_parent_class)->dispose (object); + g_string_append(command, "?"); + + while ( (s = va_arg(args, char *)) != NULL ) + { + g_string_append(command, s); + g_string_append(command, "="); + s = va_arg(args, char *); + g_string_append(command, s); + g_string_append(command, "&"); + } + + + /* TODO: erase this */ + printf("Comando: %s\n", command); + free(s); + + va_end(args); + + return command; } -static void gmyth_http_finalize (GObject *object) -{ - g_signal_handlers_destroy (object); - G_OBJECT_CLASS (gmyth_http_parent_class)->finalize (object); -} - -/** Creates a new instance of GMythHttp. - * - * @return a new instance of GMythHttp. +/** Send HTTP Command and receives the result of it + * + * @return A string with the response from the server */ -GMythHttp* gmyth_http_new () -{ - GMythHttp *http = GMYTH_HTTP (g_object_new(GMYTH_HTTP_TYPE, NULL)); - return http; -} - -/** Creates the Header of the packet. - * - * @param command The string of the command to be sent - * @return String with the header appended to the command - */ -GString * gmyth_http_create_header (GString *command) +GString +*gmyth_http_request (GMythBackendInfo *backend_info, GString *command) { - /* secure len to avoid buffer overflows */ - /* len must be big enough to support the command */ - gsize len = command->len + 2048; - gchar *new_command = g_new0 (gchar, command->len + 2048); - - g_snprintf(new_command, len, - "GET /%s HTTP/1.1\r\n" - "Host: 127.0.0.1:6544\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.8) " - "Gecko/20061025 Firefox/1.5.0.8\r\n" - "Accept: text/xml,application/xml,application/xhtml+xml,text/html;" - "q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n" - "Accept-Language: en-us,en;q=0.5\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Keep-Alive: 300\r\n" - "Connection: keep-alive\r\n" - "\r\n" - , command->str); + size_t size = strlen(backend_info->hostname) + strlen(command->str) + 13; + char *URL = malloc(sizeof(char)*size); + snprintf(URL, size+1, "http://%s:6544/%s", backend_info->hostname, command->str); - GString *new = g_string_new(new_command); - return new; + CURL *curl_handle; + + struct MemoryStruct chunk; + + chunk.memory=NULL; /* we expect realloc(NULL, size) to work */ + chunk.size = 0; /* no data at this point */ + + curl_global_init(CURL_GLOBAL_ALL); + + /* init the curl session */ + curl_handle = curl_easy_init(); + + /* specify URL to get */ + curl_easy_setopt(curl_handle, CURLOPT_URL, URL); + + /* send all data to this function */ + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + + /* we pass our 'chunk' struct to the callback function */ + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); + + /* some servers don't like requests that are made without a user-agent + field, so we provide one */ + curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + + /* get it! */ + curl_easy_perform(curl_handle); + + /* cleanup curl stuff */ + curl_easy_cleanup(curl_handle); + + GString *response = NULL; -} - -/** Removes the Header of the packet. - * - * @param packet The string of the packet - * @return String without the header - */ -GString * gmyth_http_remove_header (GString *packet) -{ -} - -/** Sends a command to the backend. - * - * @param gmyth_socket the GMythSocket instance. - * @param command The string command to be sent. - * @return gboolean If everything went ok - */ -gboolean gmyth_http_send_command(GMythSocket *gmyth_socket, GString *command) -{ - gboolean ret = TRUE; - - GIOStatus io_status = G_IO_STATUS_NORMAL; - GError* error = NULL; - - gsize bytes_written = 0; - - if( command == NULL || ( command->len <= 0 ) || command->str == NULL ) + if(chunk.memory) { - g_warning ("[%s] Invalid NULL command parameter!\n", __FUNCTION__); - return FALSE; + response = g_string_new(chunk.memory); + free(chunk.memory); } - gmyth_debug ("[%s] Sending command to Myth_HTTP_Server: %s\n", \ - __FUNCTION__, command->str); - - /* write bytes to socket */ - io_status = g_io_channel_write_chars( gmyth_socket->sd_io_ch, \ - command->str, command->len, &bytes_written, &error ); - - /* try to catch errors */ - if( (io_status == G_IO_STATUS_ERROR) || ( bytes_written <= 0 ) ) - { - g_warning ("[%s] Error while writing to socket", __FUNCTION__); - ret = FALSE; - } else if ( bytes_written < command->len ) - { - g_warning ("[%s] Not all data was written socket", __FUNCTION__); - ret = FALSE; - } - - io_status = g_io_channel_flush( gmyth_socket->sd_io_ch, &error ); - - /* not all bytes were sent */ - if ( ( bytes_written != command->len ) || ( io_status == G_IO_STATUS_ERROR ) ) - { - g_warning ("[%s] Problems when sending data to the socket\n", __FUNCTION__); - ret = TRUE; - } - - if ( error != NULL ) - { - g_printerr( "Error found reading data from IO channel"); - ret = FALSE; - g_error_free( error ); - } - - return ret; + return response; } - - -/** Receives an http answer after a gmyth_socket_send_command (). - * - * @param gmyth_socket The GMythSocket instance. - * @return The response received, or NULL if error or nothing was received. - */ -GString* gmyth_http_receive_response(GMythSocket *gmyth_socket) -{ - GIOStatus io_status = G_IO_STATUS_NORMAL; - GError* error = NULL; - GString *str = NULL; - gchar *buff = NULL; - GIOCondition io_cond; - - gsize bytes_read = -1; - - /* if gmyth_socket == NULL, return NULL */ - if ( gmyth_socket != NULL ) - { - - /* verify if there is data to read */ - io_cond = g_io_channel_get_buffer_condition (gmyth_socket->sd_io_ch); - - if ( io_cond == G_IO_OUT ) - { - /* read all data in the buffer */ - g_io_channel_read_to_end( gmyth_socket->sd_io_ch, &buff, &bytes_read, &error); - str = g_string_new(buff); - gmyth_debug ( "[%s] Bytes read = %d\n", __FUNCTION__, bytes_read ); - } - - if ( ( bytes_read < 0 ) || ( io_status == G_IO_STATUS_ERROR ) || ( error != NULL )) - { - g_free (buff); - g_free (str); - g_error_free (error); - g_printerr( "[%s] Error found receiving response from the IO channel: (%d, %s)\n", __FUNCTION__, error->code, error->message ); - return NULL; - } - - } - - /* everything went allright */ - return str; -} - -/** Send HTTP Command - * - * @return true or false - */ -GString* gmyth_http_request (GMythHttp *gmyth_http, GString *command) -{ - gmyth_socket_connect (gmyth_http->socket, gmyth_http->backend_info->hostname, 6544); - - GString *result = NULL; - gchar *buffer = NULL; - - buffer = g_strnfill( BUFLEN, ' '); - - /* creates header */ - GString *new_command = gmyth_http_create_header(command); - - /* sends the command throught the socket */ - gmyth_http_send_command (gmyth_http->socket, new_command); - - result = gmyth_http_receive_response (gmyth_http->socket); - - //if (result != NULL) - // gmyth_debug ("[%s] Response received from Myth_HTTP_Server: %s", __FUNCTION__, result->str); - - gmyth_socket_close_connection (gmyth_http->socket); - g_string_free (command, TRUE); - - return result; -} diff -r 55e1c59ed983 -r 91eb7e03b1b1 gmyth/src/gmyth_http.h --- a/gmyth/src/gmyth_http.h Fri Jan 12 11:58:01 2007 +0000 +++ b/gmyth/src/gmyth_http.h Fri Jan 12 21:26:30 2007 +0000 @@ -31,49 +31,34 @@ #include -#include "gmyth_socket.h" +#include +#include +#include +#include + #include "gmyth_backendinfo.h" -#define BUFLEN 1024 +#include +#include +#include G_BEGIN_DECLS -#define GMYTH_HTTP_TYPE (gmyth_http_get_type ()) -#define GMYTH_HTTP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_HTTP_TYPE, GMythHttp)) -#define GMYTH_HTTP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_HTTP_TYPE, GMythHttpClass)) -#define IS_GMYTH_HTTP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_HTTP_TYPE)) -#define IS_GMYTH_HTTP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_HTTP_TYPE)) -#define GMYTH_HTTP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_HTTP_TYPE, GMythHttpClass)) +#define MYTH_PORT_STATUS 6544 +#define BUFLEN 2048 +#define TYPE_TEXT_XML 0 +#define TYPE_FORM_URLENCODED 1 -#define MYTH_PORT_STATUS 6544 +typedef struct _GMythPacket GMythPacket; -typedef struct _GMythHttp GMythHttp; -typedef struct _GMythHttpClass GMythHttpClass; - -struct _GMythHttpClass +struct _GMythPacket { - GObjectClass parent_class; - - /* callbacks */ - /* no one for now */ + GString *response; + int type; }; -struct _GMythHttp -{ - GObject parent; - - GMythBackendInfo *backend_info; - GMythSocket *socket; - - GString *opt_socket_name; /* socket name (use built-in value) */ - unsigned int opt_flags; /* connection flags (none) */ -}; - - -GType gmyth_http_get_type (void); - -GMythHttp* gmyth_http_new (); -GString* gmyth_http_request (GMythHttp *gmyth_http, GString *command); +GString* gmyth_http_create_command(GString *command, ...); +GString *gmyth_http_request (GMythBackendInfo *backend_info, GString *command); G_END_DECLS diff -r 55e1c59ed983 -r 91eb7e03b1b1 gmyth/tests/http.c --- a/gmyth/tests/http.c Fri Jan 12 11:58:01 2007 +0000 +++ b/gmyth/tests/http.c Fri Jan 12 21:26:30 2007 +0000 @@ -13,12 +13,10 @@ gmyth_backend_info_set_hostname (backend_info, "localhost"); gmyth_backend_info_set_port (backend_info, 6543); - GMythHttp *gmyth_http = gmyth_http_new(); - gmyth_http->backend_info = backend_info; - GString *command = g_string_new(argv[1]); - GString *result = gmyth_http_request(gmyth_http, command); + GString *new_command = gmyth_http_create_command(command, "ChanId", "1001", "StartTime", "2006-12-20T00:05:00", NULL); + GString *result = gmyth_http_request(backend_info, new_command); printf("%s", result->str); diff -r 55e1c59ed983 -r 91eb7e03b1b1 maemo-ui/src/mmyth_epg_grid_widget.c --- a/maemo-ui/src/mmyth_epg_grid_widget.c Fri Jan 12 11:58:01 2007 +0000 +++ b/maemo-ui/src/mmyth_epg_grid_widget.c Fri Jan 12 21:26:30 2007 +0000 @@ -109,7 +109,7 @@ private->DISPLAY_CHANS = MAX_DISPLAY_CHANS; - private->backend_info = gmyth_backend_info_new_full ( "192.168.1.109", "mythtv", + private->backend_info = gmyth_backend_info_new_full ( "localhost", "mythtv", "mythtv", "mythconverg", 6543 ); // TODO: Close the epg and unref it in dispose call diff -r 55e1c59ed983 -r 91eb7e03b1b1 maemo-ui/src/mmyth_ui.c --- a/maemo-ui/src/mmyth_ui.c Fri Jan 12 11:58:01 2007 +0000 +++ b/maemo-ui/src/mmyth_ui.c Fri Jan 12 21:26:30 2007 +0000 @@ -56,7 +56,7 @@ mmyth_ui = g_new0 (MMythUi, 1); - mmyth_ui->backend_info = gmyth_backend_info_new_full( "192.168.1.109", "mythtv", "mythtv", "mythconverg", 6543 ); + mmyth_ui->backend_info = gmyth_backend_info_new_full( "localhost", "mythtv", "mythtv", "mythconverg", 6543 ); mmyth_ui->main_window = main_window; mmyth_ui->videow = NULL; diff -r 55e1c59ed983 -r 91eb7e03b1b1 maemo-ui/src/mmyth_uisettings.c --- a/maemo-ui/src/mmyth_uisettings.c Fri Jan 12 11:58:01 2007 +0000 +++ b/maemo-ui/src/mmyth_uisettings.c Fri Jan 12 21:26:30 2007 +0000 @@ -34,7 +34,7 @@ GtkWidget *label_hostname, *label_dbname; GtkWidget *label_username, *label_passwd, *label_port; - backend_info = gmyth_backend_info_new_full( "192.168.1.109", "mythtv", + backend_info = gmyth_backend_info_new_full( "localhost", "mythtv", "mythtv", "mythconverg", 6543 ); settings_dialog = gtk_dialog_new_with_buttons ("Settings",