@@ -307,6 +307,27 @@ apr_table_t* _mapcache_cache_rest_headers(mapcache_context *ctx, mapcache_tile *
307307 return ret ;
308308}
309309
310+ /* Converts an integer value to its hex character*/
311+ static char to_hex (char code ) {
312+ static char hex [] = "0123456789ABCDEF" ;
313+ return hex [code & 15 ];
314+ }
315+
316+ /* Returns a url-encoded version of str */
317+ static char * url_encode (apr_pool_t * pool , char * str ) {
318+ char * pstr = str , * buf = apr_pcalloc (pool , strlen (str ) * 3 + 1 ), * pbuf = buf ;
319+ while (* pstr ) {
320+ if (isalnum (* pstr ) || * pstr == '-' || * pstr == '_' || * pstr == '.' || * pstr == '~' || * pstr == '/' )
321+ * pbuf ++ = * pstr ;
322+ else if (* pstr == ' ' )
323+ * pbuf ++ = '+' ;
324+ else
325+ * pbuf ++ = '%' , * pbuf ++ = to_hex (* pstr >> 4 ), * pbuf ++ = to_hex (* pstr & 15 );
326+ pstr ++ ;
327+ }
328+ * pbuf = '\0' ;
329+ return buf ;
330+ }
310331/**
311332 * \brief return url for given tile given a template
312333 *
@@ -319,6 +340,8 @@ apr_table_t* _mapcache_cache_rest_headers(mapcache_context *ctx, mapcache_tile *
319340static void _mapcache_cache_rest_tile_url (mapcache_context * ctx , mapcache_tile * tile , mapcache_rest_configuration * config ,
320341 mapcache_rest_operation * operation , char * * url )
321342{
343+ char * slashptr ,* path ;
344+ int cnt = 0 ;
322345 if (operation && operation -> tile_url ) {
323346 * url = apr_pstrdup (ctx -> pool , operation -> tile_url );
324347 } else {
@@ -360,31 +383,29 @@ static void _mapcache_cache_rest_tile_url(mapcache_context *ctx, mapcache_tile *
360383 }
361384 * url = mapcache_util_str_replace (ctx -> pool ,* url , "{dim}" , dimstring );
362385 }
363- }
364-
365- /* Converts an integer value to its hex character*/
366- static char to_hex (char code ) {
367- static char hex [] = "0123456789abcdef" ;
368- return hex [code & 15 ];
369- }
386+ /* url-encode everything after the host name */
370387
371- /* Returns a url-encoded version of str */
372- /* IMPORTANT: be sure to free() the returned string after use */
373- static char * url_encode (char * str ) {
374- char * pstr = str , * buf = malloc (strlen (str ) * 3 + 1 ), * pbuf = buf ;
375- while (* pstr ) {
376- if (isalnum (* pstr ) || * pstr == '-' || * pstr == '_' || * pstr == '.' || * pstr == '~' || * pstr == '/' )
377- * pbuf ++ = * pstr ;
378- else if (* pstr == ' ' )
379- * pbuf ++ = '+' ;
380- else
381- * pbuf ++ = '%' , * pbuf ++ = to_hex (* pstr >> 4 ), * pbuf ++ = to_hex (* pstr & 15 );
382- pstr ++ ;
388+ /* find occurence of third "/" in url */
389+ slashptr = * url ;
390+ while (* slashptr ) {
391+ if (* slashptr == '/' ) cnt ++ ;
392+ if (cnt == 3 ) break ;
393+ slashptr ++ ;
383394 }
384- * pbuf = '\0' ;
385- return buf ;
395+ if (!* slashptr ) {
396+ ctx -> set_error (ctx ,500 ,"invalid rest url provided, expecting http(s)://server/path format" );
397+ return ;
398+ }
399+ path = slashptr ;
400+ path = url_encode (ctx -> pool ,path );
401+ * slashptr = 0 ;
402+
403+
404+ * url = apr_pstrcat (ctx -> pool ,* url ,path ,NULL );
405+ /*ctx->log(ctx,MAPCACHE_WARN,"rest url: %s",*url);*/
386406}
387407
408+
388409// Simple comparison function for comparing two HTTP header names that are
389410// embedded within an HTTP header line, returning true if header1 comes
390411// before header2 alphabetically, false if not
@@ -496,12 +517,9 @@ static void _mapcache_cache_google_headers_add(mapcache_context *ctx, const char
496517 ctx -> set_error (ctx ,500 ,"invalid google url provided" );
497518 return ;
498519 }
499- resource = url_encode (resource );
500520
501521 stringToSign = apr_pstrcat (ctx -> pool , stringToSign , resource , NULL );
502522
503- free (resource );
504-
505523 hmac_sha1 (stringToSign , strlen (stringToSign ), (unsigned char * )google -> secret , strlen (google -> secret ), sha );
506524
507525 apr_base64_encode (b64 , (char * )sha , 20 );
@@ -582,14 +600,11 @@ static void _mapcache_cache_azure_headers_add(mapcache_context *ctx, const char*
582600 ctx -> set_error (ctx ,500 ,"invalid azure url provided" );
583601 return ;
584602 }
585- resource = url_encode (resource );
586603
587604 canonical_resource = apr_pstrcat (ctx -> pool , "/" , azure -> id , resource , NULL );
588605
589606 stringToSign = apr_pstrcat (ctx -> pool , stringToSign , canonical_headers , canonical_resource , NULL );
590607
591- free (resource );
592-
593608 keyub64 = (char * )apr_pcalloc (ctx -> pool , apr_base64_decode_len (azure -> secret ));
594609 apr_base64_decode (keyub64 , azure -> secret );
595610
@@ -641,10 +656,8 @@ static void _mapcache_cache_s3_headers_add(mapcache_context *ctx, const char* me
641656
642657 strftime (x_amz_date , sizeof (x_amz_date ), "%Y%m%dT%H%M%SZ" , tnow );
643658 apr_table_set (headers , "x-amz-date" , x_amz_date );
644- resource = url_encode (resource );
645659
646660 canonical_request = apr_pstrcat (ctx -> pool , method , "\n" ,resource , "\n\n" ,NULL );
647- free (resource );
648661
649662 ahead = apr_table_elts (headers );
650663 aheaders = apr_pcalloc (ctx -> pool , ahead -> nelts * sizeof (char * ));
0 commit comments