Ticket #130: libsyncml-libsoup24.diff

File libsyncml-libsoup24.diff, 17.4 kB (added by danw, 10 months ago)

libsoup 2.4 patch

  • libsyncml/transports/http_client_internals.h

    old new  
    2525#include <libsoup/soup-uri.h> 
    2626 
    2727typedef struct SmlTransportHttpClientEnv { 
     28#ifdef HAVE_LIBSOUP22 
    2829        SoupUri *uri; 
     30#else 
     31        SoupURI *uri; 
     32#endif 
    2933        SoupSession *session; 
    3034        SmlTransport *tsp; 
    3135        uint16_t port; 
     
    3539        char *username; 
    3640        char *password; 
    3741        SmlBool connectDone; 
    38         GMutex *cleanupMutex; 
    39         SmlBool shutdown; 
    4042} SmlTransportHttpClientEnv; 
    4143 
    4244#endif //_HTTP_CLIENT_INTERNALS_H_ 
  • libsyncml/transports/http_client.c

    old new  
    3838 */ 
    3939/*@{*/ 
    4040 
     41#ifdef HAVE_LIBSOUP22 
     42#define soup_message_headers_get soup_message_get_header 
     43#define soup_message_headers_append soup_message_add_header 
     44#endif 
     45 
     46#ifdef HAVE_LIBSOUP22 
    4147static void _msgReceived(SoupMessage *msg, gpointer userdata) 
     48#else 
     49static void _msgReceived(SoupSession *session, SoupMessage *msg, gpointer userdata) 
     50#endif 
    4251{ 
    4352        smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, msg, userdata); 
    4453        SmlTransportHttpClientEnv *env = userdata; 
    4554        SmlError *error = NULL; 
    4655 
    47         /* this mutex lock is necessary to avoid conflicts with session shutdown */ 
    48         g_mutex_lock(env->cleanupMutex); 
    49  
    5056        /* handle potential session shutdown */ 
    51         if (env->shutdown
     57        if (msg->status_code == SOUP_STATUS_CANCELLED
    5258        { 
    53                 /* a call to finalize failed because of libsoup 
    54                  * so try to finalize again and ignore the message 
    55                  */ 
    56                 g_mutex_unlock(env->cleanupMutex); 
    57                 smlTrace(TRACE_INTERNAL, "%s - failed finalize detected", __func__); 
    58                 smlTransportHttpClientFinalize(userdata, NULL); 
     59                smlTrace(TRACE_INTERNAL, "%s - ignoring due to shutdown", __func__); 
    5960                smlTrace(TRACE_EXIT, "%s", __func__); 
    6061                return; 
    6162        } 
     
    101102        } 
    102103 
    103104        /* check the header of the received message */ 
    104         const char *header = soup_message_get_header(msg->response_headers, "Content-Type"); 
     105        const char *header = soup_message_headers_get(msg->response_headers, "Content-Type"); 
    105106        smlTrace(TRACE_INTERNAL, "content type: %s", header); 
    106107         
    107108        SmlMimeType mimetype = SML_MIMETYPE_UNKNOWN; 
     
    121122        } 
    122123 
    123124        /* prepare the received message */ 
    124         char *data = smlTryMalloc0(msg->response.length, &error); 
     125        char *data; 
     126        gsize length; 
     127 
     128#ifdef HAVE_LIBSOUP22 
     129        length = msg->response.length; 
     130#else 
     131        length = msg->response_body->length; 
     132#endif 
     133 
     134        data = smlTryMalloc0(length, &error); 
    125135        if (!data) 
    126136                goto error; 
    127         memcpy(data, msg->response.body, msg->response.length); 
    128          
    129         SmlTransportData *tspdata = smlTransportDataNew(data, msg->response.length, mimetype, TRUE, &error); 
     137 
     138#ifdef HAVE_LIBSOUP22 
     139        memcpy(data, msg->response.body, length); 
     140#else 
     141        memcpy(data, msg->response_body->data, length); 
     142#endif 
     143 
     144        SmlTransportData *tspdata = smlTransportDataNew(data, length, mimetype, TRUE, &error); 
    130145        if (!tspdata) 
    131146                goto error_free_data; 
    132147 
     
    135150 
    136151        /* cleanup */ 
    137152        smlTransportDataDeref(tspdata); 
    138         g_mutex_unlock(env->cleanupMutex); 
    139153 
    140154        smlTrace(TRACE_EXIT, "%s", __func__); 
    141155        return; 
     
    144158        g_free(data); 
    145159error: 
    146160        smlTransportReceiveEvent(env->tsp, NULL, SML_TRANSPORT_EVENT_ERROR, NULL, error); 
    147         g_mutex_unlock(env->cleanupMutex); 
    148161        smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error)); 
    149162        smlErrorDeref(&error); 
    150163} 
     
    156169 * account. Usually this is not required because the most 
    157170 * SyncML server manage the authentication via SyncHdr. 
    158171 */ 
     172 
     173#ifdef HAVE_LIBSOUP22 
    159174static void 
    160175_authenticate (SoupSession *session, SoupMessage *msg, 
    161176              const char *auth_type, const char *auth_realm, 
     
    166181        *username = g_strdup(env->username); 
    167182        *password = g_strdup(env->password); 
    168183} 
     184#else 
     185static void 
     186_authenticate (SoupSession *session, SoupMessage *msg, 
     187               SoupAuth *auth, gboolean retrying, gpointer data) 
     188{ 
     189        SmlTransportHttpClientEnv *env = data; 
     190        smlTrace(TRACE_INTERNAL, "%s: authentication via auth_type %s", __func__, soup_auth_get_scheme_name (auth)); 
    169191 
     192        if (!retrying) 
     193                soup_auth_authenticate(auth, env->username, env->password); 
     194} 
     195#endif 
     196 
    170197/*@}*/ 
    171198 
    172199/** 
     
    202229        env->url = g_strdup(config->url); 
    203230        env->proxy = g_strdup(config->proxy); 
    204231        env->connectDone = FALSE; 
    205         env->cleanupMutex = g_mutex_new(); 
    206         env->shutdown = FALSE; 
    207232         
    208233        env->tsp = tsp; 
    209234        if (config->proxy != NULL && strlen(config->proxy) > 0 || 
     
    253278        smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, data, error); 
    254279        smlAssert(data); 
    255280        SmlTransportHttpClientEnv *env = data; 
    256         g_mutex_lock(env->cleanupMutex); 
    257281         
    258282        smlAssert(env->tsp); 
    259283 
    260         env->shutdown = TRUE; 
    261  
    262         // try to stop the session 
    263         // this is a really nasty thing with lipsoup 
    264         if (!soup_session_try_prune_connection(env->session)) 
    265         { 
    266                 // do not touch the env because otherwise _msgReceived can produce crashs 
    267                 // do not signal this as an error because this memory leak is not fixable 
    268                 // if you know what to do then feel free to correct me :) 
    269                 smlTrace(TRACE_EXIT_ERROR, "%s - connection was not pruned", __func__); 
    270                 g_mutex_unlock(env->cleanupMutex); 
    271                 return TRUE; 
    272         } 
     284        soup_session_abort(env->session); 
    273285        g_object_unref(env->session); 
    274286        env->session = NULL; 
    275287 
    276         // if we are here then there are definitely no actions on the road 
    277         // from libsoup session. so it is safe to give up control and cleanup 
    278         g_mutex_unlock(env->cleanupMutex); 
    279         g_mutex_free(env->cleanupMutex); 
    280  
    281288        if (env->data != NULL) 
    282289        { 
    283290                smlTransportDataDeref(env->data); 
     
    312319                goto error; 
    313320        } 
    314321         
     322        const char *content_type; 
    315323        switch (data->type) { 
    316324                case SML_MIMETYPE_XML: 
    317                         soup_message_add_header(msg->request_headers, "Content-Type", SML_ELEMENT_XML); 
    318                         soup_message_add_header(msg->request_headers, "Accept", SML_ELEMENT_XML); 
     325                        content_type = SML_ELEMENT_XML; 
    319326                        break; 
    320327                case SML_MIMETYPE_WBXML: 
    321                         soup_message_add_header(msg->request_headers, "Content-Type", SML_ELEMENT_WBXML); 
    322                         soup_message_add_header(msg->request_headers, "Accept", SML_ELEMENT_WBXML); 
     328                        content_type = SML_ELEMENT_WBXML; 
    323329                        break; 
    324330                case SML_MIMETYPE_SAN: 
    325                         soup_message_add_header(msg->request_headers, "Content-Type", SML_ELEMENT_SAN); 
    326                         soup_message_add_header(msg->request_headers, "Accept", SML_ELEMENT_SAN); 
     331                        content_type = SML_ELEMENT_SAN; 
    327332                default: 
    328333                        smlErrorSet(&error, SML_ERROR_GENERIC, "Unknown Mimetype %d", data->type); 
    329334                        goto error_free_message; 
    330335        } 
    331336 
    332         msg->request.body = data->data; 
    333         msg->request.length = data->size; 
    334         msg->request.owner = SOUP_BUFFER_USER_OWNED; 
     337        soup_message_headers_append(msg->request_headers, "Accept", content_type); 
     338        soup_message_set_request (msg, content_type, 
     339#ifdef HAVE_LIBSOUP22 
     340                                  SOUP_BUFFER_USER_OWNED, 
     341#else 
     342                                  SOUP_MEMORY_TEMPORARY, 
     343#endif 
     344                                  data->data, data->size); 
    335345        env->data = data; 
    336346        smlTransportDataRef(data); 
    337         smlTrace(TRACE_INTERNAL, "%s: data: %s", __func__, g_strdup(msg->request.body)); 
     347        smlTrace(TRACE_INTERNAL, "%s: data: %s", __func__, g_strndup(data->data, data->size)); 
    338348         
    339349        soup_session_queue_message(env->session, msg, _msgReceived, userdata); 
    340350         
  • libsyncml/transports/http_server_internals.h

    old new  
    2121#ifndef _HTTP_SERVER_INTERNALS_H_ 
    2222#define _HTTP_SERVER_INTERNALS_H_ 
    2323 
    24 #include <libsoup/soup-session.h> 
    2524#include <libsoup/soup-uri.h> 
    2625#include <libsoup/soup-server.h> 
     26#ifdef HAVE_LIBSOUP22 
    2727#include <libsoup/soup-server-message.h> 
     28#else 
     29#include <libsoup/soup-message.h> 
     30#endif 
    2831 
    2932typedef struct SmlTransportHttpServerEnv { 
    3033        SoupServer *server; 
  • libsyncml/transports/http_server.c

    old new  
    3636 */ 
    3737/*@{*/ 
    3838 
     39#ifdef HAVE_LIBSOUP22 
    3940static void _server_callback(SoupServerContext *context, SoupMessage *msg, gpointer data) 
    4041{ 
    4142        smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, context, msg, data); 
     
    132133        smlErrorDeref(&error); 
    133134} 
    134135 
     136#else /* !HAVE_LIBSOUP22 */ 
     137 
     138static void _server_callback(SoupServer        *server, 
     139                             SoupMessage       *msg,  
     140                             const char        *path, 
     141                             GHashTable        *query, 
     142                             SoupClientContext *client, 
     143                             gpointer           data) 
     144{ 
     145        smlTrace(TRACE_ENTRY, "%s(%p, %p, %s, %p, %p, %p)", __func__, server, msg, path, query, client, data); 
     146        SmlMimeType mimetype = SML_MIMETYPE_UNKNOWN; 
     147        smlAssert(data); 
     148        SmlTransportHttpServerEnv *env = data; 
     149        SmlError *error = NULL; 
     150         
     151        smlTrace(TRACE_INTERNAL, "%s %s HTTP/1.%d", msg->method, path, soup_message_get_http_version(msg)); 
     152         
     153        if (msg->method != SOUP_METHOD_POST) { 
     154                smlErrorSet(&error, SML_ERROR_NOT_SUPPORTED, "Wrong method"); 
     155                soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); 
     156                goto error; 
     157        } 
     158         
     159        if (env->url && g_strcasecmp(path, env->url)) { 
     160                smlErrorSet(&error, SML_ERROR_FILE_NOT_FOUND, "Not Found"); 
     161                soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); 
     162                goto error; 
     163        } 
     164         
     165        const char *header = soup_message_headers_get(msg->request_headers, "Content-Type"); 
     166        if (header && !g_strncasecmp(header, SML_ELEMENT_XML, strlen(SML_ELEMENT_XML))) 
     167                mimetype = SML_MIMETYPE_XML; 
     168        else if(header && !g_strncasecmp(header, SML_ELEMENT_WBXML, strlen(SML_ELEMENT_WBXML))) 
     169                mimetype = SML_MIMETYPE_WBXML; 
     170        else if(header && !g_strncasecmp(header, SML_ELEMENT_SAN, strlen(SML_ELEMENT_SAN))) 
     171                mimetype = SML_MIMETYPE_SAN; 
     172        else if (header) { 
     173                smlErrorSet(&error, SML_ERROR_GENERIC, "Unknown mimetype"); 
     174                soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); 
     175                goto error; 
     176        } else { 
     177                smlErrorSet(&error, SML_ERROR_GENERIC, "Faulty mimetype"); 
     178                soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); 
     179                goto error; 
     180        } 
     181         
     182        if (!msg->request_body->length) { 
     183                /* Tolerate empty message for now. Http client transport could send empty messages 
     184                   for initialization. Throwing an error here breaks testcase: manager_start_session  
     185                   Empty Message for initialization got introduced with r251. 
     186                   It's not fixed yet if r251 will be the final implementation for http client initalization. */ 
     187 
     188                /* FIXME: why does it do this? This causes a leak in both 
     189                 * the client and the server, because the server never finishes 
     190                 * responding to the request. 
     191                 */ 
     192                soup_server_pause_message(server, msg); 
     193                smlTrace(TRACE_EXIT, "%s (empty message! tolerated for now ...)", __func__); 
     194                return; 
     195 
     196                /* FIXME: Throw an error again if changes in r251 got clarified/fixed. */ 
     197                /* 
     198                smlErrorSet(&error, SML_ERROR_GENERIC, "No data sent"); 
     199                soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); 
     200                goto error; 
     201                */ 
     202        } 
     203         
     204        SmlLink *link = smlLinkNew(env->tsp, msg, &error); 
     205        if (!link) 
     206                goto error; 
     207 
     208        SmlTransportData *tspdata = smlTransportDataNew((char *)msg->request_body->data, msg->request_body->length, mimetype, FALSE, &error); 
     209        if (!tspdata) 
     210                goto error_unref_msg; 
     211         
     212        smlTransportReceiveEvent(env->tsp, link, SML_TRANSPORT_EVENT_DATA, tspdata, NULL); 
     213         
     214        smlLinkDeref(link); 
     215        smlTransportDataDeref(tspdata); 
     216         
     217        soup_server_pause_message(server, msg); 
     218         
     219        smlTrace(TRACE_EXIT, "%s", __func__); 
     220        return; 
     221 
     222error_unref_msg: 
     223        smlLinkDeref(link); 
     224error: 
     225        smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error)); 
     226        smlErrorDeref(&error); 
     227} 
     228 
     229#endif /* HAVE_LIBSOUP22 */ 
     230 
    135231/*@}*/ 
    136232 
    137233/** 
     
    181277                goto error_free_env; 
    182278        } 
    183279         
     280#ifdef HAVE_LIBSOUP22 
    184281        soup_server_add_handler(env->server, NULL, NULL, _server_callback, NULL, env); 
     282#else 
     283        soup_server_add_handler(env->server, NULL, _server_callback, env, NULL); 
     284#endif 
    185285         
    186286        soup_server_run_async(env->server); 
    187287         
     
    206306        smlAssert(env->tsp); 
    207307         
    208308        soup_server_quit(env->server); 
    209         // g_object_unref(env->server); 
     309        g_object_unref(env->server); 
    210310         
    211311        g_free(env->url); 
    212312        g_free(env->interface); 
     
    230330        if (error) 
    231331                goto error_free_message; 
    232332 
    233         // duplicate the data because sometimes data is freed to early 
    234         char *soupcopy = (char *) smlTryMalloc0(data->size, &error); 
    235         if (error) 
    236                 goto error_free_message; 
    237         memcpy(soupcopy, data->data, data->size); 
    238  
    239333        soup_message_set_status (msg, SOUP_STATUS_OK); 
     334#ifdef HAVE_LIBSOUP22 
    240335        soup_server_message_set_encoding (SOUP_SERVER_MESSAGE(msg), SOUP_TRANSFER_CONTENT_LENGTH); 
     336#endif 
    241337 
     338        const char *content_type; 
    242339        switch (data->type) { 
    243340                case SML_MIMETYPE_XML: 
    244                         soup_message_add_header(msg->response_headers, "Accept", "application/vnd.syncml+xml"); 
    245                         soup_message_set_response (msg, "application/vnd.syncml+xml", SOUP_BUFFER_SYSTEM_OWNED, 
    246                                                 soupcopy, data->size); 
     341                        content_type = "application/vnd.syncml+xml"; 
    247342                        break; 
    248343                case SML_MIMETYPE_WBXML: 
    249                         soup_message_add_header(msg->response_headers, "Accept", "application/vnd.syncml+wbxml"); 
    250                         soup_message_set_response (msg, "application/vnd.syncml+wbxml", SOUP_BUFFER_SYSTEM_OWNED, 
    251                                                 soupcopy, data->size); 
     344                        content_type = "application/vnd.syncml+wbxml"; 
    252345                        break; 
    253346                default: 
    254347                        smlErrorSet(&error, SML_ERROR_GENERIC, "Unknown Mimetype"); 
    255348                        goto error_free_message; 
    256349        } 
    257350         
     351        /* FIXME: Why do we add Accept to the response headers? Accept 
     352         * is only defined as a request header. Is this just a bug? 
     353         */ 
     354 
     355#ifdef HAVE_LIBSOUP22 
     356        soup_message_add_header(msg->response_headers, "Accept", content_type); 
     357        // duplicate the data because sometimes data is freed to early 
     358        char *soupcopy = (char *) smlTryMalloc0(data->size, &error); 
     359        if (error) 
     360                goto error_free_message; 
     361        memcpy(soupcopy, data->data, data->size); 
     362        soup_message_set_response (msg, "application/vnd.syncml+xml", SOUP_BUFFER_SYSTEM_OWNED, 
     363                                   soupcopy, data->size); 
    258364        soup_message_io_unpause(msg); 
     365#else 
     366        soup_message_headers_append(msg->response_headers, "Accept", content_type); 
     367        soup_message_set_response(msg, "application/vnd.syncml+xml", 
     368                                  SOUP_MEMORY_COPY, data->data, data->size); 
     369        soup_server_unpause_message(env->server, msg); 
     370#endif 
    259371 
    260         // FIXME: the documentation of libsoup never show an example with such a call 
    261         // FIXME: msg is perhaps in use by libsoup because this is asynchronous I/O 
    262         // g_object_unref(msg); 
    263          
    264372        smlTrace(TRACE_EXIT, "%s", __func__); 
    265373        return; 
    266374         
     
    270378        else 
    271379                soup_message_set_status_full(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, smlErrorPrint(&error)); 
    272380 
     381#ifdef HAVE_LIBSOUP22 
    273382        soup_server_message_set_encoding (SOUP_SERVER_MESSAGE (msg), SOUP_TRANSFER_CONTENT_LENGTH); 
    274383        soup_message_io_unpause(msg); 
     384#else 
     385        soup_server_unpause_message(env->server, msg); 
     386#endif 
    275387 
    276388        // g_object_unref(msg); 
    277389        smlErrorDeref(&error); 
  • CMakeLists.txt

    old new  
    4747 
    4848# find requirements 
    4949SET ( OPENOBEX_MIN_VERSION "1.1" ) 
    50 SET ( LIBSOUP2_MIN_VERSION "2.2.91" ) 
     50SET ( LIBSOUP22_MIN_VERSION "2.2.91" ) 
     51SET ( LIBSOUP24_MIN_VERSION "2.3.0.1" ) 
    5152#SET ( LIBWBXML2_MIN_VERSION "0.9.0" ) 
    5253#SET ( BLUEZ_MIN_VERSION "3.19" ) 
    5354 
  • config.h.cmake

    old new  
    66/* Http Transport */ 
    77#cmakedefine ENABLE_HTTP 
    88 
     9/* libsoup version in use */ 
     10#cmakedefine HAVE_LIBSOUP22 
     11#cmakedefine HAVE_LIBSOUP24 
     12 
    913/* Obex Transport */ 
    1014#cmakedefine ENABLE_OBEX 
    1115 
  • cmake/modules/FindLibSoup2.cmake

    old new  
    22# Find libsoup headers, libraries and the answer to all questions. 
    33# 
    44#  LIBSOUP2_FOUND               True if libsoup got found 
    5 #  LIBSOUP2_INCLUDE_DIRS        Location of libsoup headers  
     5#  LIBSOUP2_INCLUDE_DIRS        Location of libsoup headers  
    66#  LIBSOUP2_LIBRARIES           List of libaries to use libsoup 
    77# 
    88# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de> 
     
    2121        SET( _pkgconfig_REQUIRED "" )    
    2222ENDIF ( LibSoup2_FIND_REQUIRED ) 
    2323 
    24 IF ( LIBSOUP2_MIN_VERSION ) 
    25         PKG_SEARCH_MODULE( LIBSOUP2 ${_pkgconfig_REQUIRED} libsoup-2.2>=${LIBSOUP2_MIN_VERSION} libsoup2>=${LIBSOUP2_MIN_VERSION} ) 
    26 ELSE ( LIBSOUP2_MIN_VERSION ) 
    27         PKG_SEARCH_MODULE( LIBSOUP2 ${_pkgconfig_REQUIRED} libsoup-2.2 libsoup2 ) 
    28 ENDIF ( LIBSOUP2_MIN_VERSION ) 
     24IF ( LIBSOUP24_MIN_VERSION ) 
     25        PKG_SEARCH_MODULE( LIBSOUP2 ${_pkgconfig_REQUIRED} libsoup-2.4>=${LIBSOUP24_MIN_VERSION} libsoup2>=${LIBSOUP24_MIN_VERSION} ) 
     26ELSE ( LIBSOUP24_MIN_VERSION ) 
     27        PKG_SEARCH_MODULE( LIBSOUP2 ${_pkgconfig_REQUIRED} libsoup-2.4 libsoup2 ) 
     28ENDIF ( LIBSOUP24_MIN_VERSION ) 
    2929 
     30IF ( LIBSOUP2_FOUND ) 
     31        OPTION ( HAVE_LIBSOUP24 "building with libsoup 2.4" ON ) 
     32        OPTION ( HAVE_LIBSOUP22 "building with libsoup 2.2" OFF ) 
     33ELSE ( LIBSOUP2_FOUND ) 
     34        IF ( LIBSOUP22_MIN_VERSION ) 
     35                PKG_SEARCH_MODULE( LIBSOUP2 ${_pkgconfig_REQUIRED} libsoup-2.2>=${LIBSOUP22_MIN_VERSION} libsoup2>=${LIBSOUP22_MIN_VERSION} ) 
     36        ELSE ( LIBSOUP22_MIN_VERSION ) 
     37                PKG_SEARCH_MODULE( LIBSOUP2 ${_pkgconfig_REQUIRED} libsoup-2.2 libsoup2 ) 
     38        ENDIF ( LIBSOUP22_MIN_VERSION ) 
    3039 
     40        IF ( LIBSOUP2_FOUND ) 
     41                SET ( HAVE_LIBSOUP24 OFF ) 
     42                SET ( HAVE_LIBSOUP22 ON ) 
     43        ENDIF ( LIBSOUP2_FOUND ) 
     44ENDIF ( LIBSOUP2_FOUND ) 
     45 
    3146IF( NOT LIBSOUP2_FOUND AND NOT PKG_CONFIG_FOUND ) 
    3247 
    3348        FIND_PATH( _libsoup2_include_DIR libsoup/soup.h PATH_SUFFIXES libsoup libsoup-2.2 )