示例#1
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;
}
示例#2
0
文件: rawx.c 项目: korween/oio-sds
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);
}
示例#3
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

    if (ne_get_session_flag(sess, NE_SESSFLAG_RFC4918)) {
        ne_add_request_header(req, "Destination", dest);
    }
    else {
        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);
}
示例#4
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;
}
示例#5
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;
}
示例#6
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;
}
示例#7
0
static void add_timeout_header(ne_request *req, long timeout)
{
    if (timeout == NE_TIMEOUT_INFINITE) {
	ne_add_request_header(req, "Timeout", "Infinite");
    } 
    else if (timeout == NE_TIMEOUT_CLOSE_TO_INFINITE){
    ne_print_request_header(req,"Timeout","Infinite, Second-%ld", 3600);
    }
    else if (timeout != NE_TIMEOUT_INVALID && timeout > 0) {
	ne_print_request_header(req, "Timeout", "Second-%ld", timeout);
    }
    /* just ignore it if timeout == 0 or invalid. */
}
示例#8
0
/*
 * this hook is called just after a request has been created, before its sent.
 * Here it is used to set the proxy connection header if available.
 */
static void request_created_hook(ne_request *req, void *userdata,
                                 const char *method, const char *requri)
{
    (void) userdata;
    (void) method;
    (void) requri;

    if( !req ) return;

    if(dav_session.proxy_type) {
        /* required for NTLM */
        ne_add_request_header(req, "Proxy-Connection", "Keep-Alive");
    }
}
示例#9
0
文件: rawx.c 项目: amogrid/redcurrant
char*
create_rawx_request_common(ne_request **req, ne_request_param_t *param, GError **err)
{
	ne_request *request = NULL;
	char str_req_id[1024];

	memset(str_req_id, 0x00, sizeof(str_req_id));

	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, "containerid", param->containerid);
	ne_add_request_header  (request, "contentpath", param->contentpath);
	ne_print_request_header(request, "chunkpos",    "%u", param->chunkpos);
	ne_print_request_header(request, "chunknb",     "%u", param->chunknb);
	ne_print_request_header(request, "chunksize",   "%"G_GINT64_FORMAT, param->chunksize);
	ne_print_request_header(request, "contentsize", "%"G_GINT64_FORMAT, param->contentsize);

	gscstat_tags_start(GSCSTAT_SERVICE_RAWX, GSCSTAT_TAGS_REQPROCTIME);

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

	*req = request;
	return g_strdup(str_req_id);
}
示例#10
0
void ne_add_depth_header(ne_request *req, int depth)
{
    const char *value;
    switch(depth) {
    case NE_DEPTH_ZERO:
	value = "0";
	break;
    case NE_DEPTH_ONE:
	value = "1";
	break;
    default:
	value = "infinity";
	break;
    }
    ne_add_request_header(req, "Depth", value);
}
示例#11
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;
}
示例#12
0
ne_decompress *ne_decompress_reader(ne_request *req, ne_accept_response acpt,
				    ne_block_reader rdr, void *userdata)
{
    ne_decompress *ctx = ne_calloc(sizeof *ctx);

    ne_add_request_header(req, "Accept-Encoding", "gzip");

    ne_add_response_body_reader(req, gz_acceptor, gz_reader, ctx);

    ctx->reader = rdr;
    ctx->userdata = userdata;
    ctx->session = ne_get_session(req);
    ctx->request = req;
    ctx->acceptor = acpt;

    ne__reqhook_pre_send(req, gz_pre_send, ctx);

    return ctx;    
}
示例#13
0
文件: rawx.c 项目: amogrid/redcurrant
char*
create_rawx_request_from_chunk(ne_request **p_req, ne_session *session,
		const char *method, gs_chunk_t *chunk, GByteArray *system_metadata,
		GError **err)
{
	char str_ci[STRLEN_CHUNKID], cPath[CI_FULLPATHLEN], *str_req_id;
	ne_request_param_t *params = new_request_param();

	if (NULL == chunk) {
		GSETERROR(err, "No chunk given");
		return NULL;
	}

	params->session = session;
	params->method = g_strdup(method);
	chunk_getpath (chunk, cPath, sizeof(cPath));
	params->cPath = g_strdup(cPath);
	params->containerid = g_strdup(C1_IDSTR(chunk->content));
	params->contentpath = g_strdup(C1_PATH(chunk->content));
	params->chunkpos = chunk->ci->position;
	params->chunknb = chunk->ci->nb;
	params->chunksize = chunk->ci->size;
	params->contentsize = chunk->content->info.size;

	str_req_id = create_rawx_request_common(p_req, params, err);
	free_request_param(params);
	if (*p_req) {
		if (system_metadata && system_metadata->data && system_metadata->len>0)
			add_req_system_metadata_header(*p_req, system_metadata);
		chunk_id2str(chunk, str_ci, sizeof(str_ci));
		GRID_DEBUG("chunkid=%s", str_ci);
		ne_add_request_header(*p_req, "chunkid", str_ci);
		return str_req_id;
	}

	g_free(str_req_id);
	return NULL;
}
示例#14
0
int ne_acl_set(ne_session *sess, const char *uri,
               ne_acl_entry *entries, int numentries)
{
    int ret;
    ne_request *req = ne_request_create(sess, "ACL", uri);
    ne_buffer *body = acl_body(entries, numentries);

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

    ne_set_request_body_buffer(req, body->data, ne_buffer_size(body));
    ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE);
    ret = ne_request_dispatch(req);

    ne_buffer_destroy(body);

    if (ret == NE_OK && ne_get_status(req)->code == 207) {
        ret = NE_ERROR;
    }

    ne_request_destroy(req);
    return ret;
}
示例#15
0
文件: util.c 项目: DJEX93/dsploit
svn_error_t *
svn_ra_neon__request_dispatch(int *code_p,
                              svn_ra_neon__request_t *req,
                              apr_hash_t *extra_headers,
                              const char *body,
                              int okay_1,
                              int okay_2,
                              apr_pool_t *pool)
{
  ne_xml_parser *error_parser;
  const ne_status *statstruct;

  /* add any extra headers passed in by caller. */
  if (extra_headers != NULL)
    {
      apr_hash_index_t *hi;
      for (hi = apr_hash_first(pool, extra_headers);
           hi; hi = apr_hash_next(hi))
        {
          const void *key;
          void *val;
          apr_hash_this(hi, &key, NULL, &val);
          ne_add_request_header(req->ne_req,
                                (const char *) key, (const char *) val);
        }
    }

  /* Certain headers must be transmitted unconditionally with every
     request; see issue #3255 ("mod_dav_svn does not pass client
     capabilities to start-commit hooks") for why.  It's okay if one
     of these headers was already added via extra_headers above --
     they are all idempotent headers.

     Note that at most one could have been sent via extra_headers,
     because extra_headers is a hash and the key would be the same for
     all of them: "DAV".  In a just and righteous world, extra_headers
     would be an array, not a hash, so that callers could send the
     same header with different values too.  But, apparently, that
     hasn't been necessary yet. */
  ne_add_request_header(req->ne_req, "DAV", SVN_DAV_NS_DAV_SVN_DEPTH);
  ne_add_request_header(req->ne_req, "DAV", SVN_DAV_NS_DAV_SVN_MERGEINFO);
  ne_add_request_header(req->ne_req, "DAV", SVN_DAV_NS_DAV_SVN_LOG_REVPROPS);

  if (body)
    ne_set_request_body_buffer(req->ne_req, body, strlen(body));

  /* attach a standard <D:error> body parser to the request */
  error_parser = error_parser_create(req);

  if (req->ne_sess == req->sess->ne_sess) /* We're consuming 'session 1' */
    req->sess->main_session_busy = TRUE;
  /* run the request, see what comes back. */
  req->rv = ne_request_dispatch(req->ne_req);
  if (req->ne_sess == req->sess->ne_sess) /* We're done consuming 'session 1' */
    req->sess->main_session_busy = FALSE;

  /* Save values from the request */
  statstruct = ne_get_status(req->ne_req);
  req->code_desc = apr_pstrdup(pool, statstruct->reason_phrase);
  req->code = statstruct->code;

  /* If we see a successful request that used authentication, we should store
     the credentials for future use. */
  if (req->sess->auth_used
      && statstruct->code < 400)
    {
      req->sess->auth_used = FALSE;
      SVN_ERR(svn_ra_neon__maybe_store_auth_info(req->sess, pool));
    }

  if (code_p)
     *code_p = req->code;

  if (!req->marshalled_error)
    SVN_ERR(req->err);

  /* If the status code was one of the two that we expected, then go
     ahead and return now. IGNORE any marshalled error. */
  if (req->rv == NE_OK && (req->code == okay_1 || req->code == okay_2))
    return SVN_NO_ERROR;

  /* Any other errors? Report them */
  SVN_ERR(req->err);

  SVN_ERR(svn_ra_neon__check_parse_error(req->method, error_parser, req->url));

  /* We either have a neon error, or some other error
     that we didn't expect. */
  return generate_error(req, pool);
}
示例#16
0
文件: libs3.c 项目: soundsrc/s3nbd
static ne_request *s3_new_request(const S3 *s3,const char *method,const char *bucket,const char *key,const char *params,const char *content_type)
{
	ne_buffer *date, *signing_string, *request_str;
	ne_request *req;
	char *sig, *p;
	time_t t;

	if(!s3) return NULL;
	if(!method) return NULL;
	if(!bucket) return NULL;
	if(!s3->session) return NULL;

	// create some string buffers
	date = ne_buffer_create();
	signing_string = ne_buffer_create();
	request_str = ne_buffer_create();

	// get the time
	t = time(NULL);
	ne_buffer_zappend(date,asctime(gmtime(&t)));
	if(date->data[date->used - 2] == '\n')
		date->data[date->used - 2] = 0;
	ne_buffer_altered(date);

	// create request
	if(key) ne_buffer_concat(request_str,"/",bucket,"/",key,NULL);
	else ne_buffer_concat(request_str,"/",bucket,NULL);

	if(params && params[0] != 0) {
		ne_buffer_zappend(request_str,"?");
		ne_buffer_zappend(request_str,params);
	}

	req = ne_request_create(s3->session,method,request_str->data);

	// Add date header
	ne_add_request_header(req,"Date",date->data);

	// Add content-type header
	if(content_type) ne_add_request_header(req,"Content-Type",content_type);
	else content_type = "";

	// construct signing string
	p = strrchr(request_str->data,'?');
	if(p) {
		*p = 0;
		ne_buffer_altered(request_str);
	}
	ne_buffer_concat(signing_string,method,"\n\n",content_type,"\n",date->data,"\n",request_str->data,NULL);
	// sign the string
	sig = s3_sign_string(s3,signing_string->data);

	// construct signed header
	ne_print_request_header(req,"Authorization","AWS %s:%s",s3->access_id,sig);

	ne_buffer_destroy(date);
	ne_buffer_destroy(signing_string);
	ne_buffer_destroy(request_str);
	free(sig);

	return req;
}
示例#17
0
svn_error_t *
svn_ra_neon__exchange_capabilities(svn_ra_neon__session_t *ras,
                                   apr_pool_t *pool)
{
  svn_ra_neon__request_t* req;
  svn_error_t *err = SVN_NO_ERROR;
  ne_xml_parser *parser = NULL;
  options_ctx_t oc = { 0 };
  const char *msg;
  int status_code;

  oc.pool = pool;
  oc.cdata = svn_stringbuf_create("", pool);

  req = svn_ra_neon__request_create(ras, "OPTIONS", ras->url->data, pool);

  /* ### Use a symbolic name somewhere for this MIME type? */
  ne_add_request_header(req->ne_req, "Content-Type", "text/xml");

  /* Create a parser to read the normal response body */
  parser = svn_ra_neon__xml_parser_create(req, ne_accept_2xx, start_element,
                                          svn_ra_neon__xml_collect_cdata,
                                          end_element, &oc);

  /* Run the request and get the resulting status code. */
  if ((err = svn_ra_neon__request_dispatch(&status_code, req, NULL,
                                           "<?xml version=\"1.0\" "
                                           "encoding=\"utf-8\"?>"
                                           "<D:options xmlns:D=\"DAV:\">"
                                           "<D:activity-collection-set/>"
                                           "</D:options>",
                                           200, 0, pool)))
    goto cleanup;

  /* Was there an XML parse error somewhere? */
  msg = ne_xml_get_error(parser);
  if (msg && *msg)
    {
      err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                              _("The %s request returned invalid XML "
                                "in the response: %s (%s)"),
                              "OPTIONS", msg, ras->url->data);
      goto cleanup;
    }

  /* We asked for, and therefore expect, to have found an activity
     collection in the response.  */
  if (oc.activity_coll == NULL)
    {
      err = svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
                             _("The OPTIONS response did not include the "
                               "requested activity-collection-set; this often "
                               "means that the URL is not WebDAV-enabled"));
      goto cleanup;
    }

  ras->act_coll = apr_pstrdup(ras->pool, oc.activity_coll->data);
  parse_capabilities(req->ne_req, ras, pool);

 cleanup:
  svn_ra_neon__request_destroy(req);

  return err;
}
/* Try to send the HTTP request to the Icecast server, and if possible deals with
 * all the probable redirections (HTTP status code == 3xx)
 */
