void fetch_resource_list_recursive(const char *uri, const char *curi)
{
    int ret = 0;
    ne_propfind_handler *hdl = NULL;
    ne_request *request = NULL;
    const char *content_type = NULL;
    const ne_status *req_status = NULL;
    int depth = NE_DEPTH_INFINITE;

    DEBUG_WEBDAV("fetch_resource_list_recursive Starting recursive propfind %s %s", uri, curi);

    /* do a propfind request and parse the results in the results function, set as callback */
    hdl = ne_propfind_create(dav_session.ctx, curi, depth);

    if(hdl) {
        ret = ne_propfind_named(hdl, ls_props, propfind_results_recursive, (void*)curi);
        request = ne_propfind_get_request( hdl );
        req_status = ne_get_status( request );
    }

    if( ret == NE_OK ) {
        /* Check the request status. */
        if( req_status && req_status->klass != 2 ) {
            set_errno_from_http_errcode(req_status->code);
            DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code,
                         req_status->reason_phrase);
            ret = NE_CONNECT;
            set_error_message(req_status->reason_phrase);
        }
        DEBUG_WEBDAV("Recursive propfind result code %d.", req_status ? req_status->code : 0);
    } else {
        if( ret == NE_ERROR && req_status->code == 404) {
            errno = ENOENT;
        } else {
            set_errno_from_neon_errcode(ret);
        }
    }

    if( ret == NE_OK ) {
        /* Check the content type. If the server has a problem, ie. database is gone or such,
         * the content type is not xml but a html error message. Stop on processing if it's
         * not XML.
         * FIXME: Generate user error message from the reply content.
         */
        content_type =  ne_get_response_header( request, "Content-Type" );
        if( !(content_type && c_streq(content_type, "application/xml; charset=utf-8") ) ) {
            DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.",
                         content_type ?  content_type: "<empty>");
            errno = ERRNO_WRONG_CONTENT;
            set_error_message("Server error: PROPFIND reply is not XML formatted!");
            ret = NE_CONNECT;
        }
    }

    if( ret != NE_OK ) {
        const char *err = NULL;

        err = ne_get_error( dav_session.ctx );
        DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>");
    }

    if( hdl )
        ne_propfind_destroy(hdl);

    if( ret != NE_OK ) {
        return;
    }

    return;
}
Beispiel #2
0
static int fetch_resource_list( const char *uri,
                                int depth,
                                struct listdir_context *fetchCtx )
{
  int ret = 0;
  ne_propfind_handler *hdl = NULL;
  ne_request *request = NULL;
  const char *content_type = NULL;
  char *curi = NULL;
  const ne_status *req_status = NULL;

  curi = _cleanPath( uri );

  if (!fetchCtx) {
    errno = ENOMEM;
    SAFE_FREE(curi);
    return -1;
  }
  fetchCtx->list = NULL;
  fetchCtx->target = curi;
  fetchCtx->currResource = NULL;

  /* do a propfind request and parse the results in the results function, set as callback */
  hdl = ne_propfind_create(dav_session.ctx, curi, depth);

  if(hdl) {
    ret = ne_propfind_named(hdl, ls_props, results, fetchCtx);
    request = ne_propfind_get_request( hdl );
    req_status = ne_get_status( request );
  }

  if( ret == NE_OK ) {
    fetchCtx->currResource = fetchCtx->list;
    /* Check the request status. */
    if( req_status && req_status->klass != 2 ) {
      set_errno_from_http_errcode(req_status->code);
      DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code,
                   req_status->reason_phrase);
      ret = NE_CONNECT;
      set_error_message(req_status->reason_phrase);
    }
    DEBUG_WEBDAV("Simple propfind result code %d.", req_status ? req_status->code : -1);
  } else {
    if( ret == NE_ERROR && req_status->code == 404) {
      errno = ENOENT;
    } else {
      set_errno_from_neon_errcode(ret);
    }
  }

  if( ret == NE_OK ) {
    /* Check the content type. If the server has a problem, ie. database is gone or such,
        * the content type is not xml but a html error message. Stop on processing if it's
        * not XML.
        * FIXME: Generate user error message from the reply content.
        */
    content_type =  ne_get_response_header( request, "Content-Type" );
    if( !(content_type && c_streq(content_type, "application/xml; charset=utf-8") ) ) {
      DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.",
                   content_type ?  content_type: "<empty>");
      errno = ERRNO_WRONG_CONTENT;
      set_error_message("Server error: PROPFIND reply is not XML formatted!");
      ret = NE_CONNECT;
    }
  }
