sub encode_uri($orig) { my @oparts = split/\//, $orig; my @eparts; foreach my $opart (@oparts) { push @eparts, encode_uri_part($opart); } return join('/', @eparts); } sub encode_uri_part($orig) { $orig = encode_utf8($orig); my $encoded = ''; my @parts = split//, $orig; foreach my $part (@parts) { if($part =~ /^[a-zA-Z0-9\:\~]/) { $encoded .= $part; }elsif($part eq ' ') { $encoded .= '+'; } else { $encoded .= '%' . uc(doFPad(sprintf("%x", ord($part)), 2)); } } return $encoded; } sub encode_uri_path($orig, $encodeslashes = 0) { my $encoded = ''; my @parts = split//, $orig; foreach my $part (@parts) { if($part =~ /^[a-zA-Z0-9\/\:\~]/) { if($encodeslashes && $part eq '/') { $encoded .= '%' . uc(doFPad(sprintf("%x", ord($part)), 2)); } else { $encoded .= $part; } }elsif($part eq ' ') { $encoded .= '%20'; } else { $encoded .= '%' . uc(doFPad(sprintf("%x", ord($part)), 2)); } } return $encoded; } sub decode_uri($orig) { my @oparts = split/\//, $orig; my @dparts; foreach my $opart (@oparts) { push @dparts, decode_uri_part($opart); } return join('/', @dparts); } sub decode_uri_part($orig) { my $decoded = ''; return $decoded unless defined($orig); my @parts = split//, $orig; while(scalar @parts) { my $part = shift @parts; if($part eq '+') { $decoded .= ' '; } elsif($part eq '%') { $decoded .= chr(hex(shift @parts) * 16 + hex(shift @parts)); } else { $decoded .= $part; } } return $decoded; } # This is similar to decode_uri_part, but treats the plus sign literally instead of as space sub decode_uri_path($orig) { my $decoded = ''; return $decoded unless defined($orig); my @parts = split//, $orig; while(scalar @parts) { my $part = shift @parts; if($part eq '%') { $decoded .= chr(hex(shift @parts) * 16 + hex(shift @parts)); } else { $decoded .= $part; } } return $decoded; }