1 /** @file
2 
3   A brief file description
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22 
23  */
24 
25 #include "tscore/ink_defs.h"
26 #include "UrlMapping.h"
27 #include "records/I_RecCore.h"
28 #include "tscore/ink_cap.h"
29 
30 /**
31  *
32  **/
33 bool
add_plugin_instance(RemapPluginInst * i)34 url_mapping::add_plugin_instance(RemapPluginInst *i)
35 {
36   _plugin_inst_list.push_back(i);
37   return true;
38 }
39 
40 /**
41  *
42  **/
43 RemapPluginInst *
get_plugin_instance(std::size_t index) const44 url_mapping::get_plugin_instance(std::size_t index) const
45 {
46   Debug("url_rewrite", "get_plugin says we have %zu plugins and asking for plugin %zu", _plugin_inst_list.size(), index);
47   if (index < _plugin_inst_list.size()) {
48     return _plugin_inst_list[index];
49   }
50   return nullptr;
51 }
52 
53 /**
54  *
55  **/
~url_mapping()56 url_mapping::~url_mapping()
57 {
58   referer_info *r;
59   redirect_tag_str *rc;
60   acl_filter_rule *afr;
61 
62   tag                 = static_cast<char *>(ats_free_null(tag));
63   filter_redirect_url = static_cast<char *>(ats_free_null(filter_redirect_url));
64 
65   while ((r = referer_list) != nullptr) {
66     referer_list = r->next;
67     delete r;
68   }
69 
70   while ((rc = redir_chunk_list) != nullptr) {
71     redir_chunk_list = rc->next;
72     delete rc;
73   }
74 
75   // Delete filters
76   while ((afr = filter) != nullptr) {
77     filter = afr->next;
78     delete afr;
79   }
80 
81   // Destroy the URLs
82   fromURL.destroy();
83   toURL.destroy();
84 }
85 
86 void
Print() const87 url_mapping::Print() const
88 {
89   char from_url_buf[131072], to_url_buf[131072];
90 
91   fromURL.string_get_buf(from_url_buf, static_cast<int>(sizeof(from_url_buf)));
92   toURL.string_get_buf(to_url_buf, static_cast<int>(sizeof(to_url_buf)));
93   printf("\t %s %s=> %s %s <%s> [plugins %s enabled; running with %zu plugins]\n", from_url_buf, unique ? "(unique)" : "",
94          to_url_buf, homePageRedirect ? "(R)" : "", tag ? tag : "", _plugin_inst_list.size() > 0 ? "are" : "not",
95          _plugin_inst_list.size());
96 }
97 
98 /**
99  *
100  **/
101 redirect_tag_str *
parse_format_redirect_url(char * url)102 redirect_tag_str::parse_format_redirect_url(char *url)
103 {
104   char *c;
105   redirect_tag_str *r;
106   redirect_tag_str *list = nullptr;
107 
108   if (url && *url) {
109     for (redirect_tag_str **rr = &list; *(c = url) != 0;) {
110       char type = 0;
111       for (type = 's'; *c; c++) {
112         if (c[0] == '%') {
113           char tmp_type = static_cast<char>(tolower(static_cast<int>(c[1])));
114           if (tmp_type == 'r' || tmp_type == 'f' || tmp_type == 't' || tmp_type == 'o') {
115             if (url == c) {
116               type = tmp_type;
117             }
118             break;
119           }
120         }
121       }
122       r = new redirect_tag_str();
123       if (likely(r)) {
124         if ((r->type = type) == 's') {
125           char svd     = *c;
126           *c           = 0;
127           r->chunk_str = ats_strdup(url);
128           *c           = svd;
129           url          = c;
130         } else {
131           url += 2;
132         }
133         (*rr = r)->next = nullptr;
134         rr              = &(r->next);
135       } else {
136         break; /* memory allocation error */
137       }
138     }
139   }
140   return list;
141 }
142 
143 /**
144  *
145  **/
referer_info(char * _ref,bool * error_flag,char * errmsgbuf,int errmsgbuf_size)146 referer_info::referer_info(char *_ref, bool *error_flag, char *errmsgbuf, int errmsgbuf_size)
147   : next(nullptr), referer(nullptr), referer_size(0), any(false), negative(false), regx_valid(false)
148 {
149   const char *error;
150   int erroffset;
151 
152   if (error_flag) {
153     *error_flag = false;
154   }
155   regx = nullptr;
156 
157   if (_ref) {
158     if (*_ref == '~') {
159       negative = true;
160       _ref++;
161     }
162     if ((referer = ats_strdup(_ref)) != nullptr) {
163       referer_size = strlen(referer);
164       if (!strcmp(referer, "*")) {
165         any = true;
166       } else {
167         regx = pcre_compile(referer, PCRE_CASELESS, &error, &erroffset, nullptr);
168         if (!regx) {
169           if (errmsgbuf && (errmsgbuf_size - 1) > 0) {
170             ink_strlcpy(errmsgbuf, error, errmsgbuf_size);
171           }
172           if (error_flag) {
173             *error_flag = true;
174           }
175         } else {
176           regx_valid = true;
177         }
178       }
179     }
180   }
181 }
182 
183 /**
184  *
185  **/
~referer_info()186 referer_info::~referer_info()
187 {
188   ats_free(referer);
189   referer      = nullptr;
190   referer_size = 0;
191 
192   if (regx_valid) {
193     pcre_free(regx);
194     regx       = nullptr;
195     regx_valid = false;
196   }
197 }
198