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); }
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. */ }
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); }
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); }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }