Esempio n. 1
0
void get(const StringSlice& url, WriteTarget out) {
    static int inited = ne_sock_init();
    if (inited != 0) {
        throw Exception("ne_sock_init()");
    }

    CString cstr(url);
    ne_uri  uri = {};
    if (ne_uri_parse(cstr.data(), &uri)) {
        throw Exception("ne_uri_parse()");
    }
    if (uri.port == 0) {
        uri.port = ne_uri_defaultport(uri.scheme);
    }
    unique_ptr<ne_uri, decltype(&ne_uri_free)>            uri_free(&uri, ne_uri_free);
    unique_ptr<ne_session, decltype(&ne_session_destroy)> sess(
            ne_session_create(uri.scheme, uri.host, uri.port), ne_session_destroy);

    unique_ptr<ne_request, decltype(&ne_request_destroy)> req(
            ne_request_create(sess.get(), "GET", uri.path), ne_request_destroy);

    ne_userdata userdata = {out};
    ne_add_response_body_reader(req.get(), accept, reader, &userdata);

    auto err = ne_request_dispatch(req.get());
    if (err != NE_OK) {
        throw Exception("ne_request_dispatch()");
    }
    auto* st = ne_get_status(req.get());
    if (st->code != 200) {
        throw Exception(st->code);
    }
}
Esempio n. 2
0
int ne_mkcol(ne_session *sess, const char *uri) 
{
    ne_request *req;
    char *real_uri;
    int ret;

    if (ne_path_has_trailing_slash(uri)) {
	real_uri = ne_strdup(uri);
    } else {
	real_uri = ne_concat(uri, "/", NULL);
    }

    req = ne_request_create(sess, "MKCOL", real_uri);

#ifdef NE_HAVE_DAV
    ne_lock_using_resource(req, real_uri, 0);
    ne_lock_using_parent(req, real_uri);
#endif
    
    ret = ne_simple_request(sess, req);

    ne_free(real_uri);

    return ret;
}
Esempio n. 3
0
static int get_range_common(ne_session *sess, const char *req_uri,
                            const char *brange, char *buf, ssize_t *bytes_read)

