| /* |
| * 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 ); |
| // } |
| } |