static gint
gst_neonhttp_src_send_request_and_redirect (GstNeonhttpSrc * src,
        ne_session ** ses, ne_request ** req, gint64 offset, gboolean do_redir)
{
    ne_session *session = NULL;
    ne_request *request = NULL;
    gchar **c;
    gint res;
    gint http_status = 0;
    guint request_count = 0;

    do {
        if (src->proxy.host && src->proxy.port) {
            session =
                ne_session_create (src->uri.scheme, src->uri.host, src->uri.port);
            ne_session_proxy (session, src->proxy.host, src->proxy.port);
        } else if (src->proxy.host || src->proxy.port) {
            /* both proxy host and port must be specified or none */
            return HTTP_REQUEST_WRONG_PROXY;
        } else {
            session =
                ne_session_create (src->uri.scheme, src->uri.host, src->uri.port);
        }

        if (src->connect_timeout > 0) {
            ne_set_connect_timeout (session, src->connect_timeout);
        }

        if (src->read_timeout > 0) {
            ne_set_read_timeout (session, src->read_timeout);
        }

        ne_set_session_flag (session, NE_SESSFLAG_ICYPROTO, 1);
        ne_ssl_set_verify (session, ssl_verify_callback, src);

        request = ne_request_create (session, "GET", src->query_string);

        if (src->user_agent) {
            ne_add_request_header (request, "User-Agent", src->user_agent);
        }

        for (c = src->cookies; c != NULL && *c != NULL; ++c) {
            GST_INFO ("Adding header Cookie : %s", *c);
            ne_add_request_header (request, "Cookies", *c);
        }

        if (src->iradio_mode)
            ne_add_request_header (request, "icy-metadata", "1");

        if (offset > 0) {
            ne_print_request_header (request, "Range",
                                     "bytes=%" G_GINT64_FORMAT "-", offset);
        }

        res = ne_begin_request (request);

        if (res == NE_OK) {
            /* When the HTTP status code is 3xx, it is not the SHOUTcast streaming content yet;
             * Reload the HTTP request with a new URI value */
            http_status = ne_get_status (request)->code;
            if (STATUS_IS_REDIRECTION (http_status) && do_redir) {
                const gchar *redir;

                /* the new URI value to go when redirecting can be found on the 'Location' HTTP header */
                redir = ne_get_response_header (request, "Location");
                if (redir != NULL) {
                    ne_uri_free (&src->uri);
                    gst_neonhttp_src_set_location (src, redir, NULL);
                    GST_LOG_OBJECT (src, "Got HTTP Status Code %d", http_status);
                    GST_LOG_OBJECT (src, "Using 'Location' header [%s]", src->uri.host);
                }
            }
        }

        if ((res != NE_OK) ||
                (offset == 0 && http_status != 200) ||
                (offset > 0 && http_status != 206 &&
                 !STATUS_IS_REDIRECTION (http_status))) {
            ne_request_destroy (request);
            request = NULL;
            ne_close_connection (session);
            ne_session_destroy (session);
            session = NULL;
            if (offset > 0 && http_status != 206 &&
                    !STATUS_IS_REDIRECTION (http_status)) {
                src->seekable = FALSE;
            }
        }

        /* if - NE_OK */
        if (STATUS_IS_REDIRECTION (http_status) && do_redir) {
            ++request_count;
            GST_LOG_OBJECT (src, "redirect request_count is now %d", request_count);
            if (request_count < MAX_HTTP_REDIRECTS_NUMBER && do_redir) {
                GST_INFO_OBJECT (src, "Redirecting to %s", src->uri.host);
            } else {
                GST_WARNING_OBJECT (src, "Will not redirect, try again with a "
                                    "different URI or redirect location %s", src->uri.host);
            }
            /* FIXME: when not redirecting automatically, shouldn't we post a
             * redirect element message on the bus? */
        }
        /* do the redirect, go back to send another HTTP request now using the 'Location' */
    } while (do_redir && (request_count < MAX_HTTP_REDIRECTS_NUMBER)
             && STATUS_IS_REDIRECTION (http_status));

    if (session) {
        *ses = session;
        *req = request;
    }

    return res;
}
示例#19
0
Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const char *verb ) {
    Hbf_State state = HBF_TRANSFER_SUCCESS;
    int cnt;

    if( ! session ) {
        state = HBF_SESSION_FAIL;
    }
    if( ! transfer ) {
        state = HBF_SPLITLIST_FAIL;
    }
    if( ! verb ) {
        state = HBF_PARAM_FAIL;
    }

    if(state == HBF_TRANSFER_SUCCESS) {
        DEBUG_HBF("%s request to %s", verb, transfer->url);
    }

    for( cnt=0; state == HBF_TRANSFER_SUCCESS && cnt < transfer->block_cnt; cnt++ ) {
        /* cnt goes from O to block_cnt,  but block_id starts at start_id and wrap around
         * That way if we have not finished uploaded when we reach block_cnt, we re-upload
         * the beginning of the file that the server did not have in cache anymore.
         */
        int block_id = (cnt + transfer->start_id) % transfer->block_cnt;
        hbf_block_t *block = transfer->block_arr[block_id];
        char *transfer_url = NULL;

        if( ! block ) state = HBF_PARAM_FAIL;

        if( transfer->abort_cb ) {
            int do_abort = (transfer->abort_cb)(transfer->user_data);
            if( do_abort ) {
              state = HBF_USER_ABORTED;
              transfer->start_id = block_id  % transfer->block_cnt;
            }
        }

        if( state == HBF_TRANSFER_SUCCESS ) {
            transfer_url = get_transfer_url( transfer, block_id );
            if( ! transfer_url ) {
                state = HBF_PARAM_FAIL;
            }
        }

        if( state == HBF_TRANSFER_SUCCESS ) {
          if( transfer->block_cnt > 1 && cnt > 0 ) {
            /* The block count is > 1, check size and mtime before transmitting. */
            state = hbf_validate_source_file(transfer);
            if( state == HBF_SOURCE_FILE_CHANGE ) {
              /* The source file has changed meanwhile */
            }
          }
        }

        if( state == HBF_TRANSFER_SUCCESS || state == HBF_SUCCESS ) {
            ne_request *req = ne_request_create(session, verb, transfer_url);

            if( req ) {
                char buf[21];

                snprintf(buf, sizeof(buf), "%"PRId64, transfer->stat_size);
                ne_add_request_header(req, "OC-Total-Length", buf);
                if( transfer->oc_header_modtime > 0 ) {
                    snprintf(buf, sizeof(buf), "%"PRId64, transfer->oc_header_modtime);
                    ne_add_request_header(req, "X-OC-Mtime", buf);
                }

                if( transfer->previous_etag ) {
                  ne_add_request_header(req, "If-Match", transfer->previous_etag);
                }

                if( transfer->block_cnt > 1 ) {
                  ne_add_request_header(req, "OC-Chunked", "1");
                  snprintf(buf, sizeof(buf), "%"PRId64, transfer->threshold);
                  ne_add_request_header(req, "OC-Chunk-Size", buf);
                }
                ne_add_request_header( req, "Content-Type", "application/octet-stream");

                state = _hbf_dav_request(transfer,  req, transfer->fd, block );

                if( state != HBF_TRANSFER_SUCCESS && state != HBF_SUCCESS) {
                  if( transfer->error_string ) free( transfer->error_string );
                  transfer->error_string = strdup( ne_get_error(session) );
                  transfer->start_id = block_id  % transfer->block_cnt;
                  /* Set the code of the last transmission. */
                  state = HBF_FAIL;
                  transfer->status_code = transfer->block_arr[block_id]->http_result_code;
                }
                ne_request_destroy(req);

                if (transfer->block_cnt > 1 && state == HBF_SUCCESS && cnt == 0) {
                    /* Success on the first chunk is suspicious.
                       It could happen that the server did not support chunking */
                    int rc = ne_delete(session, transfer_url);
                    if (rc == NE_OK && _hbf_http_error_code(session) == 204) {
                        /* If delete suceeded, it means some proxy strips the OC_CHUNKING header
                           start again without chunking: */
                       free( transfer_url );
                       return _hbf_transfer_no_chunk(session, transfer, verb);
                    }
                }

                if (state == HBF_TRANSFER_SUCCESS && transfer->chunk_finished_cb) {
                    transfer->chunk_finished_cb(transfer, block_id, transfer->user_data);
                }

            } else {
                state = HBF_MEMORY_FAIL;
            }
        }
        free( transfer_url );
    }

    /* do the source file validation finally (again). */
    if( state == HBF_TRANSFER_SUCCESS ) {
        /* This means that no etag was returned on one of the chunks to indicate
         * that the upload was finished. */
        state = HBF_TRANSFER_NOT_ACKED;
    }

    return state;
}
示例#20
0
static csync_vio_method_handle_t *owncloud_open(const char *durl,
                                                int flags,
                                                mode_t mode) {
    char *uri = NULL;
    char *dir = NULL;
    char getUrl[PATH_MAX];
    int put = 0;
    int rc = NE_OK;
#ifdef _WIN32
    int gtp = 0;
    char tmpname[13];
#endif

    struct transfer_context *writeCtx = NULL;
    csync_stat_t statBuf;
    memset( getUrl, '\0', PATH_MAX );

    (void) mode; /* unused on webdav server */
    DEBUG_WEBDAV(( "=> open called for %s\n", durl ));

    uri = _cleanPath( durl );
    if( ! uri ) {
        DEBUG_WEBDAV(("Failed to clean path for %s\n", durl ));
        errno = EACCES;
        rc = NE_ERROR;
    }

    if( rc == NE_OK )
        dav_connect( durl );

    if (flags & O_WRONLY) {
        put = 1;
    }
    if (flags & O_RDWR) {
        put = 1;
    }
    if (flags & O_CREAT) {
        put = 1;
    }


    if( rc == NE_OK && put ) {
        /* check if the dir name exists. Otherwise return ENOENT */
        dir = c_dirname( durl );
	if (dir == NULL) {
            errno = ENOMEM;
	    return NULL;
	}
        DEBUG_WEBDAV(("Stating directory %s\n", dir ));
        if( c_streq( dir, _lastDir )) {
            DEBUG_WEBDAV(("Dir %s is there, we know it already.\n", dir));
        } else {
            if( owncloud_stat( dir, (csync_vio_method_handle_t*)(&statBuf) ) == 0 ) {
                DEBUG_WEBDAV(("Directory of file to open exists.\n"));
                SAFE_FREE( _lastDir );
                _lastDir = c_strdup(dir);

            } else {
                DEBUG_WEBDAV(("Directory %s of file to open does NOT exist.\n", dir ));
                /* the directory does not exist. That is an ENOENT */
                errno = ENOENT;
                SAFE_FREE( dir );
                return NULL;
            }
        }
    }

    writeCtx = c_malloc( sizeof(struct transfer_context) );
    writeCtx->bytes_written = 0;
    if( rc == NE_OK ) {
        /* open a temp file to store the incoming data */
#ifdef _WIN32
        memset( tmpname, '\0', 13 );
        gtp = GetTempPath( PATH_MAX, getUrl );
        DEBUG_WEBDAV(("win32 tmp path: %s\n", getUrl ));
        if ( gtp > MAX_PATH || (gtp == 0) ) {
            DEBUG_WEBDAV(("Failed to compute Win32 tmp path, trying /tmp\n"));
            strcpy( getUrl, "/tmp/");
        }
        strcpy( tmpname, "csync.XXXXXX" );
        if( c_tmpname( tmpname ) == 0 ) {
            _fmode = _O_BINARY;
            strcat( getUrl, tmpname );
            writeCtx->tmpFileName = c_strdup( getUrl );
            writeCtx->fd = open( writeCtx->tmpFileName, O_RDWR | O_CREAT | O_EXCL, 0600 );
	} else {
	   writeCtx->fd = -1;
	}
#else
        writeCtx->tmpFileName = c_strdup( "/tmp/csync.XXXXXX" );
        writeCtx->fd = mkstemp( writeCtx->tmpFileName );
#endif
        DEBUG_WEBDAV(("opening temp directory %s: %d\n", writeCtx->tmpFileName, writeCtx->fd ));
        if( writeCtx->fd == -1 ) {
	    DEBUG_WEBDAV(("Failed to open temp file, errno = %d\n", errno ));
            rc = NE_ERROR;
            /* errno is set by the mkstemp call above. */
        }
    }

    if( rc == NE_OK && put) {
        DEBUG_WEBDAV(("PUT request on %s!\n", uri));
        /* reset the write buffer */
        writeCtx->bytes_written = 0;
        writeCtx->fileWritten = 0;   /* flag to indicate if contents was pushed to file */

        writeCtx->req = ne_request_create(dav_session.ctx, "PUT", uri);
	writeCtx->method = "PUT";
    }


    if( rc == NE_OK && ! put ) {
        writeCtx->req = 0;
        writeCtx->method = "GET";

        /* Download the data into a local temp file. */
        /* the download via the get function requires a full uri */
        snprintf( getUrl, PATH_MAX, "%s://%s%s", ne_get_scheme( dav_session.ctx),
                  ne_get_server_hostport( dav_session.ctx ), uri );
        DEBUG_WEBDAV(("GET request on %s\n", getUrl ));

#define WITH_HTTP_COMPRESSION
#ifdef WITH_HTTP_COMPRESSION
        writeCtx->req = ne_request_create( dav_session.ctx, "GET", getUrl );

        /* Allow compressed content by setting the header */
        ne_add_request_header( writeCtx->req, "Accept-Encoding", "gzip,deflate" );

        /* hook called before the content is parsed to set the correct reader,
         * either the compressed- or uncompressed reader.
         */
        ne_hook_post_headers( dav_session.ctx, install_content_reader, writeCtx );

        /* actually do the request */
        rc = ne_request_dispatch(writeCtx->req );
        /* possible return codes are:
         *  NE_OK, NE_AUTH, NE_CONNECT, NE_TIMEOUT, NE_ERROR (from ne_request.h)
         */

        if( rc != NE_OK || (rc == NE_OK && ne_get_status(writeCtx->req)->klass != 2) ) {
            DEBUG_WEBDAV(("request_dispatch failed with rc=%d\n", rc ));
            if( rc == NE_OK ) rc = NE_ERROR;
            errno = EACCES;
        }

        /* delete the hook again, otherwise they get chained as they are with the session */
        ne_unhook_post_headers( dav_session.ctx, install_content_reader, writeCtx );

        /* if the compression handle is set through the post_header hook, delete it. */
        if( writeCtx->decompress ) {
            ne_decompress_destroy( writeCtx->decompress );
        }

        /* delete the request in any case */
        ne_request_destroy(writeCtx->req);
#else
        DEBUG_WEBDAV(("GET Compression not supported!\n"));
        rc = ne_get( dav_session.ctx, getUrl, writeCtx->fd );  /* FIX_ESCAPE? */
#endif
        if( rc != NE_OK ) {
            DEBUG_WEBDAV(("Download to local file failed: %d.\n", rc));
            errno = EACCES;
        }
        if( close( writeCtx->fd ) == -1 ) {
            DEBUG_WEBDAV(("Close of local download file failed.\n"));
            writeCtx->fd = -1;
            rc = NE_ERROR;
            errno = EACCES;
        }

        writeCtx->fd = -1;
    }

    if( rc != NE_OK ) {
        SAFE_FREE( writeCtx );
    }

    SAFE_FREE( uri );
    SAFE_FREE( dir );

    return (csync_vio_method_handle_t *) writeCtx;
}
示例#21
0
文件: rawx.c 项目: amogrid/redcurrant
static gboolean
_rawx_update_chunk_attrs(chunk_id_t *cid, GSList *attrs, GError **err)
{
	ne_session *s = NULL;
	ne_request *r = NULL;
	int ne_rc;
	gboolean result = FALSE;

	gchar dst[128];
	guint16 port = 0;
	GString *req_str = NULL;
	char idstr[65];

	if (!addr_info_get_addr(&(cid->addr), dst, sizeof(dst), &port))
		return result;

	s = ne_session_create("http", dst, port);
	if (!s) {
		GSETERROR(err, "Failed to create session to rawx %s:%d", dst, port);
		return result;
	}

	ne_set_connect_timeout(s, 10);
	ne_set_read_timeout(s, 30);

	req_str =g_string_new("/rawx/chunk/set/");
	bzero(idstr, sizeof(idstr));
	buffer2str(&(cid->id), sizeof(cid->id), idstr, sizeof(idstr));
	req_str = g_string_append(req_str, idstr);
	GRID_TRACE("Calling %s", req_str->str);

	r = ne_request_create (s, "GET", req_str->str);
	if (!r) {
		goto end_attr;
	}

	for (; attrs != NULL; attrs = attrs->next) {
		struct chunk_attr_s *attr = attrs->data;
		ne_add_request_header(r, attr->key, attr->val);
	}

	switch (ne_rc = ne_request_dispatch(r)) {
		case NE_OK:
			result = TRUE;
			break;
		case NE_ERROR:
			GSETCODE(err, 500, "Request NE_ERROR");
			break;
		case NE_TIMEOUT:
			GSETCODE(err, 500, "Request Timeout");
			break;
		case NE_CONNECT:
			GSETCODE(err, 500, "Request Connection timeout");
			break;
		default:
			GSETCODE(err, 500, "Request failed");
			break;
	}

end_attr:
	if (NULL != req_str)
		g_string_free(req_str, TRUE);
	if (NULL != r)
		ne_request_destroy (r);
	if (NULL != s)
		ne_session_destroy (s);

	return result;
}
示例#22
0
文件: util.c 项目: DJEX93/dsploit
/* See doc string for svn_ra_neon__parsed_request. */
static svn_error_t *
parsed_request(svn_ra_neon__request_t *req,
               svn_ra_neon__session_t *ras,
               const char *method,
               const char *url,
               const char *body,
               apr_file_t *body_file,
               void set_parser(ne_xml_parser *parser,
                               void *baton),
               svn_ra_neon__startelm_cb_t startelm_cb,
               svn_ra_neon__cdata_cb_t cdata_cb,
               svn_ra_neon__endelm_cb_t endelm_cb,
               void *baton,
               apr_hash_t *extra_headers,
               int *status_code,
               svn_boolean_t spool_response,
               apr_pool_t *pool)
{
  ne_xml_parser *success_parser = NULL;
  spool_reader_baton_t spool_reader_baton;

  if (body == NULL)
    SVN_ERR(svn_ra_neon__set_neon_body_provider(req, body_file));

  /* ### use a symbolic name somewhere for this MIME type? */
  ne_add_request_header(req->ne_req, "Content-Type", "text/xml");

  /* create a parser to read the normal response body */
  success_parser = svn_ra_neon__xml_parser_create(req, NULL,
                                                  startelm_cb, cdata_cb,
                                                  endelm_cb, baton);

  /* if our caller is interested in having access to this parser, call
     the SET_PARSER callback with BATON. */
  if (set_parser != NULL)
    set_parser(success_parser, baton);

  /* Register the "main" accepter and body-reader with the request --
     the one to use when the HTTP status is 2XX.  If we are spooling
     the response to disk first, we use our custom spool reader.  */
  if (spool_response)
    {
      /* Blow the temp-file away as soon as we eliminate the entire request */
      SVN_ERR(svn_io_open_unique_file3(&spool_reader_baton.spool_file,
                                       &spool_reader_baton.spool_file_name,
                                       NULL,
                                       svn_io_file_del_on_pool_cleanup,
                                       req->pool, pool));
      spool_reader_baton.req = req;

      svn_ra_neon__add_response_body_reader(req, ne_accept_2xx, spool_reader,
                                            &spool_reader_baton);
    }
  else
    attach_ne_body_reader(req, ne_accept_2xx, cancellation_callback,
                          get_cancellation_baton(req, ne_xml_parse_v,
                                                 success_parser, pool));

  /* run the request and get the resulting status code. */
  SVN_ERR(svn_ra_neon__request_dispatch(
              status_code, req, extra_headers, body,
              (strcmp(method, "PROPFIND") == 0) ? 207 : 200,
              0, pool));

  if (spool_response)
    {
      /* All done with the temporary file we spooled the response into. */
      (void) apr_file_close(spool_reader_baton.spool_file);

      /* The success parser may set an error value in req->err */
      SVN_RA_NEON__REQ_ERR
        (req, parse_spool_file(ras, spool_reader_baton.spool_file_name,
                               success_parser, req->pool));
      if (req->err)
        {
          svn_error_compose(req->err, svn_error_createf
                            (SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                             _("Error reading spooled %s request response"),
                             method));
          return req->err;
        }
    }

  SVN_ERR(svn_ra_neon__check_parse_error(method, success_parser, url));

  return SVN_NO_ERROR;
}
示例#23
0
文件: rawx.c 项目: amogrid/redcurrant
gs_status_t rawx_delete (gs_chunk_t *chunk, GError **err)
{
	char str_req_id [1024];
	char str_addr [STRLEN_ADDRINFO];
	char str_ci [STRLEN_CHUNKID];
	char cPath [CI_FULLPATHLEN];
	char str_hash[STRLEN_CHUNKHASH];

	ne_request *request=NULL;
	ne_session *session=NULL;
	
	memset(str_req_id, 0x00, sizeof(str_req_id));

	if (!chunk || !chunk->ci || !chunk->content)
	{
		GSETERROR (err,"Invalid parameter (bad chunk structure)");
		goto error_label;
	}

	addr_info_to_string (&(chunk->ci->id.addr), str_addr, sizeof(str_addr));
	chunk_id2str(chunk, str_ci, sizeof(str_ci));
	chunk_getpath (chunk, cPath, sizeof(cPath));
	DEBUG("about to delete %s on %s", str_ci, cPath);

	gscstat_tags_start(GSCSTAT_SERVICE_RAWX, GSCSTAT_TAGS_REQPROCTIME);

	session = rawx_opensession (chunk, err);
	if (!session)
	{
		GSETERROR (err, "Cannot open a webdav session");
		goto error_label;
	}

	/*Create a webdav request*/
	do {
		request = ne_request_create (session, RAWX_DELETE, cPath);
		if (!request)
		{
			GSETERROR (err, "cannot create a %s WebDAV request", RAWX_DELETE);
			goto error_label;
		}

	} while (0);

	chunk_id2str (chunk, str_ci, sizeof(str_ci));
	chunk_gethash (chunk, str_hash, sizeof(str_hash));

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


	ne_add_request_header  (request, "chunkid",     str_ci);
	ne_add_request_header  (request, "chunkhash",   str_hash);
	ne_add_request_header  (request, "containerid", C1_IDSTR(chunk->content));
	ne_add_request_header  (request, "contentpath", chunk->content->info.path);
	ne_print_request_header(request, "chunkpos",    "%"G_GUINT32_FORMAT, chunk->ci->position);
	ne_print_request_header(request, "chunknb",     "%"G_GUINT32_FORMAT, chunk->ci->nb);
	ne_print_request_header(request, "chunksize",   "%"G_GINT64_FORMAT, chunk->ci->size);
	ne_print_request_header(request, "contentsize", "%"G_GINT64_FORMAT, chunk->content->info.size);

	/*now perform the request*/
	switch (ne_request_dispatch (request))
	{
		case NE_OK:
			if (ne_get_status(request)->klass != 2) {
				GSETERROR (err, "cannot delete '%s' (%s) (ReqId:%s)", cPath, ne_get_error(session), str_req_id);
				goto error_label;
			}
			DEBUG("chunk deletion finished (success) : %s", cPath);
			break;
		case NE_AUTH:
		case NE_CONNECT:
		case NE_TIMEOUT:
		case NE_ERROR:
			GSETERROR (err, "unexpected error from the WebDAV server (%s) (ReqId:%s)", ne_get_error(session), str_req_id);
			goto error_label;
	}

	ne_request_destroy (request);
	ne_session_destroy (session);
	
	TRACE("%s deleted (ReqId:%s)", cPath, str_req_id);

	gscstat_tags_end(GSCSTAT_SERVICE_RAWX, GSCSTAT_TAGS_REQPROCTIME);

	return 1;
error_label:
	TRACE("could not delete %s", cPath);
	if (request)
		ne_request_destroy (request);
	if (session)
		ne_session_destroy (session);

	gscstat_tags_end(GSCSTAT_SERVICE_RAWX, GSCSTAT_TAGS_REQPROCTIME);

	return 0;
}
示例#24
0
int ne_lock(ne_session *sess, struct ne_lock *lock) 
{
    ne_request *req = ne_request_create(sess, "LOCK", lock->uri.path);
    ne_buffer *body = ne_buffer_create();
    ne_xml_parser *parser = ne_xml_create();
    int ret, parse_failed;
    struct lock_ctx ctx;

    memset(&ctx, 0, sizeof ctx);
    ctx.cdata = ne_buffer_create();    
    ctx.req = req;

    ne_xml_push_handler(parser, lk_startelm, lk_cdata, lk_endelm, &ctx);
    
    /* Create the body */
    ne_buffer_concat(body, "<?xml version=\"1.0\" encoding=\"utf-8\"?>" EOL
		    "<lockinfo xmlns='DAV:'>" EOL " <lockscope>",
		    lock->scope==ne_lockscope_exclusive?
		    "<exclusive/>":"<shared/>",
		    "</lockscope>" EOL
		    "<locktype><write/></locktype>", NULL);

    if (lock->owner) {
	ne_buffer_concat(body, "<owner>", lock->owner, "</owner>" EOL, NULL);
    }
    ne_buffer_zappend(body, "</lockinfo>" EOL);

    ne_set_request_body_buffer(req, body->data, ne_buffer_size(body));
    /* ne_add_request_header(req, "Content-Type", NE_XML_MEDIA_TYPE); */
    /* Just to test whether sever accepts both text/xml and application/xml */
    ne_add_request_header(req, "Content-Type", "text/xml");
    ne_add_depth_header(req, lock->depth);
    add_timeout_header(req, lock->timeout);
    
    /* TODO: 
     * By 2518, we need this only if we are creating a lock-null resource.
     * Since we don't KNOW whether the lock we're given is a lock-null
     * or not, we cover our bases.
     */
    ne_lock_using_parent(req, lock->uri.path);
    /* This one is clearer from 2518 sec 8.10.4. */
    ne_lock_using_resource(req, lock->uri.path, lock->depth);

    ret = ne_xml_dispatch_request(req, parser);

    ne_buffer_destroy(body);
    ne_buffer_destroy(ctx.cdata);
    parse_failed = ne_xml_failed(parser);
    
    if (ret == NE_OK && ne_get_status(req)->klass == 2) {
	if (ctx.token == NULL) {
	    ret = NE_ERROR;
	    ne_set_error(sess, _("No Lock-Token header given"));
	}
	else if (parse_failed) {
	    ret = NE_ERROR;
	    ne_set_error(sess, "%s", ne_xml_get_error(parser));
	}
	else if (ne_get_status(req)->code == 207) {
	    ret = NE_ERROR;
	    /* TODO: set the error string appropriately */
	}
	else if (ctx.found) {
	    /* it worked: copy over real lock details if given. */
            if (lock->token) ne_free(lock->token);
	    lock->token = ctx.token;
            ctx.token = NULL;
	    if (ctx.active.timeout != NE_TIMEOUT_INVALID)
		lock->timeout = ctx.active.timeout;
	    lock->scope = ctx.active.scope;
	    lock->type = ctx.active.type;
	    if (ctx.active.depth >= 0)
		lock->depth = ctx.active.depth;
	    if (ctx.active.owner) {
		if (lock->owner) ne_free(lock->owner);
		lock->owner = ctx.active.owner;
		ctx.active.owner = NULL;
	    }
	} else {
	    ret = NE_ERROR;
	    ne_set_error(sess, _("Response missing activelock for %s"), 
			 ctx.token);
	}
    } else if (ret == NE_OK /* && status != 2xx */) {
	ret = NE_ERROR;
    }

    ne_lock_free(&ctx.active);
    if (ctx.token) ne_free(ctx.token);
    ne_request_destroy(req);
    ne_xml_destroy(parser);

    return ret;
}
示例#25
0
/* Gets a file from the owncloud url to the open file descriptor. */
static int owncloud_get(csync_vio_method_handle_t *flocal,
                        csync_vio_method_handle_t *fremote,
                        csync_vio_file_stat_t *vfs) {
  int rc = 0;
  int neon_stat;
  const ne_status *status;
  int fd;

  struct transfer_context *write_ctx = (struct transfer_context*) fremote;
  (void) vfs; /* stat information of the source file */

  fd = csync_vio_getfd(flocal);
  if (fd == -1) {
    errno = EINVAL;
    return -1;
  }

  /* GET a file to the open file descriptor */
  if( write_ctx == NULL ) {
    errno = EINVAL;
    return -1;
  }

  if( write_ctx->req == NULL ) {
    errno = EINVAL;
    return -1;
  }

  DEBUG_WEBDAV("  -- GET on %s", write_ctx->url);

  write_ctx->fd = fd;

  /* Allow compressed content by setting the header */
  ne_add_request_header( write_ctx->req, "Accept-Encoding", "gzip,deflate" );

  /* hook called before the content is parsed to set the correct reader,
         * either the compressed- or uncompressed reader.
         */
  ne_hook_post_headers( dav_session.ctx, install_content_reader, write_ctx );

  neon_stat = ne_request_dispatch(write_ctx->req );
  /* possible return codes are:
   *  NE_OK, NE_AUTH, NE_CONNECT, NE_TIMEOUT, NE_ERROR (from ne_request.h)
   */

  if( neon_stat != NE_OK ) {
    set_errno_from_neon_errcode(neon_stat);
    DEBUG_WEBDAV("Error GET: Neon: %d, errno %d", neon_stat, errno);
    rc = -1;
  } else {
    status = ne_get_status( write_ctx->req );
    if( status->klass != 2 ) {
      DEBUG_WEBDAV("sendfile request failed with http status %d!", status->code);
      set_errno_from_http_errcode( status->code );
      /* decide if soft error or hard error that stops the whole sync. */
      /* Currently all problems concerning one file are soft errors */
      if( status->klass == 4 /* Forbidden and stuff, soft error */ ) {
        rc = 1;
      } else if( status->klass == 5 /* Server errors and such */ ) {
        rc = 1; /* No Abort on individual file errors. */
      } else {
        rc = 1;
      }
    } else {
      DEBUG_WEBDAV("http request all cool, result code %d (%s)", status->code,
                   status->reason_phrase ? status->reason_phrase : "<empty>");
    }
  }

  /* delete the hook again, otherwise they get chained as they are with the session */
  ne_unhook_post_headers( dav_session.ctx, install_content_reader, write_ctx );

  /* if the compression handle is set through the post_header hook, delete it. */
  if( write_ctx->decompress ) {
    ne_decompress_destroy( write_ctx->decompress );
  }

  return rc;
}
示例#26
0
文件: netxml-ups.c 项目: balooloo/nut
/**
 *  \brief  Send HTTP request over a session
 *
 *  The function creates HTTP request, sends it and reads-out the response.
 *
 *  \param[in]   session    HTTP session
 *  \param[in]   method     Request method
 *  \param[in]   uri        Request URI
 *  \param[in]   ct         Request content type (optional, \c NULL accepted)
 *  \param[in]   req_body   Request body (optional, \c NULL is accepted)
 *  \param[out]  resp_body  Response body (optional, \c NULL is accepted)
 *
 *  \return HTTP status code if response was sent, 0 on send error
 */
