gmyth/src/gmyth_http.c
author morphbr
Mon Jan 15 15:01:29 2007 +0000 (2007-01-15)
branchtrunk
changeset 270 bb8a8b1c449d
parent 268 91eb7e03b1b1
child 300 01d60f80fa52
permissions -rw-r--r--
[svn r271] Updated config files to completely support libcurl
     1 /**
     2  * GMyth Library
     3  *
     4  * @file gmyth/gmyth_http.c
     5  * 
     6  * @brief <p> GMythHttp class provides a wrapper to access
     7  * data from the database using http+xml
     8  *
     9  * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    10  * @author Artur Duque de Souza <@indt.org.br>
    11  *
    12  */
    13 /*
    14  * 
    15  * This program is free software; you can redistribute it and/or modify
    16  * it under the terms of the GNU Lesser General Public License as published by
    17  * the Free Software Foundation; either version 2 of the License, or
    18  * (at your option) any later version.
    19  *
    20  * This program is distributed in the hope that it will be useful,
    21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    23  * GNU General Public License for more details.
    24  *
    25  * You should have received a copy of the GNU Lesser General Public License
    26  * along with this program; if not, write to the Free Software
    27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    28  */
    29  
    30 #ifdef HAVE_CONFIG_H
    31 #include "config.h"
    32 #endif
    33 
    34 #include <assert.h>
    35 #include <libxml/parser.h>
    36 #include <libxml/tree.h>
    37 
    38 #include "gmyth_http.h"
    39 #include "gmyth_debug.h"
    40 #include "gmyth_socket.h"
    41 
    42 struct MemoryStruct 
    43 {
    44   char *memory;
    45   size_t size;
    46 };
    47 
    48 /* Aux functions got from libcurl */
    49 void *myrealloc(void *ptr, size_t size)
    50 {
    51     /* There might be a realloc() out there that doesn't like reallocing
    52         NULL pointers, so we take care of it here */
    53     if(ptr)
    54         return realloc(ptr, size);
    55     else
    56         return malloc(size);
    57 }
    58 
    59 size_t
    60 WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
    61 {
    62   size_t realsize = size * nmemb;
    63   struct MemoryStruct *mem = (struct MemoryStruct *)data;
    64 
    65   mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
    66   if (mem->memory) {
    67     memcpy(&(mem->memory[mem->size]), ptr, realsize);
    68     mem->size += realsize;
    69     mem->memory[mem->size] = 0;
    70   }
    71   return realsize;
    72 }
    73 
    74 /** Create a String containing the URL with the command
    75  *
    76  * @param command A string with the command
    77  * @param variables Vars to use with their values \
    78  *                    MUST FINISH WITH NULL!!!
    79  * @return The response
    80  */
    81 GString* gmyth_http_create_command(GString *command, ...)
    82 {
    83     va_list args;
    84     va_start(args, command);
    85     char* s = NULL;
    86 
    87     g_string_append(command, "?");
    88 
    89     /* Sintax: var, value */
    90     while ( (s = va_arg(args, char *)) != NULL ) 
    91     {
    92         g_string_append(command, s);
    93         g_string_append(command, "=");
    94         s = va_arg(args, char *);
    95         g_string_append(command, s);
    96         g_string_append(command, "&");
    97     }
    98 
    99     free(s);
   100     va_end(args);
   101 
   102     return command;
   103 }
   104 
   105 /** Send HTTP Command and receives the result of it
   106  *
   107  * @return A string with the response from the server
   108  *          NULL if there is no response.
   109  */
   110 GString 
   111 *gmyth_http_request (GMythBackendInfo *backend_info, GString *command)
   112 {
   113 
   114     LIBXML_TEST_VERSION
   115 
   116     size_t size = strlen(backend_info->hostname) + strlen(command->str) + 13;
   117     char *URL = malloc(sizeof(char)*size);
   118     snprintf(URL, size+1, "http://%s:6544/%s", backend_info->hostname, command->str);     
   119 
   120     CURL *curl_handle;
   121     
   122     struct MemoryStruct chunk;
   123     
   124     chunk.memory=NULL; /* we expect realloc(NULL, size) to work */
   125     chunk.size = 0;    /* no data at this point */
   126     
   127     curl_global_init(CURL_GLOBAL_ALL);
   128     
   129     /* init the curl session */
   130     curl_handle = curl_easy_init();
   131     
   132     /* specify URL to get */
   133     curl_easy_setopt(curl_handle, CURLOPT_URL, URL);
   134     
   135     /* send all data to this function  */
   136     curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
   137     
   138     /* we pass our 'chunk' struct to the callback function */
   139     curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
   140     
   141     /* some servers don't like requests that are made without a user-agent
   142         field, so we provide one */
   143     curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
   144     
   145     /* get it! */
   146     curl_easy_perform(curl_handle);
   147     
   148     /* cleanup curl stuff */
   149     curl_easy_cleanup(curl_handle);
   150     
   151     GString *response = NULL;
   152 
   153     if(chunk.memory)
   154     {
   155         response = g_string_new(chunk.memory);
   156         free(chunk.memory);
   157     }
   158 
   159     return response;
   160 }