if((type != FOLLOW_RETRY) &&
(data->req.httpcode != 401) && (data->req.httpcode != 407) &&
- Curl_is_absolute_url(newurl, NULL, 0))
+ Curl_is_absolute_url(newurl, NULL, 0, FALSE))
/* If this is not redirect due to a 401 or 407 response and an absolute
URL: don't allow a custom port number */
disallowport = TRUE;
CURLU_ALLOW_SPACE |
(data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
if(uc) {
- if(type != FOLLOW_FAKE)
+ if(type != FOLLOW_FAKE) {
+ failf(data, "The redirect target URL could not be parsed: %s",
+ curl_url_strerror(uc));
return Curl_uc_to_curlcode(uc);
+ }
/* the URL could not be parsed for some reason, but since this is FAKE
mode, just duplicate the field as-is */
* Returns the length of the scheme if the given URL is absolute (as opposed
* to relative). Stores the scheme in the buffer if TRUE and 'buf' is
* non-NULL. The buflen must be larger than MAX_SCHEME_LEN if buf is set.
+ *
+ * If 'guess_scheme' is TRUE, it means the URL might be provided without
+ * scheme.
*/
-size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
+size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
+ bool guess_scheme)
{
int i;
DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN));
if(buf)
buf[0] = 0; /* always leave a defined value in buf */
#ifdef WIN32
- if(STARTS_WITH_DRIVE_PREFIX(url))
+ if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url))
return 0;
#endif
for(i = 0; i < MAX_SCHEME_LEN; ++i) {
break;
}
}
- if(i && (url[i] == ':') && (url[i + 1] == '/')) {
+ if(i && (url[i] == ':') && ((url[i + 1] == '/') || !guess_scheme)) {
+ /* If this does not guess scheme, the scheme always ends with the colon so
+ that this also detects data: URLs etc. In guessing mode, data: could
+ be the host name "data" with a specified port number. */
+
/* the length of the scheme is the name part only */
size_t len = i;
if(buf) {
goto fail;
}
- schemelen = Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf));
+ schemelen = Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf),
+ flags & (CURLU_GUESS_SCHEME|
+ CURLU_DEFAULT_SCHEME));
/* handle the file: scheme */
if(schemelen && !strcmp(schemebuf, "file")) {
p++;
i++;
}
- if((i < 1) || (i>3)) {
- /* less than one or more than three slashes */
- result = CURLUE_BAD_SLASHES;
- goto fail;
- }
schemep = schemebuf;
if(!Curl_builtin_scheme(schemep) &&
goto fail;
}
+ if((i < 1) || (i>3)) {
+ /* less than one or more than three slashes */
+ result = CURLUE_BAD_SLASHES;
+ goto fail;
+ }
if(junkscan(schemep, flags)) {
result = CURLUE_BAD_SCHEME;
goto fail;
/* if the new thing is absolute or the old one is not
* (we could not get an absolute url in 'oldurl'),
* then replace the existing with the new. */
- if(Curl_is_absolute_url(part, NULL, 0)
+ if(Curl_is_absolute_url(part, NULL, 0,
+ flags & (CURLU_GUESS_SCHEME|
+ CURLU_DEFAULT_SCHEME))
|| curl_url_get(u, CURLUPART_URL, &oldurl, flags)) {
return parseurl_and_replace(part, u, flags);
}