Improve RsUrl

Fix a bug in RsUrl::fromString eating one character when parsing URL
  string with IPv6 host
Offer explicit conversion from sockaddr_storage
This commit is contained in:
Gioacchino Mazzurco 2019-11-11 11:14:28 +01:00
parent aabba04be9
commit 056904c90b
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
2 changed files with 32 additions and 8 deletions

View File

@ -1,6 +1,6 @@
/* /*
* RetroShare * RetroShare
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> * Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@ -17,15 +17,16 @@
*/ */
#include "rsurl.h"
#include "serialiser/rstypeserializer.h"
#include <cstdio> #include <cstdio>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include "rsurl.h"
#include "serialiser/rstypeserializer.h"
#include "util/rsnet.h"
using namespace std; using namespace std;
RsUrl::RsUrl() : mPort(0), mHasPort(false) {} RsUrl::RsUrl() : mPort(0), mHasPort(false) {}
@ -33,6 +34,26 @@ RsUrl::RsUrl() : mPort(0), mHasPort(false) {}
RsUrl::RsUrl(const std::string& urlStr) : mPort(0), mHasPort(false) RsUrl::RsUrl(const std::string& urlStr) : mPort(0), mHasPort(false)
{ fromString(urlStr); } { fromString(urlStr); }
RsUrl::RsUrl(const sockaddr_storage& addr): mPort(0), mHasPort(false)
{
switch(addr.ss_family)
{
case AF_INET: setScheme("ipv4"); break;
case AF_INET6: setScheme("ipv6"); break;
default:
{
std::string addrDump;
sockaddr_storage_dump(addr, &addrDump);
RsErr() << __PRETTY_FUNCTION__ << " got invalid addr: " << addrDump
<< std::endl;
return;
}
}
setHost(sockaddr_storage_iptostring(addr));
setPort(sockaddr_storage_port(addr));
}
RsUrl& RsUrl::fromString(const std::string& urlStr) RsUrl& RsUrl::fromString(const std::string& urlStr)
{ {
size_t endI = urlStr.size()-1; size_t endI = urlStr.size()-1;
@ -55,7 +76,7 @@ RsUrl& RsUrl::fromString(const std::string& urlStr)
{ {
if(++hostBeginI >= endI) return *this; if(++hostBeginI >= endI) return *this;
hostEndI = urlStr.find(ipv6WrapClose, hostBeginI); hostEndI = urlStr.find(ipv6WrapClose, hostBeginI);
mHost = urlStr.substr(hostBeginI, hostEndI - hostBeginI - 1); mHost = urlStr.substr(hostBeginI, hostEndI - hostBeginI);
++hostEndI; ++hostEndI;
} }
else else
@ -250,10 +271,10 @@ RsUrl& RsUrl::setFragment(const std::string& fragment)
size_t boundary = len-2; // % Encoded char must be at least 2 hex char size_t boundary = len-2; // % Encoded char must be at least 2 hex char
for (size_t i = 0; i < len; ++i) for (size_t i = 0; i < len; ++i)
{ {
if(str[i] == '%' && i < boundary) if(str[i] == '%' && i < boundary)
{ {
decoded << static_cast<char>(std::stoi(str.substr(++i, 2), 0, 16)); decoded << static_cast<char>(std::stoi(
str.substr(++i, 2), nullptr, 16 ));
++i; ++i;
} }
else decoded << str[i]; else decoded << str[i];

View File

@ -22,6 +22,8 @@
#include "serialiser/rsserializable.h" #include "serialiser/rsserializable.h"
struct sockaddr_storage;
/** /**
* Very simplistic and minimal URL helper class for RetroShare, after looking * Very simplistic and minimal URL helper class for RetroShare, after looking
* for a small and self-contained C/C++ URL parsing and manipulation library, * for a small and self-contained C/C++ URL parsing and manipulation library,
@ -36,7 +38,8 @@
struct RsUrl : RsSerializable struct RsUrl : RsSerializable
{ {
RsUrl(); RsUrl();
RsUrl(const std::string& urlStr); explicit RsUrl(const std::string& urlStr);
explicit RsUrl(const sockaddr_storage& ssas);
RsUrl& fromString(const std::string& urlStr); RsUrl& fromString(const std::string& urlStr);
std::string toString() const; std::string toString() const;