Skip to content

Commit e95ddc3

Browse files
committed
rest caches: properly encode special characters in URL
1 parent 4069d68 commit e95ddc3

File tree

1 file changed

+42
-29
lines changed

1 file changed

+42
-29
lines changed

lib/cache_rest.c

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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 *
319340
static 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

Comments
 (0)