blob: 92930278d6b16437a40be2f79a43bb52166d6fef [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 "URI.h"
#include <apr_strings.h>
#include <decaf/lang/Integer.h>
using namespace decaf;
using namespace decaf::net;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
////////////////////////////////////////////////////////////////////////////////
const std::string URI::unreserved = "_-!.~\'()*";
const std::string URI::punct = ",;:$&+=";
const std::string URI::reserved = punct + "?/[]@";
const std::string URI::someLegal = unreserved + punct;
const std::string URI::allLegal = unreserved + reserved;
////////////////////////////////////////////////////////////////////////////////
URI::URI( const std::string& uri ) throw ( URISyntaxException) {
this->uriString = NULL;
this->parseURI( uri );
}
////////////////////////////////////////////////////////////////////////////////
URI::URI( const std::string& scheme,
const std::string& ssp,
const std::string& fragment ) throw ( URISyntaxException ) {
std::string uri = "";
if( scheme != "" ) {
uri.append( scheme );
uri.append( ":" );
}
if( ssp != "" ) {
// QUOTE ILLEGAL CHARACTERS
uri.append( quoteComponent( ssp, allLegal ) );
}
if( fragment != "" ) {
uri.append( "#" );
// QUOTE ILLEGAL CHARACTERS
uri.append( quoteComponent( fragment, allLegal ) );
}
// Now hand of to the main parse function.
this->parseURI( uri );
}
////////////////////////////////////////////////////////////////////////////////
URI::URI( const std::string& scheme, const std::string& userInfo,
const std::string& host, int port,
const std::string& path, const std::string& query,
const std::string& fragment ) throw ( URISyntaxException ) {
this->uriString = NULL;
if( scheme == "" && userInfo == "" && host == "" &&
path == "" && query == "" && fragment == "" ) {
this->uri.path = "";
return;
}
if( scheme != "" && path.length() > 0 && path.at(0) != '/') {
throw URISyntaxException(
__FILE__, __LINE__, path,
"URI::URI - Path string: %s starts with invalid char '/'" );
}
std::string uri = "";
if( scheme != "" ) {
uri.append( scheme );
uri.append( ":" );
}
if( userInfo != "" || host != "" || port != -1 ) {
uri.append( "//" );
}
if( userInfo != "" ) {
// QUOTE ILLEGAL CHARACTERS in userinfo
uri.append(quoteComponent( userInfo, someLegal ) );
uri.append( "@" );
}
if( host != "" ) {
std::string newHost = host;
// check for ipv6 addresses that hasn't been enclosed
// in square brackets
if( host.find( ":" ) != std::string::npos &&
host.find( "]" ) == std::string::npos &&
host.find( "[" ) == std::string::npos ) {
newHost = std::string( "[" ) + host + "]";
}
uri.append( newHost );
}
if( port != -1 ) {
uri.append( ":" );
uri.append( Integer::toString( port ) );
}
if( path != "" ) {
// QUOTE ILLEGAL CHARS
uri.append( quoteComponent( path, "/@" + someLegal ) );
}
if( query != "" ) {
uri.append( "?" );
// QUOTE ILLEGAL CHARS
uri.append( quoteComponent( query, allLegal ) );
}
if( fragment != "" ) {
// QUOTE ILLEGAL CHARS
uri.append( "#" );
uri.append( quoteComponent( fragment, allLegal ) );
}
this->parseURI( uri );
}
////////////////////////////////////////////////////////////////////////////////
URI::URI( const std::string& scheme, const std::string& host,
const std::string& path, const std::string& fragment )
throw ( URISyntaxException ) {
this->uriString = NULL;
URI::URI( scheme, "", host, -1, path, "", fragment );
}
////////////////////////////////////////////////////////////////////////////////
URI::URI( const std::string& scheme, const std::string& authority,
const std::string& path, const std::string& query,
const std::string& fragment ) throw ( URISyntaxException ) {
this->uriString = NULL;
if( scheme != "" && path.length() > 0 && path.at(0) != '/' ) {
throw URISyntaxException(
__FILE__, __LINE__, path,
"URI::URI - Path String %s must start with a '/'" );
}
std::string uri = "";
if( scheme != "" ) {
uri.append( scheme );
uri.append( ":" );
}
if( authority != "" ) {
uri.append("//");
// QUOTE ILLEGAL CHARS
uri.append( quoteComponent( authority, "@[]" + someLegal ) );
}
if( path != "" ) {
// QUOTE ILLEGAL CHARS
uri.append( quoteComponent( path, "/@" + someLegal ) );
}
if( query != "" ) {
// QUOTE ILLEGAL CHARS
uri.append( "?" );
uri.append( quoteComponent( query, allLegal ) );
}
if( fragment != "" ) {
// QUOTE ILLEGAL CHARS
uri.append( "#" );
uri.append( quoteComponent( fragment, allLegal ) );
}
this->parseURI( uri );
}
////////////////////////////////////////////////////////////////////////////////
void URI::parseURI( const std::string& uri ) throw ( URISyntaxException ) {
// Use APR to perform the main parse.
apr_status_t result = apr_uri_parse( pool.getAprPool(),
uri.c_str(), &this->uri );
if( result != APR_SUCCESS ) {
throw URISyntaxException(
__FILE__, __LINE__, uri,
"URI::praseURI - URI String %s invalid." );
}
std::cout << "\n";
std::cout << "Original URI String: " << uri << std::endl;
std::cout << "\n";
std::cout << "Scheme: "
<< ( this->uri.scheme ? this->uri.scheme : "" ) << std::endl;
std::cout << "Host: "
<< ( this->uri.hostinfo ? this->uri.hostinfo : "" ) << std::endl;
std::cout << "User: "
<< ( this->uri.user ? this->uri.user : "" ) << std::endl;
std::cout << "Passwrod: "
<< ( this->uri.password ? this->uri.password : "" ) << std::endl;
std::cout << "Host Name: "
<< ( this->uri.hostname ? this->uri.hostname : "" ) << std::endl;
std::cout << "Port Str: "
<< ( this->uri.port_str ? this->uri.port_str : "" ) << std::endl;
std::cout << "Path: "
<< ( this->uri.path ? this->uri.path : "" ) << std::endl;
std::cout << "Query: "
<< ( this->uri.query ? this->uri.query : "" ) << std::endl;
std::cout << "Fragment: "
<< ( this->uri.fragment ? this->uri.fragment : "" ) << std::endl;
std::cout << "Port: " << this->uri.port << std::endl;
std::cout << "Is Initialized: " << this->uri.is_initialized << std::endl;
std::cout << "DNS Looked Up: " << this->uri.dns_looked_up << std::endl;
std::cout << "DNS Resolved: " << this->uri.dns_resolved << std::endl;
}
////////////////////////////////////////////////////////////////////////////////
int URI::compareTo( const URI& value ) const {
return 0;
}
////////////////////////////////////////////////////////////////////////////////
bool URI::equals( const URI& value ) const {
return compareTo( value ) == 0 ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
bool URI::operator==( const URI& value ) const {
return compareTo( value ) == 0 ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
bool URI::operator<( const URI& value ) const {
return compareTo( value ) == -1 ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
URI URI::create( const std::string uri )
throw ( lang::exceptions::IllegalArgumentException ) {
try {
return URI( uri );
} catch( URISyntaxException& e ) {
throw IllegalArgumentException( e );
}
}
////////////////////////////////////////////////////////////////////////////////
std::string URI::quoteComponent( const std::string& component,
const std::string& legalset ) {
// try {
/*
* Use a different encoder than URLEncoder since: 1. chars like "/",
* "#", "@" etc needs to be preserved instead of being encoded, 2.
* UTF-8 char set needs to be used for encoding instead of default
* platform one
*/
// return URIEncoderDecoder.quoteIllegal(component, legalset);
// } catch( UnsupportedEncodingException e ) {
// throw RuntimeException( e );
// }
}