Url parsing

This commit is contained in:
lganzzzo 2018-06-27 12:44:26 +03:00
parent b8a8d41c4f
commit 1358805784
6 changed files with 290 additions and 131 deletions

View File

@ -26,6 +26,7 @@
#include <stdlib.h>
#include <cstdlib>
#include <algorithm>
namespace oatpp { namespace parser {
@ -507,6 +508,11 @@ namespace oatpp { namespace parser {
}
bool ParsingCaret::findText(p_char8 text, v_int32 textSize) {
m_pos = (v_int32)(std::search(&m_data[m_pos], &m_data[m_size], text, text + textSize) - m_data);
return m_pos != m_size;
}
std::shared_ptr<oatpp::base::String> ParsingCaret::findTextFromList(const std::shared_ptr<oatpp::collection::LinkedList<std::shared_ptr<oatpp::base::String>>>& list){
while(m_pos < m_size){

View File

@ -52,7 +52,12 @@ public:
, m_end(-1)
{}
void end(){
void start() {
m_start = m_caret.m_pos;
m_end = -1;
}
void end() {
m_end = m_caret.m_pos;
}
@ -61,6 +66,9 @@ public:
}
v_int32 getSize(){
if(m_end == -1) {
return m_caret.m_pos - m_start;
}
return m_end - m_start;
}
@ -156,6 +164,8 @@ public:
std::shared_ptr<base::String> parseStringEnclosed(char openChar, char closeChar, char escapeChar, bool saveAsOwnData);
std::shared_ptr<base::String> parseName(bool saveAsOwnData);
bool findText(p_char8 text, v_int32 textSize);
std::shared_ptr<base::String> findTextFromList(const std::shared_ptr<oatpp::collection::LinkedList<std::shared_ptr<base::String>>>& list);
bool notAtCharFromSet(const char* set) const;

160
network/Url.cpp Normal file
View File

@ -0,0 +1,160 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "Url.hpp"
#include <cstdlib>
namespace oatpp { namespace network {
std::shared_ptr<oatpp::base::String> Url::Parser::parseScheme(oatpp::parser::ParsingCaret& caret) {
v_int32 pos0 = caret.getPosition();
caret.findChar(':');
v_int32 size = caret.getPosition() - pos0;
if(size > 0) {
v_char8 buff[size];
std::memcpy(buff, &caret.getData()[pos0], size);
oatpp::base::String::lowerCase(buff, size);
return oatpp::base::String::createShared(buff, size, true);
}
return nullptr;
}
Url::Authority Url::Parser::parseAuthority(oatpp::parser::ParsingCaret& caret) {
p_char8 data = caret.getData();
v_int32 pos0 = caret.getPosition();
v_int32 pos = pos0;
v_int32 hostPos = pos0;
v_int32 atPos = -1;
v_int32 portPos = -1;
while (pos < caret.getSize()) {
v_char8 a = data[pos];
if(a == '@') {
atPos = pos;
pos ++;
hostPos = pos;
} else if(a == ':') {
pos ++;
portPos = pos; // last ':' in authority proceeds port in case it goes after '@'
} else if(a == '/' || a == '?' || a == '#') {
if(pos == pos0) {
return Url::Authority();
}
break;
} else {
pos ++;
}
}
caret.setPosition(pos);
Url::Authority result;
if(atPos > -1) {
result.userInfo = oatpp::base::String::createShared(&data[pos0], atPos - pos0, true);
}
if(portPos > hostPos) {
result.host = oatpp::base::String::createShared(&data[hostPos], portPos - 1 - hostPos, true);
char* end;
result.port = (v_int32) std::strtol((const char*)&data[portPos], &end, 10);
bool success = (((v_int64)end - (v_int64)&data[portPos]) == pos - portPos);
if(!success) {
caret.setError("Invalid port string");
}
} else {
result.host = oatpp::base::String::createShared(&data[hostPos], pos - pos0, true);
}
return result;
}
std::shared_ptr<oatpp::base::String> Url::Parser::parsePath(oatpp::parser::ParsingCaret& caret) {
oatpp::parser::ParsingCaret::Label label(caret);
caret.findCharFromSet((p_char8)"?#", 2);
if(label.getSize() > 0) {
return label.toString(true);
}
return nullptr;
}
void Url::Parser::parseQueryParamsToMap(Url::Parameters& params, oatpp::parser::ParsingCaret& caret) {
if(caret.findChar('?')) {
do {
caret.inc();
oatpp::parser::ParsingCaret::Label nameLabel(caret);
if(caret.findChar('=')) {
nameLabel.end();
caret.inc();
oatpp::parser::ParsingCaret::Label valueLabel(caret);
caret.findChar('&');
params.put(nameLabel.toString(), valueLabel.toString());
}
} while (caret.canContinueAtChar('&'));
}
}
void Url::Parser::parseQueryParamsToMap(Url::Parameters& params, const oatpp::base::String::PtrWrapper& str) {
oatpp::parser::ParsingCaret caret(str.getPtr());
parseQueryParamsToMap(params, caret);
}
std::shared_ptr<Url::Parameters> Url::Parser::parseQueryParams(oatpp::parser::ParsingCaret& caret) {
auto params = Url::Parameters::createShared();
parseQueryParamsToMap(*params, caret);
return params;
}
std::shared_ptr<Url::Parameters> Url::Parser::parseQueryParams(const oatpp::base::String::PtrWrapper& str) {
auto params = Url::Parameters::createShared();
parseQueryParamsToMap(*params, str);
return params;
}
Url Url::Parser::parseUrl(oatpp::parser::ParsingCaret& caret) {
Url result;
result.scheme = parseScheme(caret);
if(caret.canContinueAtChar(':', 1)) {
if(caret.proceedIfFollowsText((p_char8)"//", 2)) {
if(!caret.isAtChar('/')) {
result.authority = parseAuthority(caret);
}
result.path = parsePath(caret);
result.queryParams = parseQueryParams(caret);
} else {
result.authority = parseAuthority(caret);
}
}
return result;
}
}}

113
network/Url.hpp Normal file
View File

@ -0,0 +1,113 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_network_Url_hpp
#define oatpp_network_Url_hpp
#include "oatpp/core/parser/ParsingCaret.hpp"
#include "oatpp/core/collection/ListMap.hpp"
#include "oatpp/core/base/String.hpp"
namespace oatpp { namespace network {
class Url : public oatpp::base::Controllable {
public:
typedef oatpp::collection::ListMap<oatpp::base::String::PtrWrapper, oatpp::base::String::PtrWrapper> Parameters;
public:
struct Authority {
std::shared_ptr<oatpp::base::String> userInfo;
std::shared_ptr<oatpp::base::String> host;
v_int32 port = -1;
};
public:
class Parser {
public:
/**
* parse "<scheme>:"
* example "http", "https", "ftp"
* returns lowercase string before ':' char
* caret should be at the first char of the scheme
*/
static std::shared_ptr<oatpp::base::String> parseScheme(oatpp::parser::ParsingCaret& caret);
/**
* parse utl authority components.
* userinfo is not parsed into login and password separately as
* inclusion of password in userinfo is deprecated and ignored here
* caret should be at the first char of the authority (not at "//")
*/
static Url::Authority parseAuthority(oatpp::parser::ParsingCaret& caret);
/**
* parse path of the url
* caret should be at the first char of the path
*/
static std::shared_ptr<oatpp::base::String> parsePath(oatpp::parser::ParsingCaret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by ParsingCaret
* and put that params to Parameters map
*/
static void parseQueryParamsToMap(Url::Parameters& params, oatpp::parser::ParsingCaret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by str
* and put that params to Parameters map
*/
static void parseQueryParamsToMap(Url::Parameters& params, const oatpp::base::String::PtrWrapper& str);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by ParsingCaret
*/
static std::shared_ptr<Url::Parameters> parseQueryParams(oatpp::parser::ParsingCaret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by str
*/
static std::shared_ptr<Url::Parameters> parseQueryParams(const oatpp::base::String::PtrWrapper& str);
/**
* parse Url
*/
static Url parseUrl(oatpp::parser::ParsingCaret& caret);
};
public:
std::shared_ptr<oatpp::base::String> scheme;
Authority authority;
std::shared_ptr<oatpp::base::String> path;
std::shared_ptr<Parameters> queryParams;
};
}}
#endif /* oatpp_network_url_Url_hpp */

View File

@ -1,66 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "Parser.hpp"
namespace oatpp { namespace web { namespace url {
void Parser::parseQueryParamsToMap(Parameters& params, oatpp::parser::ParsingCaret& caret) {
if(caret.findChar('?')) {
do {
caret.inc();
oatpp::parser::ParsingCaret::Label nameLabel(caret);
if(caret.findChar('=')) {
nameLabel.end();
caret.inc();
oatpp::parser::ParsingCaret::Label valueLabel(caret);
caret.findChar('&');
params.put(nameLabel.toString(), valueLabel.toString());
}
} while (caret.canContinueAtChar('&'));
}
}
void Parser::parseQueryParamsToMap(Parameters& params, const oatpp::base::String::PtrWrapper& str) {
oatpp::parser::ParsingCaret caret(str.getPtr());
parseQueryParamsToMap(params, caret);
}
std::shared_ptr<Parser::Parameters> Parser::parseQueryParams(oatpp::parser::ParsingCaret& caret) {
auto params = Parameters::createShared();
parseQueryParamsToMap(*params, caret);
return params;
}
std::shared_ptr<Parser::Parameters> Parser::parseQueryParams(const oatpp::base::String::PtrWrapper& str) {
auto params = Parameters::createShared();
parseQueryParamsToMap(*params, str);
return params;
}
}}}

View File

@ -1,64 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_web_url_Parser_hpp
#define oatpp_web_url_Parser_hpp
#include "oatpp/core/collection/ListMap.hpp"
#include "oatpp/core/parser/ParsingCaret.hpp"
namespace oatpp { namespace web { namespace url {
class Parser {
public:
typedef oatpp::collection::ListMap<oatpp::base::String::PtrWrapper, oatpp::base::String::PtrWrapper> Parameters;
public:
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by ParsingCaret
* and put that params to Parameters map
*/
static void parseQueryParamsToMap(Parameters& params, oatpp::parser::ParsingCaret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by str
* and put that params to Parameters map
*/
static void parseQueryParamsToMap(Parameters& params, const oatpp::base::String::PtrWrapper& str);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by ParsingCaret
*/
static std::shared_ptr<Parameters> parseQueryParams(oatpp::parser::ParsingCaret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by str
*/
static std::shared_ptr<Parameters> parseQueryParams(const oatpp::base::String::PtrWrapper& str);
};
}}}
#endif /* oatpp_web_url_Parser_hpp */