{
    ne_request *req = ne_request_create(sess, "GET", req_uri);
    const ne_status *status;
    int ret;

    ne_add_request_header(req, "Range", brange);
    ne_add_request_header(req, "Accept-Ranges", "bytes");

    ret = dispatch_to_buffer(sess, req, buf, brange, bytes_read);

    status = ne_get_status(req);

    if (ret == NE_OK && status->code == 416) {
        /* connection is terminated too early with Apache/1.3, so we check
         * this even if ret == NE_ERROR... */
        ne_set_error(sess, "Range is not satisfiable");
        ret = NE_ERROR;
    }
    else if (ret == NE_OK) {
        if (status->klass == 2 && status->code != 206) {
            ne_set_error(sess, "Resource does not support ranged GET requests");
            ret = NE_ERROR;
        }
        else if (status->klass != 2) {
            ret = NE_ERROR;
        }
    }

    ne_request_destroy(req);

    return ret;
}
Esempio n. 4
0
/* PUT's from fd to URI */
int ne_put(ne_session *sess, const char *uri, int fd) 
{
    ne_request *req;
    struct stat st;
    int ret;

    if (fstat(fd, &st)) {
        int errnum = errno;
        char buf[200];

        ne_set_error(sess, _("Could not determine file size: %s"),
                     ne_strerror(errnum, buf, sizeof buf));
        return NE_ERROR;
    }
    
    req = ne_request_create(sess, "PUT", uri);

#ifdef NE_HAVE_DAV
    ne_lock_using_resource(req, uri, 0);
    ne_lock_using_parent(req, uri);
#endif

    ne_set_request_body_fd(req, fd, 0, st.st_size);
	
    ret = ne_request_dispatch(req);
    
    if (ret == NE_OK && ne_get_status(req)->klass != 2)
	ret = NE_ERROR;

    ne_request_destroy(req);

    return ret;
}
Esempio n. 5
0
int ne_getmodtime(ne_session *sess, const char *uri, time_t *modtime)
{
    ne_request *req = ne_request_create(sess, "HEAD", uri);
    const char *value;
    int ret;

    ret = ne_request_dispatch(req);

    value = ne_get_response_header(req, "Last-Modified");

    if (ret == NE_OK && ne_get_status(req)->klass != 2) {
	*modtime = -1;
	ret = NE_ERROR;
    }
    else if (value) {
        *modtime = ne_httpdate_parse(value);
    }
    else {
        *modtime = -1;
    }

    ne_request_destroy(req);

    return ret;
}
Esempio n. 6
0
static int copy_or_move(ne_session *sess, int is_move, int overwrite,
			int depth, const char *src, const char *dest) 
{
    ne_request *req = ne_request_create( sess, is_move?"MOVE":"COPY", src );

    /* 2518 S8.9.2 says only use Depth: infinity with MOVE. */
    if (!is_move) {
	ne_add_depth_header(req, depth);
    }

#ifdef NE_HAVE_DAV
    if (is_move) {
	ne_lock_using_resource(req, src, NE_DEPTH_INFINITE);
    }
    ne_lock_using_resource(req, dest, NE_DEPTH_INFINITE);
    /* And we need to be able to add members to the destination's parent */
    ne_lock_using_parent(req, dest);
#endif

    ne_print_request_header(req, "Destination", "%s://%s%s", 
			      ne_get_scheme(sess), 
			      ne_get_server_hostport(sess), dest);
    
    ne_add_request_header(req, "Overwrite", overwrite?"T":"F");

    return ne_simple_request(sess, req);
}
Esempio n. 7
0
static Hbf_State _hbf_transfer_no_chunk(ne_session *session, hbf_transfer_t *transfer, const char *verb) {
    int res;
    const ne_status* req_status;

    ne_request *req = ne_request_create(session, verb ? verb : "PUT", transfer->url);
    if (!req)
        return HBF_MEMORY_FAIL;

    ne_add_request_header( req, "Content-Type", "application/octet-stream");

    ne_set_request_body_fd(req, transfer->fd, 0, transfer->stat_size);
    DEBUG_HBF("HBF: chunking not supported for %s", transfer->url);
    res = ne_request_dispatch(req);
    req_status = ne_get_status( req );

    if (res == NE_OK && req_status->klass == 2) {
        ne_request_destroy(req);
        return HBF_SUCCESS;
    }

    if( transfer->error_string ) free( transfer->error_string );
    transfer->error_string = strdup( ne_get_error(session) );
    transfer->status_code = req_status->code;
    ne_request_destroy(req);
    return HBF_FAIL;
}
Esempio n. 8
0
static int large_get(void)
{
    ne_request *req = ne_request_create(i_session, "GET", path);
    char buffer[BLOCKSIZE], origin[BLOCKSIZE * 2];
    long long progress = 0;
    ssize_t offset = 0;
    ssize_t bytes;

    memcpy(origin, block, BLOCKSIZE);
    memcpy(origin + BLOCKSIZE, block, BLOCKSIZE);

    ONNREQ("begin large GET request", ne_begin_request(req));

    ONNREQ("failed GET request", ne_get_status(req)->klass != 2);

    while ((bytes = ne_read_response_block(req, buffer, BLOCKSIZE)) > 0) {
        ONV(memcmp(origin + offset, buffer, bytes),
            ("byte mismatch at %" NE_FMT_LONG_LONG, progress));
        offset = (offset + bytes) % BLOCKSIZE;
        progress += bytes;
    }

    ONNREQ("failed reading GET response", bytes < 0);

    ONNREQ("end large GET request", ne_end_request(req));

    ne_request_destroy(req);
    return OK;
}
Esempio n. 9
0
static int netxml_get_page(const char *page)
{
	int		ret = NE_ERROR;
	ne_request	*request;
	ne_xml_parser	*parser;

	upsdebugx(2, "%s: %s", __func__, (page != NULL)?page:"(null)");

	if (page != NULL) {
		request = ne_request_create(session, "GET", page);

		parser = ne_xml_create();

		ne_xml_push_handler(parser, subdriver->startelm_cb, subdriver->cdata_cb, subdriver->endelm_cb, NULL);

		ret = netxml_dispatch_request(request, parser);

		if (ret) {
			upsdebugx(2, "%s: %s", __func__, ne_get_error(session));
		}

		ne_xml_destroy(parser);
		ne_request_destroy(request);
	}
	return ret;
}
Esempio n. 10
0
char*
create_rawx_request_common(ne_request **req, ne_request_param_t *param, GError **err)
{
	ne_request *request = NULL;
	char str_req_id[LIMIT_LENGTH_REQID];

	if (NULL == param->session || NULL == param->method || NULL == param->cPath) {
		GSETERROR(err, "Invalid parameter");
		*req = NULL;
		return NULL;
	}

	if (NULL == (request = ne_request_create (param->session, param->method, param->cPath))) {
		GSETERROR(err, "cannot create a new WebDAV request (%s)", ne_get_error(param->session));
		*req = NULL;
		return NULL;
	}

	/* add additionnal headers */
	ne_add_request_header  (request, RAWX_HEADER_PREFIX "container-id", param->containerid);
	ne_add_request_header  (request, RAWX_HEADER_PREFIX "content-path", param->contentpath);
	ne_print_request_header(request, RAWX_HEADER_PREFIX "content-size", "%"G_GINT64_FORMAT, param->contentsize);
	ne_print_request_header(request, RAWX_HEADER_PREFIX "content-chunksnb", "%u", param->chunknb);
	ne_print_request_header(request, RAWX_HEADER_PREFIX "chunk-pos",    "%u", param->chunkpos);
	ne_print_request_header(request, RAWX_HEADER_PREFIX "chunk-size",   "%"G_GINT64_FORMAT, param->chunksize);

	/* Add request header */
	add_req_id_header(request, str_req_id, sizeof(str_req_id)-1);

	*req = request;
	return g_strdup(str_req_id);
}
Esempio n. 11
0
int any_request(ne_session *sess, const char *uri)
{
    ne_request *req = ne_request_create(sess, "GET", uri);
    int ret = ne_request_dispatch(req);
    ne_request_destroy(req);
    return ret;
}
Esempio n. 12
0
static ne_request*
_build_request(ne_session *http_session, const gchar *path_url)
{
	ne_request *http_request;

	http_request = ne_request_create(http_session, "GET", path_url);
	ne_add_request_header(http_request, "User-Agent", "HoneyComb-gridagent-httpconf");
	return http_request;
}
Esempio n. 13
0
int any_2xx_request(ne_session *sess, const char *uri)
{
    ne_request *req = ne_request_create(sess, "GET", uri);
    int ret = ne_request_dispatch(req);
    int klass = ne_get_status(req)->klass;
    ne_request_destroy(req);
    ONV(ret != NE_OK || klass != 2,
	("request failed: %s", ne_get_error(sess)));
    return ret;
}
Esempio n. 14
0
int ne_unbind(ne_session *sess, const char *uri) 
{
    ne_request *req = ne_request_create(sess, "UNBIND", uri);

#ifdef NE_HAVE_DAV
    ne_lock_using_resource(req, uri, NE_DEPTH_INFINITE);
    ne_lock_using_parent(req, uri);
#endif
    return ne_simple_request(sess, req);
}    
Esempio n. 15
0
WebGrep::IssuedRequest Client::issueRequest(const char* method, const char* path, bool withLock)
{
  std::shared_ptr<std::lock_guard<std::mutex>> lk;
  if (withLock) {
      lk = std::make_shared<std::lock_guard<std::mutex>>(ctx->mu);
    }
  ctx->response.clear();
  auto rq = ne_request_create(ctx->sess, method, path);
  ne_add_response_body_reader(rq, ne_accept_always, httpResponseReader, (void*)ctx.get());
  IssuedRequest out;
  out.ctx = ctx;
  out.req = std::shared_ptr<ne_request>(rq, [out](ne_request* ptr){ne_request_destroy(ptr);} );
  return out;
}
Esempio n. 16
0
int any_2xx_request_body(ne_session *sess, const char *uri)
{
    ne_request *req = ne_request_create(sess, "GET", uri);
#define BSIZE 5000
    char *body = memset(ne_malloc(BSIZE), 'A', BSIZE);
    int ret;
    ne_set_request_body_buffer(req, body, BSIZE);
    ret = ne_request_dispatch(req);
    ne_free(body);
    ONV(ret != NE_OK || ne_get_status(req)->klass != 2,
	("request failed: %s", ne_get_error(sess)));
    ne_request_destroy(req);
    return ret;
}
Esempio n. 17
0
/* Get to given fd */
int ne_get(ne_session *sess, const char *uri, int fd)
{
    ne_request *req = ne_request_create(sess, "GET", uri);
    int ret;

    ret = dispatch_to_fd(req, fd, NULL);
    
    if (ret == NE_OK && ne_get_status(req)->klass != 2) {
	ret = NE_ERROR;
    }

    ne_request_destroy(req);

    return ret;
}
Esempio n. 18
0
int ne_options(ne_session *sess, const char *uri, ne_server_capabilities *caps)
{
    ne_request *req = ne_request_create(sess, "OPTIONS", uri);
    int ret = ne_request_dispatch(req);
    const char *header = ne_get_response_header(req, "DAV");
    
    if (header) parse_dav_header(header, caps);
 
    if (ret == NE_OK && ne_get_status(req)->klass != 2) {
	ret = NE_ERROR;
    }
    
    ne_request_destroy(req);

    return ret;
}
Esempio n. 19
0
/* Get to given fd */
int ne_post(ne_session *sess, const char *uri, int fd, const char *buffer)
{
    ne_request *req = ne_request_create(sess, "POST", uri);
    int ret;

    ne_set_request_body_buffer(req, buffer, strlen(buffer));

    ret = dispatch_to_fd(req, fd, NULL);
    
    if (ret == NE_OK && ne_get_status(req)->klass != 2) {
	ret = NE_ERROR;
    }

    ne_request_destroy(req);

    return ret;
}
Esempio n. 20
0
/* Perform a conditional PUT request with given If: header value,
 * placing response status-code in *code and class in *klass.  Fails
 * if requests cannot be dispatched. */