static int send_http_request(
	ne_session *session,
	const char *method,
	const char *uri,
	const char *ct,
	ne_buffer  *req_body,
	ne_buffer  *resp_body)
{
	int resp_code = 0;

	ne_request *req = NULL;

	/* Create request */
	req = ne_request_create(session, method, uri);

	/* Neon claims that request creation is always successful */
	assert(NULL != req);

	do {  /* Pragmatic do ... while (0) loop allowing breaks on error */
		const ne_status *req_st;

		/* Set Content-Type */
		if (NULL != ct)
			ne_add_request_header(req, "Content-Type", ct);

		/* Set request body */
		if (NULL != req_body)
			/* BEWARE: The terminating '\0' byte is "used", too */
			ne_set_request_body_buffer(req,
				req_body->data, req_body->used - 1);

		/* Send request */
		int status = ne_begin_request(req);

		if (NE_OK != status) {
			break;
		}

		/* Read response */
		assert(NE_OK == status);

		for (;;) {
			char buff[512];

			ssize_t read;

			read = ne_read_response_block(req, buff, sizeof(buff));

			/* Read failure */
			if (0 > read) {
				status = NE_ERROR;

				break;
			}

			if (0 == read)
				break;

			if (NULL != resp_body)
				ne_buffer_append(resp_body, buff, read);
		}

		if (NE_OK != status) {
			break;
		}

		/* Request served */
		ne_end_request(req);

		/* Get response code */
		req_st = ne_get_status(req);

		assert(NULL != req_st);

		resp_code = req_st->code;

	} while (0);  /* end of do ... while (0) pragmatic loop */

	if (NULL != req)
		ne_request_destroy(req);

	return resp_code;
}