예제 #1
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;
}
예제 #2
0
파일: netxml-ups.c 프로젝트: balooloo/nut
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;
}
예제 #3
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;
}
예제 #4
0
파일: utils.c 프로젝트: Distrotech/neon
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;
}
예제 #5
0
static FillBufferResult fill_buffer (struct neon_handle * h)
{
    int bsize = free_rb (& h->rb);
    int to_read = MIN (bsize, NEON_NETBLKSIZE);

    char buffer[NEON_NETBLKSIZE];

    bsize = ne_read_response_block (h->request, buffer, to_read);

    if (! bsize)
    {
        _DEBUG ("<%p> End of file encountered", h);
        return FILL_BUFFER_EOF;
    }

    if (bsize < 0)
    {
        _ERROR ("<%p> Error while reading from the network", (void *) h);
        ne_request_destroy (h->request);
        h->request = NULL;
        return FILL_BUFFER_ERROR;
    }

    _DEBUG ("<%p> Read %d bytes of %d", h, bsize, to_read);

    write_rb (& h->rb, buffer, bsize);

    return FILL_BUFFER_SUCCESS;
}
예제 #6
0
static GByteArray*
_download_to_gba(ne_session *session, const gchar *path_url, GError **error)
{
	GByteArray *gba;
	ne_request *http_request;

	DEBUG("About to download [%s] into a memory buffer", path_url);

	gba = g_byte_array_new();
	http_request = _build_request(session, path_url);
	ne_add_response_body_reader(http_request, ne_accept_2xx, read_to_gba, gba);

	switch (ne_request_dispatch(http_request)) {
	case NE_OK:
		if (ne_get_status(http_request)->klass != 2) {
			GSETERROR (error, "Failed to download '%s': %s", path_url, ne_get_error(session));
			g_byte_array_free(gba, TRUE);
			gba = NULL;
		}
		break;
	case NE_AUTH:
	case NE_CONNECT:
	case NE_TIMEOUT:
	case NE_ERROR:
	default:
		GSETERROR(error,"Failed download '%s': %s", path_url, ne_get_error(session));
		g_byte_array_free(gba, TRUE);
		gba = NULL;
		break;
	}

	ne_request_destroy(http_request);
	return gba;
}
static void
gst_neonhttp_src_dispose (GObject * gobject)
{
    GstNeonhttpSrc *src = GST_NEONHTTP_SRC (gobject);

    ne_uri_free (&src->uri);
    ne_uri_free (&src->proxy);

    g_free (src->user_agent);

    if (src->cookies) {
        g_strfreev (src->cookies);
        src->cookies = NULL;
    }

    if (src->request) {
        ne_request_destroy (src->request);
        src->request = NULL;
    }

    if (src->session) {
        ne_close_connection (src->session);
        ne_session_destroy (src->session);
        src->session = NULL;
    }

    if (src->location) {
        ne_free (src->location);
    }
    if (src->query_string) {
        ne_free (src->query_string);
    }

    G_OBJECT_CLASS (parent_class)->dispose (gobject);
}
예제 #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;
}
예제 #9
0
파일: libs3.c 프로젝트: soundsrc/s3nbd
int s3_delete_object(S3 *s3,const char *bucket,const char *key)
{
	ne_request *req;
	int err, retry;

	if(!s3) return -1;
	if(!bucket) return -1;

	s3_begin_session(s3);

	req = s3_new_request(s3,"DELETE",bucket,key,NULL,NULL);

	// send to server
	do {
		err = ne_begin_request(req);
		if(err != NE_OK) err = -EIO;
		else {
			if(ne_get_status(req)->code != 204) {
				s3_handle_error_response(s3,req);
				err = -EACCES;
			}
			retry = ne_end_request(req);
		}
	} while(retry == NE_RETRY);

	ne_request_destroy(req);
	s3_end_session(s3);

	return err;
}
예제 #10
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;
}
예제 #11
0
파일: csync_owncloud.c 프로젝트: gco/csync
static int owncloud_close(csync_vio_method_handle_t *fhandle) {
    struct transfer_context *writeCtx;
    int ret = 0;
    enum csync_notify_type_e notify_tag;

    writeCtx = (struct transfer_context*) fhandle;

    if (fhandle == NULL) {
        errno = EBADF;
        ret = -1;
    }

    /* handle the PUT request */
    if( ret != -1 && strcmp( writeCtx->method, "PUT" ) == 0 ) {
      notify_tag = CSYNC_NOTIFY_FINISHED_UPLOAD;
      ne_request_destroy( writeCtx->req );
      _fs.name = NULL;
    } else  {
      /* Its a GET request. */
      notify_tag = CSYNC_NOTIFY_FINISHED_DOWNLOAD;
    }

    /* Finish callback */
    if (_file_progress_cb) {
        ne_set_notifier(dav_session.ctx, 0, 0);
        _file_progress_cb(writeCtx->url, notify_tag, 0, 0, _userdata );
    }

    /* free mem. Note that the request mem is freed by the ne_request_destroy call */
    SAFE_FREE( writeCtx->url );
    SAFE_FREE( writeCtx );

    return ret;
}
예제 #12
0
파일: ne_basic.c 프로젝트: tolsen/limeberry
/* 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;
}
예제 #13
0
파일: utils.c 프로젝트: Distrotech/neon
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;
}
예제 #14
0
파일: libs3.c 프로젝트: soundsrc/s3nbd
int s3_get_bucket(S3 *s3,const char *bucket,
	const char *prefix,const char *marker,int max_keys,const char *delimiter,
	const S3KeyInfoCallback *key_info_cb)
{
	ne_request *req;
	int err, retry;
	ne_buffer *params;

	if(!s3) return -1;
	if(!bucket) return -1;

	params = ne_buffer_create();
	if(prefix) ne_buffer_concat(params,"prefix=",prefix,"/&",NULL);
	if(marker) ne_buffer_concat(params,"marker=",marker,"&",NULL);
	if(max_keys >= 0) {
		char mk[16];
		snprintf(mk,16,"%d",max_keys);
		mk[15] = 0;
		ne_buffer_concat(params,"max_keys=",max_keys,"&",NULL);
	}
	if(delimiter) ne_buffer_concat(params,"delimiter=",delimiter,"&",NULL);

	s3_begin_session(s3);

	req = s3_new_request(s3,"GET",bucket,NULL,params->data,NULL);

	ne_buffer_destroy(params);

	// send to server
	do {
		err = ne_begin_request(req);
		if(err != NE_OK) err = -EIO;
		else {
			if(ne_get_status(req)->code != 200) {
				s3_handle_error_response(s3,req);
				err = -EACCES;
			} else {
				s3->key_info.key_info_cb = key_info_cb;
				s3_parse_xml_response(s3,
					req,
					s3_xml_key_info_startelm,
					s3_xml_key_info_cdata,
					s3_xml_key_info_endelm,
					&s3->key_info
				);
			}
			retry = ne_end_request(req);
		}
	} while(retry == NE_RETRY);

	ne_request_destroy(req);
	s3_end_session(s3);

	return err;
}
static void
gst_neonhttp_src_close_session (GstNeonhttpSrc * src)
{
    if (src->request) {
        ne_request_destroy (src->request);
        src->request = NULL;
    }

    if (src->session) {
        ne_close_connection (src->session);
        ne_session_destroy (src->session);
        src->session = NULL;
    }
}
예제 #16
0
파일: utils.c 프로젝트: Distrotech/neon
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;
}
예제 #17
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;
}
예제 #18
0
파일: ne_basic.c 프로젝트: tolsen/limeberry
/* 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;
}
예제 #19
0
파일: util.c 프로젝트: DJEX93/dsploit
static apr_status_t
dav_request_sess_cleanup(void *baton)
{
  svn_ra_neon__request_t *req = baton;

  /* Make sure we don't run the 'child' cleanup anymore:
     the pool it refers to probably doesn't exist anymore when it
     finally does get run if it hasn't by now. */
  apr_pool_cleanup_kill(req->pool, req, dav_request_cleanup);

  if (req->ne_req)
    ne_request_destroy(req->ne_req);

  return APR_SUCCESS;
}
예제 #20
0
int neon_vfs_fclose_impl (VFSFile * file)
{
    struct neon_handle * h = vfs_get_handle (file);

    if (h->reader_status.reading)
        kill_reader (h);

    if (h->request)
        ne_request_destroy (h->request);
    if (h->session)
        ne_session_destroy (h->session);

    handle_free (h);

    return 0;
}
예제 #21
0
파일: ne_basic.c 프로젝트: tolsen/limeberry
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;
}
예제 #22
0
파일: ne_basic.c 프로젝트: tolsen/limeberry
/* 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;
}
예제 #23
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;
}
예제 #24
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;
}
예제 #25
0
파일: ne_basic.c 프로젝트: tolsen/limeberry
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;
}
예제 #26
0
파일: rawx.c 프로젝트: amogrid/redcurrant
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;
}
예제 #27
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;
}
예제 #28
0
파일: libs3.c 프로젝트: soundsrc/s3nbd
int s3_head_object(S3 *s3,const char *bucket,const char *key,S3ObjectInfo *oi)
{
	ne_request *req;
	int err;

	if(!s3) return -1;
	if(!bucket) return -1;

	s3_begin_session(s3);

	req = s3_new_request(s3,"HEAD",bucket,key,NULL,NULL);

	// send to server
	err = ne_request_dispatch(req);
	if(err != NE_OK) err = -EIO;

	if(ne_get_status(req)->code != 200) {
		s3_handle_error_response(s3,req);
		if(ne_get_status(req)->code == 404) err = -ENOENT;
		else err = -EACCES;
	} else if(oi) {
		const char *str;
		str = ne_get_response_header(req,"Content-Length");
		if(str) oi->content_length = strtol(str,NULL,10);
		str = ne_get_response_header(req,"Content-Type");
		if(str) {
			strncpy(oi->content_type,str,31);
			oi->content_type[31] = 0;
		}
		str = ne_get_response_header(req,"ETag");
		if(str) {
			strncpy(oi->etag,str,79);
			oi->etag[79] = 0;
		}
	}

	ne_request_destroy(req);
	s3_end_session(s3);

	return err;
}
예제 #29
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;
}
예제 #30
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;
}