1 /*
2  * This File is part of Davix, The IO library for HTTP based protocols
3  * Copyright (C) CERN 2013
4  * Author: Adrien Devresse <adrien.devresse@cern.ch>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20 */
21 
22 #include <davix_internal.hpp>
23 #include <davixcontext.hpp>
24 
25 #include <string_utils/stringutils.hpp>
26 #include <utils/davix_uri.hpp>
27 #include <modules/modules_profiles.hpp>
28 #include <neon/neonsessionfactory.hpp>
29 #include <davix_context_internal.hpp>
30 #include <core/RedirectionResolver.hpp>
31 #include <set>
32 #include <mutex>
33 
34 namespace Davix{
35 
36 struct LibPath;
37 
38 
39 static LibPath lib_path;
40 
41 
redirCachingDisabled()42 static bool redirCachingDisabled(){
43     return ( getenv("DAVIX_DISABLE_REDIRECT_CACHING") != NULL);
44 }
45 
46 ///  Implementation f the core logic in davix
47 struct ContextInternal
48 {
ContextInternalDavix::ContextInternal49     ContextInternal():
50         _fsess(new NEONSessionFactory()),
51         _redirectionResolver(new RedirectionResolver(!redirCachingDisabled())),
52         _hook_list()
53     {
54             DAVIX_SLOG(DAVIX_LOG_DEBUG, DAVIX_LOG_CORE, "libdavix path {}, version: {}", getLibPath(), version());
55     }
56 
ContextInternalDavix::ContextInternal57     ContextInternal(const ContextInternal & orig) :
58         _fsess(new NEONSessionFactory()),
59         _redirectionResolver(new RedirectionResolver(!redirCachingDisabled())),
60         _hook_list(orig._hook_list)
61     {
62     }
63 
~ContextInternalDavix::ContextInternal64     virtual ~ContextInternal(){}
65 
66     // implementation of getSessionFactory
getSessionFactoryDavix::ContextInternal67     inline NEONSessionFactory* getSessionFactory(){
68          return _fsess.get();
69     }
70 
getRedirectionResolverDavix::ContextInternal71     inline RedirectionResolver* getRedirectionResolver() {
72         return _redirectionResolver.get();
73     }
74 
75     std::unique_ptr<NEONSessionFactory>  _fsess;
76     std::unique_ptr<RedirectionResolver> _redirectionResolver;
77     HookList _hook_list;
78 };
79 
80 ///////////////////////////////////////////////////////////////
81 //////////////////////////////////////////////////////////////
82 //////////////////////////////////////////////////////////////
83 
84 
Context()85 Context::Context() :
86     _intern(new ContextInternal())
87 {
88 }
89 
Context(const Context & c)90 Context::Context(const Context &c) :
91     _intern(new ContextInternal(*(c._intern))){
92 }
93 
operator =(const Context & c)94 Context & Context::operator=(const Context & c){
95     if( this != &c ){
96         if( _intern != NULL)
97             delete _intern;
98         _intern = new ContextInternal(*(c._intern));
99     }
100     return *this;
101 }
102 
~Context()103 Context::~Context(){
104     delete _intern;
105 }
106 
clone()107 Context* Context::clone(){
108     return new Context(*this);
109 }
110 
111 
setSessionCaching(bool caching)112 void Context::setSessionCaching(bool caching){
113     _intern->_fsess->setSessionCaching(caching);
114 }
115 
getSessionCaching() const116 bool Context::getSessionCaching() const{
117     return _intern->_fsess->getSessionCaching();
118 }
119 
clearCache()120 void Context::clearCache() {
121   _intern->_fsess.reset(new NEONSessionFactory());
122 }
123 
createRequest(const std::string & url,DavixError ** err)124 HttpRequest* Context::createRequest(const std::string & url, DavixError** err){
125     return new HttpRequest(*this, Uri(url), err);
126 }
127 
128 
createRequest(const Uri & uri,DavixError ** err)129 HttpRequest* Context::createRequest(const Uri &uri, DavixError **err){
130     return new HttpRequest(*this, uri, err);
131 }
132 
133 
loadModule(const std::string & name)134 void Context::loadModule(const std::string &name){
135     if( StrUtil::compare_ncase("grid",name) == 0){
136         loadGridProfile(*this);
137         return;
138     }
139     DAVIX_SLOG(DAVIX_LOG_WARNING, DAVIX_LOG_CORE, "No module named {} found", name);
140 }
141 
getHookList()142 HookList & Context::getHookList(){
143     return _intern->_hook_list;
144 }
145 
SessionFactoryFromContext(Context & c)146 NEONSessionFactory & ContextExplorer::SessionFactoryFromContext(Context & c){
147     return *static_cast<NEONSessionFactory*>(c._intern->getSessionFactory());
148 }
149 
RedirectionResolverFromContext(Context & c)150 RedirectionResolver & ContextExplorer::RedirectionResolverFromContext(Context &c) {
151     return *c._intern->getRedirectionResolver();
152 }
153 
LibPath()154 LibPath::LibPath(){
155     Dl_info shared_lib_infos;
156 
157     // do an address resolution on a local function
158     // get this resolution to determine davix shared library path at runtime
159     if( dladdr((void*) &version, &shared_lib_infos) != 0){
160         path = shared_lib_infos.dli_fname;
161     }
162 
163 }
164 
version()165 const std::string & version(){
166     static const std::string _version = DAVIX_VERSION_STRING;
167     return _version;
168 }
169 
170 
171 
getLibPath()172 const std::string & getLibPath(){
173     return lib_path.path;
174 }
175 
176 
177 } // End Davix
178