Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / media / UrlResolverPlugin.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/media/UrlResolverPlugin.cc
10  *
11 */
12 #include <iostream>
13 #include "zypp/base/Logger.h"
14 #include "zypp/media/UrlResolverPlugin.h"
15 #include "zypp/media/MediaException.h"
16 #include "zypp/PluginScript.h"
17 #include "zypp/ZConfig.h"
18
19 using std::endl;
20
21 ///////////////////////////////////////////////////////////////////
22 namespace zypp
23 { /////////////////////////////////////////////////////////////////
24   ///////////////////////////////////////////////////////////////////
25   namespace media
26   { /////////////////////////////////////////////////////////////////
27
28     /** UrlResolverPlugin implementation. */
29     struct UrlResolverPlugin::Impl
30     {
31
32
33     };
34     ///////////////////////////////////////////////////////////////////
35
36     Url UrlResolverPlugin::resolveUrl(const Url & o_url, HeaderList &headers)
37     {
38         if (o_url.getScheme() != "plugin")
39             return o_url;        
40         
41         Url url(o_url);
42         std::string name = url.getPathName();
43         Pathname plugin_path = (ZConfig::instance().pluginsPath()/"urlresolver")/name;    
44         if (PathInfo(plugin_path).isExist()) {
45             PluginScript scr;
46             scr.open(plugin_path);
47             // send frame to plugin
48             PluginFrame f("RESOLVEURL");
49
50             url::ParamMap params = url.getQueryStringMap();
51             url::ParamMap::const_iterator param_it;
52             for( param_it = params.begin();
53                  param_it != params.end();
54                  ++param_it)
55                 f.setHeader(param_it->first, param_it->second);
56             
57             scr.send(f);
58
59             PluginFrame r(scr.receive());
60             if (r.command() == "RESOLVEDURL") {
61                 // now set
62                 url = Url(r.body());
63                 PluginFrame::HeaderListIterator it;
64                 
65                 for (it = r.headerBegin();
66                      it != r.headerEnd();
67                      ++it) {
68                     std::pair<std::string, std::string> values(*it);
69                     // curl resets headers that are empty, so we use a workaround
70                     if (values.second.empty()) {
71                         values.second = "\nX-libcurl-Empty-Header-Workaround: *";
72                     }                    
73                     headers.insert(values);                    
74                 }
75             }
76             else if (r.command() == "ERROR") {
77                 ZYPP_THROW(MediaException(r.body()));
78             }            
79         }
80         return url;        
81     }
82
83     /** \relates UrlResolverPlugin::Impl Stream output */
84     inline std::ostream & operator<<( std::ostream & str, const UrlResolverPlugin::Impl & obj )
85     {
86       return str << "UrlResolverPlugin::Impl";
87     }
88
89     UrlResolverPlugin::~UrlResolverPlugin()
90     {}
91
92     std::ostream & operator<<( std::ostream & str, const UrlResolverPlugin & obj )
93     {
94       return str << *obj._pimpl;
95     }
96
97     /////////////////////////////////////////////////////////////////
98   } // namespace media
99   ///////////////////////////////////////////////////////////////////
100   /////////////////////////////////////////////////////////////////
101 } // namespace zypp
102 ///////////////////////////////////////////////////////////////////