Exemple #1
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);
}
Exemple #2
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. */
}
Exemple #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

    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);
}
Exemple #4
0
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);
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
0
int s3_put_object(S3 *s3,const char *bucket,const char *key,const char *content_type,int content_length,const S3ReadCallback *rcb)
{
	ne_request *req;
	int err, retry;

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

	s3_begin_session(s3);

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

	ne_print_request_header(req,"Content-Length","%d",content_length);

#ifdef NE_LFS
	ne_set_request_body_provider64(req,content_length,rcb->callback,rcb->userdata);
#else
	ne_set_request_body_provider(req,content_length,rcb->callback,rcb->userdata);
#endif

	//ne_set_request_body_buffer(req,"hello",5);
	// 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;
			}
			retry = ne_end_request(req);
		}
	} while(retry == NE_RETRY);

	ne_request_destroy(req);
	s3_end_session(s3);

	return err;
}
Exemple #8
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;
}
Exemple #9
0
static int open_request (struct neon_handle * handle, uint64_t startbyte)
{
    int ret;
    const ne_status * status;
    ne_uri * rediruri;

    if (handle->purl->query && * (handle->purl->query))
    {
        SCONCAT3 (tmp, handle->purl->path, "?", handle->purl->query);
        handle->request = ne_request_create (handle->session, "GET", tmp);
    }
    else
        handle->request = ne_request_create (handle->session, "GET", handle->purl->path);

    if (startbyte > 0)
        ne_print_request_header (handle->request, "Range", "bytes=%"PRIu64"-", startbyte);

    ne_print_request_header (handle->request, "Icy-MetaData", "1");

    /* Try to connect to the server. */
    _DEBUG ("<%p> Connecting...", handle);
    ret = ne_begin_request (handle->request);
    status = ne_get_status (handle->request);
    _DEBUG ("<%p> Return: %d, Status: %d", handle, ret, status->code);

    if (ret == NE_OK)
    {
        switch (status->code)
        {
        case 401:
            /* Authorization required. Reconnect to authenticate */
            _DEBUG ("Reconnecting due to 401");
            ne_end_request (handle->request);
            ret = ne_begin_request (handle->request);
            break;

        case 301:
        case 302:
        case 303:
        case 307:
            /* Redirect encountered. Reconnect. */
            ne_end_request (handle->request);
            ret = NE_REDIRECT;
            break;

        case 407:
            /* Proxy auth required. Reconnect to authenticate */
            _DEBUG ("Reconnecting due to 407");
            ne_end_request (handle->request);
            ret = ne_begin_request (handle->request);
            break;
        }
    }

    switch (ret)
    {
    case NE_OK:
        if (status->code > 199 && status->code < 300)
        {
            /* URL opened OK */
            _DEBUG ("<%p> URL opened OK", handle);
            handle->content_start = startbyte;
            handle->pos = startbyte;
            handle_headers (handle);
            return 0;
        }

        break;

    case NE_REDIRECT:
        /* We hit a redirect. Handle it. */
        _DEBUG ("<%p> Redirect encountered", handle);
        handle->redircount += 1;
        rediruri = (ne_uri *) ne_redirect_location (handle->session);
        ne_request_destroy (handle->request);
        handle->request = NULL;

        if (! rediruri)
        {
            _ERROR ("<%p> Could not parse redirect response", (void *) handle);
            return -1;
        }

        ne_uri_free (handle->purl);
        ne_uri_copy (handle->purl, rediruri);
        return 1;
    }

    /* Something went wrong. */
    _ERROR ("<%p> Could not open URL: %d (%d)", (void *) handle, ret, status->code);

    if (ret)
        _ERROR ("<%p> neon error string: %s", (void *) handle, ne_get_error (handle->session));

    ne_request_destroy (handle->request);
    handle->request = NULL;
    return -1;
}
Exemple #10
0
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;
}
/* 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;
}
Exemple #12
0
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;
}