source: main/trunk/greenstone2/runtime-src/src/recpt/extlinkaction.cpp@ 28913

Last change on this file since 28913 was 28913, checked in by ak19, 10 years ago

6th commit for security of cgiargs. Looked over all occurrences of setmacro in *action.cpp files

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/**********************************************************************
2 *
3 * extlinkaction.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "gsdl_modules_cfg.h"
27#ifdef GSDL_USE_EXTLINK_ACTION
28
29#include <string.h>
30#include "extlinkaction.h"
31#include "recptprototools.h"
32#include "cgiutils.h"
33
34extlinkaction::extlinkaction () {
35
36 // this action uses cgi variables "a", "d", and "href"
37
38 cgiarginfo arg_ainfo;
39 arg_ainfo.shortname = "a";
40 arg_ainfo.longname = "action";
41 arg_ainfo.multiplechar = true;
42 arg_ainfo.multiplevalue = false;
43 arg_ainfo.defaultstatus = cgiarginfo::weak;
44 arg_ainfo.argdefault = "extlink";
45 arg_ainfo.savedarginfo = cgiarginfo::must;
46 argsinfo.addarginfo (NULL, arg_ainfo);
47
48 arg_ainfo.shortname = "el";
49 arg_ainfo.longname = "external link preference";
50 arg_ainfo.multiplechar = true;
51 arg_ainfo.multiplevalue = false;
52 arg_ainfo.defaultstatus = cgiarginfo::weak;
53 arg_ainfo.argdefault = "direct"; // changed from "prompt" - will now directly load external links instead of
54 // going through an intermediate page indicating that the link is external
55 arg_ainfo.savedarginfo = cgiarginfo::must;
56 argsinfo.addarginfo (NULL, arg_ainfo);
57
58 arg_ainfo.shortname = "d";
59 arg_ainfo.longname = "document OID";
60 arg_ainfo.multiplechar = true;
61 arg_ainfo.multiplevalue = false;
62 arg_ainfo.defaultstatus = cgiarginfo::none;
63 arg_ainfo.argdefault = g_EmptyText;
64 arg_ainfo.savedarginfo = cgiarginfo::can;
65 argsinfo.addarginfo (NULL, arg_ainfo);
66
67 arg_ainfo.shortname = "href";
68 arg_ainfo.longname = "URL of external link";
69 arg_ainfo.multiplechar = true;
70 arg_ainfo.multiplevalue = false;
71 arg_ainfo.defaultstatus = cgiarginfo::none;
72 arg_ainfo.argdefault = g_EmptyText;
73 arg_ainfo.savedarginfo = cgiarginfo::can;
74 argsinfo.addarginfo (NULL, arg_ainfo);
75
76 arg_ainfo.shortname = "rl";
77 arg_ainfo.longname = "is relative link";
78 arg_ainfo.multiplechar = false;
79 arg_ainfo.multiplevalue = false;
80 arg_ainfo.defaultstatus = cgiarginfo::none;
81 arg_ainfo.argdefault = "0";
82 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
83 argsinfo.addarginfo (NULL, arg_ainfo);
84
85}
86
87extlinkaction::~extlinkaction () {
88}
89
90
91void extlinkaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
92 response_t &response, text_t &response_data,
93 ostream &logout) {
94
95 text_t link;
96 if (get_link (args, protos, link, logout)) {
97 response = location;
98 response_data = link;
99 return;
100 }
101
102 // external link
103 if (!link.empty()) {
104 if (args["el"] == "direct") {
105 response = location;
106 response_data = link;
107 return;
108 }
109 }
110
111 response = content;
112 response_data = "text/html";
113}
114
115void extlinkaction::define_internal_macros (displayclass &disp, cgiargsclass &args,
116 recptprotolistclass * /*protos*/,
117 ostream &/*logout*/) {
118
119 // define_internal_macros sets the following macros:
120
121 // _nexturl_ link to external page
122 // _prevdoc_ link to previous document
123 // disp.setmacro("nexturl", "extlink", cgi_safe(args["href"]));
124 // problem in whist, above line changed. Perhaps decode_cgi_arg ??
125 // see also HTML plugin
126
127 text_t nexturl_macro = args["href"];
128 if(!isValidURLProtocol(nexturl_macro)) {
129 nexturl_macro = encodeForURL(nexturl_macro); // URL has invalid protocol like javascript:, so URL encode it
130 } else {
131 nexturl_macro = encodeForHTMLAttr(nexturl_macro);
132 }
133
134 disp.setmacro("nexturl", "extlink", nexturl_macro); // goes into a full-url context
135 disp.setmacro("prevdoc", "extlink", args["d"]);
136}
137
138
139// if link is found returns true and url in link, otherwise returns
140// false
141bool extlinkaction::get_link (cgiargsclass &args, recptprotolistclass *protos,
142 text_t &link, ostream &logout) {
143
144 text_t &arg_href = args["href"];
145 text_t &thiscollection = args["c"];
146 if (arg_href.empty()) return false;
147
148 text_t httpdoc = "_gwcgi_?e=_compressedoptions_&a=d";
149 if (args["rl"] == "1") {
150
151 FilterResponse_t response;
152 text_tset metadata;
153 metadata.insert ("section");
154
155 recptproto *collectproto = protos->getrecptproto (thiscollection, logout);
156
157 if (get_info (arg_href, thiscollection, args["l"], metadata, false, collectproto, response, logout)) {
158 if (!response.docInfo[0].metadata["section"].values[0].empty()) {
159 link = httpdoc+"&d=" + response.docInfo[0].metadata["section"].values[0];
160 return true;
161 }
162 }
163
164 // need to see if link exists in any other collection
165 // if cross-collection searching/browsing is turned on
166 if (args["ccs"] == "1" && !args["cc"].empty()) {
167 text_tarray collections;
168 splitchar (args["cc"].begin(), args["cc"].end(), ',', collections);
169
170 text_tarray::const_iterator col_here = collections.begin();
171 text_tarray::const_iterator col_end = collections.end();
172
173 while (col_here != col_end) {
174
175 // don't need to check current collection again
176 if (*col_here == thiscollection) {++col_here; continue;}
177
178 recptproto *collectproto = protos->getrecptproto (*col_here, logout);
179 if (collectproto == NULL) {++col_here; continue;}
180
181 if (get_info (arg_href, *col_here, args["l"], metadata, false, collectproto, response, logout)) {
182 if (!response.docInfo[0].metadata["section"].values[0].empty()) {
183 link = httpdoc+"&c=" + *col_here + "&d=" +
184 response.docInfo[0].metadata["section"].values[0];
185 return true;
186 }
187 }
188 ++col_here;
189 }
190 }
191 return false;
192
193 } else {
194 // link is external
195 link = arg_href;
196 return false;
197 }
198}
199
200
201bool extlinkaction::do_action (cgiargsclass &args, recptprotolistclass *protos,
202 browsermapclass * /*browsers*/, displayclass &disp,
203 outconvertclass &outconvert, ostream &textout,
204 ostream &logout) {
205
206 if (args["href"].empty()) {
207 // oops, this shouldn't happen
208 textout << outconvert << disp << ("_extlink:header_\n")
209 << ("_extlink:notfoundcontent_\n")
210 << ("_extlink:footer_\n");
211 return true;
212 }
213
214 if (args["rl"] == "1") {
215 // need to see if link exists in any other collection
216 // if cross-collection searching/browsing is turned on
217 if (args["ccs"] == "1" && !args["cc"].empty()) {
218
219 FilterResponse_t response;
220 text_tset metadata;
221 metadata.insert ("section");
222 text_tarray collections;
223 splitchar (args["cc"].begin(), args["cc"].end(), ',', collections);
224
225 text_tarray::const_iterator col_here = collections.begin();
226 text_tarray::const_iterator col_end = collections.end();
227
228 while (col_here != col_end) {
229
230 // don't need to check current collection
231 if (*col_here == args["c"]) {++col_here; continue;}
232
233 recptproto *collectproto = protos->getrecptproto (*col_here, logout);
234 if (get_info (args["href"], *col_here, args["l"], metadata, false, collectproto, response, logout)) {
235 if (!response.docInfo[0].metadata["section"].values[0].empty()) {
236 ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, *col_here, logout);
237 text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]); //
238 if (collectionname.empty()) {
239 collectionname = *col_here;
240 }
241 textout << outconvert << disp << ("_extlink:header_\n")
242 << ("_extlink:foundintcontent_(" + *col_here + ", " + collectionname +
243 ", " + response.docInfo[0].metadata["section"].values[0] + "\n")
244 << ("_extlink:footer_\n");
245 return true;
246 }
247 }
248 ++col_here;
249 }
250 }
251 textout << outconvert << disp << ("_extlink:header_\n")
252 << ("_extlink:notfoundcontent_\n")
253 << ("_extlink:footer_\n");
254
255
256 } else {
257 // link is external
258 textout << outconvert << disp << ("_extlink:header_\n")
259 << ("_extlink:foundcontent_\n")
260 << ("_extlink:footer_\n");
261 }
262
263 return true;
264}
265
266#endif //GSDL_USE_EXTLINK_ACTION
Note: See TracBrowser for help on using the repository browser.