@@ -239,6 +239,25 @@ static char* _net_get_verb(http_verb verb) {
239239 return NULL ;
240240}
241241
242+ static char * _escape_url (const char * url ) {
243+ return curl_easy_escape (NULL , url , 0 );
244+ }
245+
246+ // Like _escape_url but don't encode "/".
247+ static char * _escape_url_object_name (const char * url ) {
248+ gchar * * split = g_strsplit (url , "/" , 0 );
249+ gchar * * ptr ;
250+ gchar * escaped_ptr ;
251+ for (ptr = split ; * ptr ; ptr ++ ) {
252+ escaped_ptr = _escape_url (* ptr );
253+ g_free (* ptr );
254+ * ptr = escaped_ptr ;
255+ }
256+ escaped_ptr = g_strjoinv ("/" , split );
257+ g_strfreev (split );
258+ return escaped_ptr ;
259+ }
260+
242261static unsigned char * _generate_signature_str (http_verb verb , char * resource_name , char * date ,
243262 char * content_type , char * md5 , char * amz_headers ) {
244263 char * verb_str ;
@@ -529,8 +548,10 @@ ds3_client* ds3_create_client(const char* endpoint, ds3_creds* creds) {
529548
530549static void _set_query_param (ds3_request * _request , const char * key , const char * value ) {
531550 struct _ds3_request * request = (struct _ds3_request * ) _request ;
551+ gpointer escaped_key = (gpointer ) _escape_url (key );
552+ gpointer escaped_value = (gpointer ) _escape_url (value );
532553
533- g_hash_table_insert (request -> query_params , ( gpointer ) key , ( gpointer ) g_strdup ( value ) );
554+ g_hash_table_insert (request -> query_params , escaped_key , escaped_value );
534555}
535556
536557void ds3_client_proxy (ds3_client * client , const char * proxy ) {
@@ -556,77 +577,71 @@ void ds3_request_set_max_keys(ds3_request* _request, uint32_t max_keys) {
556577 _set_query_param (_request , "max-keys" , max_keys_s );
557578}
558579
559- static struct _ds3_request * _common_request_init (void ){
580+ static struct _ds3_request * _common_request_init (http_verb verb , const char * path_prefix , const char * bucket_name , const char * object_name ){
560581 struct _ds3_request * request = g_new0 (struct _ds3_request , 1 );
582+ char * escaped_bucket_name = NULL ;
583+ char * escaped_object_name = NULL ;
584+ char * joined_path = NULL ;
561585 request -> headers = _create_hash_table ();
562586 request -> query_params = _create_hash_table ();
587+ request -> verb = verb ;
588+ if (bucket_name != NULL ) {
589+ escaped_bucket_name = _escape_url (bucket_name );
590+ }
591+ if (object_name != NULL ) {
592+ escaped_object_name = _escape_url_object_name (object_name );
593+ }
594+ joined_path = g_strjoin ("/" , escaped_bucket_name , escaped_object_name , NULL );
595+ request -> path = g_strconcat (path_prefix , joined_path , NULL );
596+ g_free (joined_path );
597+ if (escaped_bucket_name != NULL ) {
598+ g_free (escaped_bucket_name );
599+ }
600+ if (escaped_object_name != NULL ) {
601+ g_free (escaped_object_name );
602+ }
563603 return request ;
564604}
565605
566606ds3_request * ds3_init_get_service (void ) {
567- struct _ds3_request * request = _common_request_init ();
568- request -> verb = HTTP_GET ;
569- request -> path = g_new0 (char , 2 );
570- request -> path [0 ] = '/' ;
571- return (ds3_request * ) request ;
607+ return (ds3_request * ) _common_request_init (HTTP_GET , "/" , NULL , NULL );
572608}
573609
574610ds3_request * ds3_init_get_bucket (const char * bucket_name ) {
575- struct _ds3_request * request = _common_request_init ();
576- request -> verb = HTTP_GET ;
577- request -> path = g_strconcat ("/" , bucket_name , NULL );
578- return (ds3_request * ) request ;
611+ return (ds3_request * ) _common_request_init (HTTP_GET , "/" , bucket_name , NULL );
579612}
580613
581614ds3_request * ds3_init_get_object (const char * bucket_name , const char * object_name ) {
582- struct _ds3_request * request = _common_request_init ();
583- request -> verb = HTTP_GET ;
584- request -> path = g_strconcat ("/" , bucket_name , "/" , object_name , NULL );
585- return (ds3_request * ) request ;
615+ return (ds3_request * ) _common_request_init (HTTP_GET , "/" , bucket_name , object_name );
586616}
587617
588618ds3_request * ds3_init_delete_object (const char * bucket_name , const char * object_name ) {
589- struct _ds3_request * request = _common_request_init ();
590- request -> verb = HTTP_DELETE ;
591- request -> path = g_strconcat ("/" , bucket_name , "/" , object_name , NULL );
592- return (ds3_request * ) request ;
619+ return (ds3_request * ) _common_request_init (HTTP_DELETE , "/" , bucket_name , object_name );
593620}
594621
595622ds3_request * ds3_init_put_object (const char * bucket_name , const char * object_name , uint64_t length ) {
596- struct _ds3_request * request = _common_request_init ();
597- request -> verb = HTTP_PUT ;
598- request -> path = g_strconcat ("/" , bucket_name , "/" , object_name , NULL );
623+ struct _ds3_request * request = _common_request_init (HTTP_PUT , "/" , bucket_name , object_name );
599624 request -> length = length ;
600625 return (ds3_request * ) request ;
601626}
602627
603628ds3_request * ds3_init_put_bucket (const char * bucket_name ) {
604- struct _ds3_request * request = _common_request_init ();
605- request -> verb = HTTP_PUT ;
606- request -> path = g_strconcat ("/" , bucket_name , NULL );
607- return (ds3_request * ) request ;
629+ return (ds3_request * ) _common_request_init (HTTP_PUT , "/" , bucket_name , NULL );
608630}
609631
610632ds3_request * ds3_init_delete_bucket (const char * bucket_name ) {
611- struct _ds3_request * request = _common_request_init ();
612- request -> verb = HTTP_DELETE ;
613- request -> path = g_strconcat ("/" , bucket_name , NULL );
614- return (ds3_request * ) request ;
633+ return (ds3_request * ) _common_request_init (HTTP_DELETE , "/" , bucket_name , NULL );
615634}
616635
617636ds3_request * ds3_init_get_bulk (const char * bucket_name , ds3_bulk_object_list * object_list ) {
618- struct _ds3_request * request = _common_request_init ();
619- request -> verb = HTTP_PUT ;
620- request -> path = g_strconcat ("/_rest_/bucket/" , bucket_name , NULL );
637+ struct _ds3_request * request = _common_request_init (HTTP_PUT , "/_rest_/bucket/" , bucket_name , NULL );
621638 _set_query_param ((ds3_request * ) request , "operation" , "start_bulk_get" );
622639 request -> object_list = object_list ;
623640 return (ds3_request * ) request ;
624641}
625642
626643ds3_request * ds3_init_put_bulk (const char * bucket_name , ds3_bulk_object_list * object_list ) {
627- struct _ds3_request * request = _common_request_init ();
628- request -> verb = HTTP_PUT ;
629- request -> path = g_strconcat ("/_rest_/bucket/" , bucket_name , NULL );
644+ struct _ds3_request * request = _common_request_init (HTTP_PUT , "/_rest_/bucket/" , bucket_name , NULL );
630645 _set_query_param ((ds3_request * ) request , "operation" , "start_bulk_put" );
631646 request -> object_list = object_list ;
632647 return (ds3_request * ) request ;
0 commit comments