|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2017 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include <config.h>
|
|
Packit |
8f70b4 |
#include "trio.h"
|
|
Packit |
8f70b4 |
#include "xstring.h"
|
|
Packit |
8f70b4 |
#include <ctype.h>
|
|
Packit |
8f70b4 |
#include <assert.h>
|
|
Packit |
8f70b4 |
#include "url.h"
|
|
Packit |
8f70b4 |
#include "ascii_ctype.h"
|
|
Packit |
8f70b4 |
#include "ConnectionSlot.h"
|
|
Packit |
8f70b4 |
#include "bookmark.h"
|
|
Packit |
8f70b4 |
#include "misc.h"
|
|
Packit |
8f70b4 |
#include "log.h"
|
|
Packit |
8f70b4 |
#include "network.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
URL -> [PROTO://]CONNECT[[:]/PATH]
|
|
Packit |
8f70b4 |
CONNECT -> [USER[:PASS]@]HOST[:PORT]
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
exceptions:
|
|
Packit |
8f70b4 |
file:/PATH
|
|
Packit |
8f70b4 |
bm:BOOKMARK[/PATH]
|
|
Packit |
8f70b4 |
slot:SLOT[/PATH]
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static bool valid_slot(const char *s);
|
|
Packit |
8f70b4 |
static bool valid_bm(const char *s);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ParsedURL::ParsedURL(const char *url,bool proto_required,bool use_rfc1738)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
parse(url,proto_required,use_rfc1738);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
ParsedURL::~ParsedURL()
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void ParsedURL::parse(const char *url,bool proto_required,bool use_rfc1738)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
orig_url.set(url);
|
|
Packit |
8f70b4 |
xstring_c connect;
|
|
Packit |
8f70b4 |
const char *base=url;
|
|
Packit |
8f70b4 |
const char *scan=base;
|
|
Packit |
8f70b4 |
while(is_ascii_alpha(*scan))
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
if(scan[0]==':' && scan[1]=='/' && scan[2]=='/')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// found protocol
|
|
Packit |
8f70b4 |
proto.nset(base,scan-base);
|
|
Packit |
8f70b4 |
base=scan+=3;
|
|
Packit |
8f70b4 |
if(!strcmp(proto,"file") && scan[0]=='/')
|
|
Packit |
8f70b4 |
goto file_with_no_host;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(scan[0]==':' && !strncmp(base,"file:",5))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// special form for file protocol
|
|
Packit |
8f70b4 |
proto.nset(base,scan-base);
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
file_with_no_host:
|
|
Packit |
8f70b4 |
path.set(scan);
|
|
Packit |
8f70b4 |
host.set("localhost");
|
|
Packit |
8f70b4 |
goto decode;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(scan[0]==':'
|
|
Packit |
8f70b4 |
&& ((!strncmp(base,"slot:",5) && valid_slot(scan+1))
|
|
Packit |
8f70b4 |
|| (!strncmp(base,"bm:",3) && valid_bm(scan+1))))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// special form for selecting a connection slot or a bookmark
|
|
Packit |
8f70b4 |
proto.nset(base,scan-base);
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
base=scan;
|
|
Packit |
8f70b4 |
scan=strchr(scan,'/');
|
|
Packit |
8f70b4 |
if(scan)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
host.nset(base,scan-base);
|
|
Packit |
8f70b4 |
path.set(scan);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
host.set(base);
|
|
Packit |
8f70b4 |
goto decode;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(proto_required)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// all the rest is path, if protocol is required.
|
|
Packit |
8f70b4 |
path.set(base);
|
|
Packit |
8f70b4 |
goto decode;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
scan=base;
|
|
Packit |
8f70b4 |
while(*scan && *scan!='/')
|
|
Packit |
8f70b4 |
scan++; // skip host name, port and user:pass
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
connect.nset(base,scan-base-(scan>base && scan[-1]==':'));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(*scan=='/') // directory
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(scan[1]=='~')
|
|
Packit |
8f70b4 |
path.set(scan+1);
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if((!xstrcmp(proto,"ftp") || !xstrcmp(proto,"hftp"))
|
|
Packit |
8f70b4 |
&& use_rfc1738)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// special handling for ftp protocol.
|
|
Packit |
8f70b4 |
if(!strncasecmp(scan+1,"%2F",3))
|
|
Packit |
8f70b4 |
path.set(scan+1);
|
|
Packit |
8f70b4 |
else if(!(is_ascii_alpha(scan[1]) && scan[2]==':' && scan[3]=='/'))
|
|
Packit |
8f70b4 |
path.vset("~",scan,NULL);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
path.set(scan);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(proto)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!strcmp(proto,"http") || !strcmp(proto,"https"))
|
|
Packit |
8f70b4 |
path.set("/");
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// try to extract user name/password
|
|
Packit |
8f70b4 |
base=connect;
|
|
Packit |
8f70b4 |
scan=strrchr(base,'@');
|
|
Packit |
8f70b4 |
if(scan)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
user.nset(base,scan-base);
|
|
Packit |
8f70b4 |
base=scan+1;
|
|
Packit |
8f70b4 |
scan=user;
|
|
Packit |
8f70b4 |
while(*scan && *scan!=':')
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
if(*scan==':')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
pass.set(scan+1);
|
|
Packit |
8f70b4 |
user.truncate(scan-user);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
// extract host name
|
|
Packit |
8f70b4 |
scan=base;
|
|
Packit |
8f70b4 |
if(*scan=='[') // RFC2732 [ipv6]
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
while(*scan && *scan!=']')
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
if(*scan==']')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
host.nset(base+1,scan-base-2);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
scan=base;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(scan==base)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
while(*scan && *scan!=':')
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
host.nset(base,scan-base);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(*scan==':') // port found
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(strchr(scan+1,':')==0)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
port.set(scan+1);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
/* more than one colon - maybe it is ipv6 digital address */
|
|
Packit |
8f70b4 |
host.set(base);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
decode:
|
|
Packit |
8f70b4 |
user.url_decode();
|
|
Packit |
8f70b4 |
pass.url_decode();
|
|
Packit |
8f70b4 |
host.url_decode();
|
|
Packit |
8f70b4 |
path.url_decode();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(!xstrcmp(proto,"slot"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const FileAccess *fa=ConnectionSlot::FindSession(host);
|
|
Packit |
8f70b4 |
if(!fa)
|
|
Packit |
8f70b4 |
return;
|
|
Packit |
8f70b4 |
orig_url.set(0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
proto.set(fa->GetProto());
|
|
Packit |
8f70b4 |
user.set(fa->GetUser());
|
|
Packit |
8f70b4 |
pass.set(fa->GetPassword());
|
|
Packit |
8f70b4 |
host.set(fa->GetHostName());
|
|
Packit |
8f70b4 |
port.set(fa->GetPort());
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FA::Path cwd(fa->GetCwd());
|
|
Packit |
8f70b4 |
if(path)
|
|
Packit |
8f70b4 |
cwd.Change(path+(path[0]=='/'));
|
|
Packit |
8f70b4 |
path.set(cwd);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!xstrcmp(proto,"bm"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *bm=lftp_bookmarks.Lookup(host);
|
|
Packit |
8f70b4 |
if(!bm || !bm[0])
|
|
Packit |
8f70b4 |
return;
|
|
Packit |
8f70b4 |
const char *new_url=0;
|
|
Packit |
8f70b4 |
xstring u(bm);
|
|
Packit |
8f70b4 |
if(orig_url)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *new_path=orig_url+url::path_index(orig_url);
|
|
Packit |
8f70b4 |
if(new_path[0]=='/')
|
|
Packit |
8f70b4 |
new_path++;
|
|
Packit |
8f70b4 |
if(new_path[0]=='/' || new_path[0]=='~')
|
|
Packit |
8f70b4 |
u.truncate(url::path_index(u));
|
|
Packit |
8f70b4 |
assert(u[0]);
|
|
Packit |
8f70b4 |
if(u.last_char()!='/' && new_path[0]!='/')
|
|
Packit |
8f70b4 |
u.append('/');
|
|
Packit |
8f70b4 |
else if(u.last_char()=='/' && new_path[0]=='/')
|
|
Packit |
8f70b4 |
new_path++;
|
|
Packit |
8f70b4 |
u.append(new_path);
|
|
Packit |
8f70b4 |
new_url=u;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
new_url=url_file(bm,path+(path && path[0]=='/'));
|
|
Packit |
8f70b4 |
parse(new_url,proto_required,use_rfc1738);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
static bool valid_slot(const char *cs)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring& s=xstring::get_tmp(cs);
|
|
Packit |
8f70b4 |
s.truncate_at('/');
|
|
Packit |
8f70b4 |
s.url_decode();
|
|
Packit |
8f70b4 |
return 0!=ConnectionSlot::Find(s);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
static bool valid_bm(const char *bm)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring& s=xstring::get_tmp(bm);
|
|
Packit |
8f70b4 |
s.truncate_at('/');
|
|
Packit |
8f70b4 |
s.url_decode();
|
|
Packit |
8f70b4 |
const char *url=lftp_bookmarks.Lookup(s);
|
|
Packit |
8f70b4 |
return(url && !strchr(url,' ') && !strchr(url,'\t'));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int url::path_index(const char *base)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *scan=base;
|
|
Packit |
8f70b4 |
while(is_ascii_alpha(*scan))
|
|
Packit |
8f70b4 |
scan++;
|
|
Packit |
8f70b4 |
if(scan[0]!=':')
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
if(scan[1]=='/' && scan[2]=='/')
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// found protocol
|
|
Packit |
8f70b4 |
const char *slash=strchr(scan+3,'/');
|
|
Packit |
8f70b4 |
if(slash)
|
|
Packit |
8f70b4 |
return slash-base;
|
|
Packit |
8f70b4 |
return strlen(base);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(!strncmp(base,"file:",5))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// special form for file protocol
|
|
Packit |
8f70b4 |
return scan+1-base;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if((!strncmp(base,"slot:",5) && valid_slot(base+5))
|
|
Packit |
8f70b4 |
|| (!strncmp(base,"bm:",3) && valid_bm(base+3)))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
const char *slash=strchr(scan+1,'/');
|
|
Packit |
8f70b4 |
if(slash)
|
|
Packit |
8f70b4 |
return slash-base;
|
|
Packit |
8f70b4 |
return strlen(base);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *url::path_ptr(const char *base)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!base)
|
|
Packit |
8f70b4 |
return 0;
|
|
Packit |
8f70b4 |
return base+path_index(base);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
char *ParsedURL::Combine(const char *home,bool use_rfc1738)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
xstring buf("");
|
|
Packit |
8f70b4 |
return CombineTo(buf,home,use_rfc1738).borrow();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
xstring& ParsedURL::CombineTo(xstring& u,const char *home,bool use_rfc1738) const
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
bool is_file=!xstrcmp(proto,"file");
|
|
Packit |
8f70b4 |
bool is_ftp=(!xstrcmp(proto,"ftp") || !xstrcmp(proto,"hftp"));
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
if(proto)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
u.append(proto);
|
|
Packit |
8f70b4 |
u.append(is_file?":":"://");
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(user && !is_file)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
u.append(url::encode(user,URL_USER_UNSAFE));
|
|
Packit |
8f70b4 |
if(pass)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
u.append(':');
|
|
Packit |
8f70b4 |
u.append(url::encode(pass,URL_PASS_UNSAFE));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
u.append('@');
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(host && !is_file) {
|
|
Packit |
8f70b4 |
unsigned encode_flags=0;
|
|
Packit |
8f70b4 |
if(xtld_name_ok(host))
|
|
Packit |
8f70b4 |
encode_flags|=URL_ALLOW_8BIT;
|
|
Packit |
8f70b4 |
if(is_ipv6_address(host))
|
|
Packit |
8f70b4 |
u.append('[').append(host).append(']');
|
|
Packit |
8f70b4 |
else
|
|
Packit |
8f70b4 |
u.append_url_encoded(host,URL_HOST_UNSAFE,encode_flags);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(port && !is_file)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
u.append(':');
|
|
Packit |
8f70b4 |
u.append(url::encode(port,URL_PORT_UNSAFE));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
if(path && strcmp(path,"~"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(path[0]!='/' && !is_file) // e.g. ~/path
|
|
Packit |
8f70b4 |
u.append('/');
|
|
Packit |
8f70b4 |
int p_offset=0;
|
|
Packit |
8f70b4 |
if(is_ftp && use_rfc1738)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
// some cruft for ftp urls...
|
|
Packit |
8f70b4 |
if(path[0]=='/' && xstrcmp(home,"/"))
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
u.append("/%2F");
|
|
Packit |
8f70b4 |
p_offset=1;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
else if(path[0]=='~' && path[1]=='/')
|
|
Packit |
8f70b4 |
p_offset=2;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
u.append(url::encode(path+p_offset,URL_PATH_UNSAFE));
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
return u;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const xstring& url::decode(const char *p)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!p)
|
|
Packit |
8f70b4 |
return xstring::null;
|
|
Packit |
8f70b4 |
return xstring::get_tmp(p).url_decode();
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const xstring& url::encode(const char *s,int len,const char *unsafe,unsigned flags)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!s)
|
|
Packit |
8f70b4 |
return xstring::null;
|
|
Packit |
8f70b4 |
return xstring::get_tmp("").append_url_encoded(s,len,unsafe,flags);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool url::dir_needs_trailing_slash(const char *proto_c)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
if(!proto_c)
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
char *proto=alloca_strdup(proto_c);
|
|
Packit |
8f70b4 |
char *colon=strchr(proto,':');
|
|
Packit |
8f70b4 |
if(colon)
|
|
Packit |
8f70b4 |
*colon=0;
|
|
Packit |
8f70b4 |
return !strcasecmp(proto,"http")
|
|
Packit |
8f70b4 |
|| !strcasecmp(proto,"https");
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool url::find_password_pos(const char *url,int *start,int *len)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
*start=*len=0;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *scan=strstr(url,"://");
|
|
Packit |
8f70b4 |
if(!scan)
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
scan+=3;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *at=strchr(scan,'@');
|
|
Packit |
8f70b4 |
if(!at)
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *colon=strchr(scan,':');
|
|
Packit |
8f70b4 |
if(!colon || colon>at)
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *slash=strchr(scan,'/');
|
|
Packit |
8f70b4 |
if(slash && slash
|
|
Packit |
8f70b4 |
return false;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
*start=colon+1-url;
|
|
Packit |
8f70b4 |
*len=at-colon-1;
|
|
Packit |
8f70b4 |
return true;
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
const char *url::hide_password(const char *url)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int start,len;
|
|
Packit |
8f70b4 |
if(!find_password_pos(url,&start,&len))
|
|
Packit |
8f70b4 |
return url;
|
|
Packit |
8f70b4 |
return xstring::format("%.*sXXXX%s",start,url,url+start+len);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
const char *url::remove_password(const char *url)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
int start,len;
|
|
Packit |
8f70b4 |
if(!find_password_pos(url,&start,&len))
|
|
Packit |
8f70b4 |
return url;
|
|
Packit |
8f70b4 |
return xstring::format("%.*s%s",start-1,url,url+start+len);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool url::is_url(const char *p)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
ParsedURL url(p,true);
|
|
Packit |
8f70b4 |
return url.proto!=0;
|
|
Packit |
8f70b4 |
}
|