static int conditional_put(const char *ifhdr, int *klass, int *code)
{
    ne_request *req;
    
    req = ne_request_create(i_session, "PUT", res);
    ne_set_request_body_fd(req, i_foo_fd, 0, i_foo_len);

    ne_print_request_header(req, "If", "%s", ifhdr);
    
    ONMREQ("PUT", res, ne_request_dispatch(req));

    if (code) *code = ne_get_status(req)->code;
    if (klass) *klass = ne_get_status(req)->klass;
    
    ne_request_destroy(req);
    return OK;
}
Esempio n. 21
0
int ne_get_range(ne_session *sess, const char *uri, 
		 ne_content_range *range, int fd)
{
    ne_request *req = ne_request_create(sess, "GET", uri);
    const ne_status *status;
    int ret;
    char brange[64];

    if (range->end == -1) {
        ne_snprintf(brange, sizeof brange, "bytes=%" NE_FMT_OFF_T "-", 
                    range->start);
    }
    else {
	ne_snprintf(brange, sizeof brange,
                    "bytes=%" NE_FMT_OFF_T "-%" NE_FMT_OFF_T,
                    range->start, range->end);
    }

    ne_add_request_header(req, "Range", brange);
    ne_add_request_header(req, "Accept-Ranges", "bytes");

    ret = dispatch_to_fd(req, fd, brange);

    status = ne_get_status(req);

    if (ret == NE_OK && status->code == 416) {
	/* connection is terminated too early with Apache/1.3, so we check
	 * this even if ret == NE_ERROR... */
	ne_set_error(sess, _("Range is not satisfiable"));
	ret = NE_ERROR;
    }
    else if (ret == NE_OK) {
	if (status->klass == 2 && status->code != 206) {
	    ne_set_error(sess, _("Resource does not support ranged GETs."));
	    ret = NE_ERROR;
	}
	else if (status->klass != 2) {
	    ret = NE_ERROR;
	}
    } 
    
    ne_request_destroy(req);

    return ret;
}
Esempio n. 22
0
int ne_lock_refresh(ne_session *sess, struct ne_lock *lock)
{
    ne_request *req = ne_request_create(sess, "LOCK", lock->uri.path);
    ne_xml_parser *parser = ne_xml_create();
    int ret;
    struct lock_ctx ctx;

    memset(&ctx, 0, sizeof ctx);
    ctx.cdata = ne_buffer_create();
    ctx.req = req;
    ctx.token = lock->token;

    /* Handle the response and update *lock appropriately. */
    ne_xml_push_handler(parser, lk_startelm, lk_cdata, lk_endelm, &ctx);
    
    /* For a lock refresh, submitting only this lock token must be
     * sufficient. */
    ne_print_request_header(req, "If", "(<%s>)", lock->token);
    add_timeout_header(req, lock->timeout);

    ret = ne_xml_dispatch_request(req, parser);

    if (ret == NE_OK) {
        if (ne_get_status(req)->klass != 2) {
            ret = NE_ERROR; /* and use default session error */
        } else if (ne_xml_failed(parser)) {
	    ret = NE_ERROR;
	    ne_set_error(sess, "%s", ne_xml_get_error(parser));
	} else if (!ctx.found) {
            ne_set_error(sess, _("No activelock for <%s> returned in "
                                 "LOCK refresh response"), lock->token);
            ret = NE_ERROR;
        } else /* success! */ {
            /* update timeout for passed-in lock structure. */
            lock->timeout = ctx.active.timeout;
        }
    }

    ne_lock_free(&ctx.active);
    ne_buffer_destroy(ctx.cdata);
    ne_request_destroy(req);
    ne_xml_destroy(parser);

    return ret;
}
Esempio n. 23
0
static gboolean _ne_request(const char *host, int port, const char *target,
		const char *method, GSList *headers, GError **err)
{
	GRID_TRACE("%s", __FUNCTION__);
	gboolean result = FALSE;
	ne_session* session = ne_session_create("http", host, port);
	ne_set_connect_timeout(session, 10);
	ne_set_read_timeout(session, 30);

	GRID_DEBUG("%s http://%s:%d%s", method, host, port, target);
	ne_request* req = ne_request_create(session, method, target);
	if (NULL != req) {
		for (GSList *l = headers; l; l = l->next) {
			gchar **toks = g_strsplit(l->data, ":", 2);
			ne_add_request_header(req, toks[0], toks[1]);
			g_strfreev(toks);
		}
		switch (ne_request_dispatch(req)) {
			case NE_OK:
				if (ne_get_status(req)->klass != 2) {
					*err = NEWERROR(0, "cannot %s '%s' (%s)", method, target,
							ne_get_error(session));
				} else {
					result = TRUE;
				}
				break;
			case NE_AUTH:
			case NE_CONNECT:
			case NE_TIMEOUT:
			case NE_ERROR:
			default:
				*err = NEWERROR(0,
						"unexpected error from the WebDAV server (%s)",
						ne_get_error(session));
				break;
		}
		ne_request_destroy(req);
	} else {
		// This should be an assertion
		*err = NEWERROR(0, "Failed to create request");
	}
	ne_session_destroy (session);
	return result;
}
Esempio n. 24
0
/* Deletes the specified resource. (and in only two lines of code!) */
int ne_delete(ne_session *sess, const char *uri) 
{
    ne_request *req = ne_request_create(sess, "DELETE", uri);

#ifdef NE_HAVE_DAV
    ne_lock_using_resource(req, uri, NE_DEPTH_INFINITE);
    ne_lock_using_parent(req, uri);
#endif
    
    /* joe: I asked on the DAV WG list about whether we might get a
     * 207 error back from a DELETE... conclusion, you shouldn't if
     * you don't send the Depth header, since we might be an HTTP/1.1
     * client and a 2xx response indicates success to them.  But
     * it's all a bit unclear. In any case, DAV servers today do
     * return 207 to DELETE even if we don't send the Depth header.
     * So we handle 207 errors appropriately. */

    return ne_simple_request(sess, req);
}
Esempio n. 25
0
static int large_put(void)
{
    ne_request *req = ne_request_create(i_session, "PUT", path);
    int count, ret;
   
#ifdef NE_LFS
    ne_set_request_body_provider64(req, TOTALSIZE, provider, &count);
#else
    ne_set_request_body_provider(req, TOTALSIZE, provider, &count);
#endif
    
    ret = ne_request_dispatch(req);

    ONNREQ("large PUT request", ret || ne_get_status(req)->klass != 2);

    ne_request_destroy(req);

    return OK;
}
Esempio n. 26
0
/* sends a small segment of the file from a high offset. */
static int send_high_offset(void)
{
    int ret, fd = open64(SPARSE, O_RDONLY);
    ne_session *sess;
    ne_request *req;

    ONN("could not open sparse file", fd < 0);

    CALL(make_session(&sess, serve_check_body, NULL));
    
    req = ne_request_create(sess, "PUT", "/sparse");
    ne_set_request_body_fd64(req, fd, point, strlen(data));
    ret = ne_request_dispatch(req);
    CALL(await_server());
    ONV(ret != NE_OK || ne_get_status(req)->klass != 2,
        ("request failed: %s", ne_get_error(sess)));
    ne_request_destroy(req);
    ne_session_destroy(sess);
    close(fd);
    return OK;
}
Esempio n. 27
0
static int read_large_response(void)
{
    ne_session *sess;
    ne_request *req;
    off64_t count = 0;
    int ret;
    char buf[8192];

    CALL(make_session(&sess, serve_large_response, NULL));

    req = ne_request_create(sess, "GET", "/foo");

#ifdef NE_DEBUGGING
    ne_debug_init(ne_debug_stream, ne_debug_mask & ~(NE_DBG_HTTPBODY|NE_DBG_HTTP));
#endif
    
    ret = ne_begin_request(req);
    if (ret == NE_OK) {
        while ((ret = ne_read_response_block(req, buf, sizeof buf)) > 0)
            count += ret;
        if (ret == NE_OK)
            ret = ne_end_request(req);
    }

#ifdef NE_DEBUGGING
    ne_debug_init(ne_debug_stream, ne_debug_mask & (NE_DBG_HTTPBODY|NE_DBG_HTTP));
#endif
        
    ONV(ret, ("request failed: %s", ne_get_error(sess)));
    ONV(count != RESPSIZE, 
        ("response body was %" NE_FMT_OFF64_T " not %" NE_FMT_OFF64_T,
         count, RESPSIZE));

    ne_request_destroy(req);

    CALL(any_2xx_request(sess, "/bar"));
    CALL(await_server());
    ne_session_destroy(sess);
    return OK;
}
Esempio n. 28
0
svn_error_t *
svn_ra_neon__request_create(svn_ra_neon__request_t **request,
                            svn_ra_neon__session_t *sess,
                            const char *method, const char *url,
                            apr_pool_t *pool)
{
  apr_pool_t *reqpool = svn_pool_create(pool);
  svn_ra_neon__request_t *req;
  const char *path;

  /* We never want to send Neon an absolute URL, since that can cause
     problems with some servers (for example, those that may be accessed
     using different server names from different locations, or those that
     want to rewrite the incoming URL).  If the URL passed in is absolute,
     convert it to a path-absolute relative URL. */
  path = path_from_url(url);

  req = apr_pcalloc(reqpool, sizeof(*req));
  req->ne_sess = sess->main_session_busy ? sess->ne_sess2 : sess->ne_sess;
  req->ne_req = ne_request_create(req->ne_sess, method, path);
  req->sess = sess;
  req->pool = reqpool;
  req->iterpool = svn_pool_create(req->pool);
  req->method = apr_pstrdup(req->pool, method);
  req->url = apr_pstrdup(req->pool, url);
  req->rv = -1;

  /* Neon resources may be NULL on out-of-memory */
  assert(req->ne_req != NULL);
  apr_pool_cleanup_register(sess->pool, req,
                            dav_request_sess_cleanup,
                            apr_pool_cleanup_null);
  apr_pool_cleanup_register(reqpool, req,
                            dav_request_cleanup,
                            apr_pool_cleanup_null);

  *request = req;
  return SVN_NO_ERROR;
}
Esempio n. 29
0
int ne_unlock(ne_session *sess, const struct ne_lock *lock)
{
    ne_request *req = ne_request_create(sess, "UNLOCK", lock->uri.path);
    int ret;
    
    ne_print_request_header(req, "Lock-Token", "<%s>", lock->token);
    
    /* UNLOCK of a lock-null resource removes the resource from the
     * parent collection; so an UNLOCK may modify the parent
     * collection. (somewhat counter-intuitive, and not easily derived
     * from 2518.) */
    ne_lock_using_parent(req, lock->uri.path);

    ret = ne_request_dispatch(req);
    
    if (ret == NE_OK && ne_get_status(req)->klass != 2) {
	ret = NE_ERROR;
    }

    ne_request_destroy(req);
    
    return ret;
}
Esempio n. 30
0
static char *
_check_chunk(const char *cid)
{
	ne_session *session=NULL;
	ne_request *request=NULL;

	GString *str = g_string_new("");

	char **split = g_strsplit(cid, "/", 0);
	char **addr_tok = g_strsplit(split[2], ":", 2);

	if(NULL != (session = ne_session_create("http", addr_tok[0], atoi(addr_tok[1])))) {
		ne_set_connect_timeout(session, 10);
		ne_set_read_timeout(session, 30);
		/* FIXME: I'm a little harder with strrchr success presumption */
		if(NULL != (request = ne_request_create (session, "HEAD", strrchr(cid, '/')))) {
			switch (ne_request_dispatch (request)) {
				case NE_OK:
					if (ne_get_status(request)->klass != 2) {
						g_string_append_printf(str, "(Chunk unavailable : %s)",
								ne_get_error(session));
					}
					break;
				default:
					g_string_append_printf(str, "(Chunk unavailable : %s)",
							ne_get_error(session));
			}
			ne_request_destroy (request);
		} 
		ne_session_destroy (session);
	}

	g_strfreev(addr_tok);
	g_strfreev(split);

	return g_string_free(str, FALSE);
}