#ifndef NDEBUG
  if( ret != NE_OK ) {
    const char *err = ne_get_error(dav_session.ctx);
    DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>");
  }
#endif /* NDEBUG */

  if (hdl != NULL) {
    ne_propfind_destroy(hdl);
  }

#ifndef NDEBUG
  if (ret == NE_REDIRECT) {
    const ne_uri *redir_ne_uri = ne_redirect_location(dav_session.ctx);
    if (redir_ne_uri) {
      char *redir_uri = ne_uri_unparse(redir_ne_uri);
      DEBUG_WEBDAV("Permanently moved to %s", redir_uri);
    }
  }
#endif /* NDEBUG */

  if( ret != NE_OK ) {
    free_fetchCtx(fetchCtx);
    return -1;
  }

  return 0;
}
Beispiel #3
0
/*
 * fetches a resource list from the WebDAV server. This is equivalent to list dir.
 */
static struct listdir_context *fetch_resource_list(const char *uri, int depth)
{
    struct listdir_context *fetchCtx;
    int ret = 0;
    ne_propfind_handler *hdl = NULL;
    ne_request *request = NULL;
    const char *content_type = NULL;
    char *curi = NULL;
    const ne_status *req_status = NULL;

    curi = _cleanPath( uri );

    /* The old legacy one-level PROPFIND cache. Also gets filled
       by the recursive cache if 'infinity' did not suceed. */
    if (propfind_cache) {
        if (c_streq(curi, propfind_cache->target)) {
            DEBUG_WEBDAV("fetch_resource_list Using simple PROPFIND cache %s", curi);
            propfind_cache->ref++;
            SAFE_FREE(curi);
            return propfind_cache;
        }
    }

    fetchCtx = c_malloc( sizeof( struct listdir_context ));
    if (!fetchCtx) {
        errno = ENOMEM;
        SAFE_FREE(curi);
        return NULL;
    }
    fetchCtx->list = NULL;
    fetchCtx->target = curi;
    fetchCtx->currResource = NULL;
    fetchCtx->ref = 1;

    /* do a propfind request and parse the results in the results function, set as callback */
    hdl = ne_propfind_create(dav_session.ctx, curi, depth);

    if(hdl) {
        ret = ne_propfind_named(hdl, ls_props, results, fetchCtx);
        request = ne_propfind_get_request( hdl );
        req_status = ne_get_status( request );
    }

    if( ret == NE_OK ) {
        fetchCtx->currResource = fetchCtx->list;
        /* Check the request status. */
        if( req_status && req_status->klass != 2 ) {
            set_errno_from_http_errcode(req_status->code);
            DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code,
                         req_status->reason_phrase);
            ret = NE_CONNECT;
            set_error_message(req_status->reason_phrase);
            oc_notify_progress( uri, CSYNC_NOTIFY_ERROR,
                                req_status->code,
                                (intptr_t)(req_status->reason_phrase) );
        }
        DEBUG_WEBDAV("Simple propfind result code %d.", req_status->code);
    } else {
        if( ret == NE_ERROR && req_status->code == 404) {
            errno = ENOENT;
        } else {
            set_errno_from_neon_errcode(ret);
        }
    }

    if( ret == NE_OK ) {
        /* Check the content type. If the server has a problem, ie. database is gone or such,
         * the content type is not xml but a html error message. Stop on processing if it's
         * not XML.
         * FIXME: Generate user error message from the reply content.
         */
        content_type =  ne_get_response_header( request, "Content-Type" );
        if( !(content_type && c_streq(content_type, "application/xml; charset=utf-8") ) ) {
            DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.",
                         content_type ?  content_type: "<empty>");
            errno = ERRNO_WRONG_CONTENT;
            set_error_message("Server error: PROPFIND reply is not XML formatted!");
            ret = NE_CONNECT;
        }
    }

    if( ret != NE_OK ) {
        const char *err = NULL;
        set_errno_from_neon_errcode(ret);

        err = ne_get_error( dav_session.ctx );
        if(err) {
            set_error_message(err);
        }
        DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>");
    }

    if( hdl )
        ne_propfind_destroy(hdl);

    if( ret != NE_OK ) {
        free_fetchCtx(fetchCtx);
        return NULL;
    }

    free_fetchCtx(propfind_cache);
    propfind_cache = fetchCtx;
    propfind_cache->ref++;
    return fetchCtx;
}