From 9bdb3a0ea0ee00a0dc7bfa7fb6658859f9024d13 Mon Sep 17 00:00:00 2001 From: knowcenter Date: Tue, 24 Jul 2007 16:34:32 +0000 Subject: Stable version. Known problems: Verification with MOA 1.0.0 signatures git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@151 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- .../java/at/knowcenter/wag/egov/egiz/PdfAS.java | 8 ++- .../wag/egov/egiz/sig/ConnectorFactory.java | 31 ++++++++--- .../egov/egiz/sig/connectors/ConnectorChooser.java | 27 +--------- .../sig/connectors/bku/DetachedBKUConnector.java | 58 ++++++++++++++++++-- .../connectors/moa/DetachedLocRefMOAConnector.java | 63 +++++++++++++++++++--- .../egov/egiz/sig/sigid/DetachedIdFormatter.java | 11 ++-- .../sig/sigid/DetachedLocRefMOAIdFormatter.java | 26 +++++---- .../wag/egov/egiz/sig/sigid/OldMOAIdFormatter.java | 3 +- .../wag/egov/egiz/sig/sigkz/SigKZIDHelper.java | 8 --- .../egiz/web/servlets/VerifyPreviewServlet.java | 4 +- .../wag/egov/egiz/web/servlets/VerifyServlet.java | 6 +-- 11 files changed, 169 insertions(+), 76 deletions(-) (limited to 'src/main/java/at/knowcenter/wag/egov/egiz') diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java index cdc0aa8..83f2dcf 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -65,6 +65,7 @@ import at.knowcenter.wag.egov.egiz.sig.connectors.bku.SignSignatureObject; import at.knowcenter.wag.egov.egiz.sig.signatureobject.SignatureObjectHelper; import at.knowcenter.wag.egov.egiz.tools.CodingHelper; import at.knowcenter.wag.egov.egiz.tools.Normalizer; +import at.knowcenter.wag.egov.egiz.web.SessionInformation; import at.knowcenter.wag.exactparser.ParseDocument; import at.knowcenter.wag.exactparser.parsing.PDFUtils; import at.knowcenter.wag.exactparser.parsing.results.HeaderParseResult; @@ -774,15 +775,18 @@ public abstract class PdfAS // TODO the choosing algorithm should be extracted into a visitor or factory design pattern. public static List verifySignatureHoldersWeb(List signature_holders, - String connector, String loc_ref) throws PDFDocumentException, NormalizeException, SignatureException + //String connector, String loc_ref) throws PDFDocumentException, NormalizeException, SignatureException + SessionInformation si, String loc_ref) throws PDFDocumentException, NormalizeException, SignatureException { List results = new ArrayList(); for (int i = 0; i < signature_holders.size(); i++) { SignatureHolder holder = (SignatureHolder) signature_holders.get(i); - SignatureResponse result = verifyWeb(holder, connector, loc_ref); + SignatureResponse result = verifyWeb(holder, si.connector, loc_ref); results.add(result); + + si.current_operation++; } return results; } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java index 8d9a480..690a913 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/ConnectorFactory.java @@ -65,6 +65,11 @@ public abstract class ConnectorFactory * The logger definition. */ private static final Logger logger_ = ConfigLogger.getLogger(ConnectorFactory.class); + + /** + * Key value in property file + */ + public static final String MOA_ID_VISIBLE_PROPERTY_KEY = "moa.id.field.visible"; /** * Retrieves the ConnectorInformation from the connector Class. @@ -321,15 +326,27 @@ public abstract class ConnectorFactory public static boolean needsSIG_ID(String connector) { // all modernn detached signatures have the SIG_ID field. - - try { - if(!SettingsReader.getInstance().getValueFromKey("moa.id.field.visible").equals("true")) - return false; - } catch (SettingsException e) { + if(connector.equals("moa")) + { + String is_id_field_visible = null; + + try + { + is_id_field_visible = SettingsReader.getInstance().getValueFromKey(MOA_ID_VISIBLE_PROPERTY_KEY); + } catch (SettingsException e) + { e.printStackTrace(); - } - + } + // if not setted in config, show it + if(is_id_field_visible == null) + return true; + if(is_id_field_visible.equals("true")) + return true; + else + return false; + } + return true; //return !connector.equals("moa"); } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java index 38680c4..4dcd1b5 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/ConnectorChooser.java @@ -7,9 +7,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import at.knowcenter.wag.egov.egiz.PdfASID; -import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; import at.knowcenter.wag.egov.egiz.exceptions.ConnectorException; -import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.EnvelopedBase64BKUConnector; import at.knowcenter.wag.egov.egiz.sig.connectors.bku.LocRefDetachedBKUConnector; @@ -31,8 +29,6 @@ public final class ConnectorChooser * The log. */ private static Log log = LogFactory.getLog(ConnectorChooser.class); - - private static final String MOA_DETACHED_ENABLED_KEY = "moa.sign.console.detached.enabled"; public static LocalConnector chooseLocalConnectorForSign(String connector, String profile, String loc_ref_url) throws ConnectorException @@ -81,21 +77,7 @@ public final class ConnectorChooser } if (connector.equals(MOA)) { - // is detached mode enabled from console - String detached_mode_enabled = null; - - try - { - detached_mode_enabled = SettingsReader.getInstance().getValueFromKey(MOA_DETACHED_ENABLED_KEY); - } catch (SettingsException e) - { - e.printStackTrace(); - } - - // currently MOA does'nt support detached mode in command line - if(detached_mode_enabled == null || detached_mode_enabled.equals("true")) - return new DetachedLocRefMOAConnector(profile, "formdata:fileupload"); - + // TODO MOA detached signing is not allowed at the commandline log.warn("Detached MOA is not supported on the commandline. -> choosing Base64 temporarily."); return new EnvelopingBase64MOAConnector(profile); } @@ -223,13 +205,6 @@ public final class ConnectorChooser return chooseEnvelopedBase64ConnectorHotfix(profile, connector); } - // test - if (sig_id.equals("")) - { - log.debug("sig_id is null, which means that it is a MOA signature -> choose a hotfix base64 connector (thus it is moa - it doesn't matter)."); - - return chooseEnvelopedBase64ConnectorHotfix(profile, connector); - } String[] sig_id_parts = sig_id.split("@"); if (sig_id_parts.length == 2) diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java index 9713a4a..410c46e 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/bku/DetachedBKUConnector.java @@ -3,6 +3,7 @@ */ package at.knowcenter.wag.egov.egiz.sig.connectors.bku; +import java.io.File; import java.security.cert.X509Certificate; import java.util.Properties; @@ -456,7 +457,27 @@ public class DetachedBKUConnector implements Connector, LocalConnector * The configuration key of the sign URL. */ protected static final String SIGN_URL_KEY = "bku.sign.url"; //$NON-NLS-1$ + + /** + * BKU template file prefix + */ + protected static final String TEMPLATE_FILE_PREFIX = "./templates/bku."; + + /** + * signing file template sufix + */ + protected static final String SIGN_TEMPLATE_FILE_SUFIX = ".sign.xml"; + + /** + * verifing template file sufix + */ + protected static final String VERIFY_REQUEST_TEMPLATE_FILE_SUFIX = ".verify.request.xml"; + /** + * verifing file template key sufix + */ + protected static final String VERIFY_TEMPLATE_SUFIX = ".verify.template.xml"; + /** * The configuration key of the verify request template. */ @@ -525,11 +546,21 @@ public class DetachedBKUConnector implements Connector, LocalConnector { throw new ConnectorException(300, e); } - + this.sign_keybox_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEYBOX_IDENTIFIER_KEY); - String sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY); + String sign_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.bku.algorithm.id") + SIGN_TEMPLATE_FILE_SUFIX; + + // try to load template from file this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); + + // when first load failed (the template file does'nt exist), load it from default template file + if(this.sign_request_template == null) + { + sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY); + this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); + } + if (this.sign_request_template == null) { throw new ConnectorException(300, "Can not read the create xml request template"); //$NON-NLS-1$ @@ -537,16 +568,35 @@ public class DetachedBKUConnector implements Connector, LocalConnector this.sign_url = getConnectorValueFromProfile(settings, profile, SIGN_URL_KEY); - String verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY); + // verify + + String verify_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.bku.algorithm.id") + VERIFY_REQUEST_TEMPLATE_FILE_SUFIX; + + // try to load template file for verifing this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename)); + + if(this.verify_request_template == null) + { + verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY); + this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename)); + } + if (this.verify_request_template == null) { // TODO make this a settings exception throw new ConnectorException(300, "Can not read the verify xml request template"); //$NON-NLS-1$ } - String verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); + // load template key file + String verify_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.bku.algorithm.id") + VERIFY_TEMPLATE_SUFIX; this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); + + if(this.verify_template == null) + { + verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); + this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); + } + if (this.verify_template == null) { // TODO make this a settings exception diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java index 98d381a..b6e65b3 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/connectors/moa/DetachedLocRefMOAConnector.java @@ -37,7 +37,7 @@ public class DetachedLocRefMOAConnector implements Connector /** * The SIG_ID prefix. */ - public static final String SIG_ID_PREFIX = "etsi-bku-detached@"; //$NON-NLS-1$ + // public static final String SIG_ID_PREFIX = "etsi-bku-detached@"; //$NON-NLS-1$ /** * The log. @@ -322,6 +322,26 @@ public class DetachedLocRefMOAConnector implements Connector * The configuration key of the sign URL. */ protected static final String SIGN_URL_KEY = "moa.sign.url"; //$NON-NLS-1$ + + /** + * MOA template file prefix + */ + protected static final String TEMPLATE_FILE_PREFIX = "./templates/moa."; + + /** + * signing file template sufix + */ + protected static final String SIGN_TEMPLATE_FILE_SUFIX = ".sign.xml"; + + /** + * verifing template file sufix + */ + protected static final String VERIFY_REQUEST_TEMPLATE_FILE_SUFIX = ".verify.request.xml"; + + /** + * verifing file template key sufix + */ + protected static final String VERIFY_TEMPLATE_SUFIX = ".verify.template.xml"; /** * The configuration key of the verify request template. @@ -402,9 +422,21 @@ public class DetachedLocRefMOAConnector implements Connector } this.sign_key_identifier = getConnectorValueFromProfile(settings, profile, SIGN_KEY_IDENTIFIER_KEY); - - String sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY); + + String sign_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moa.algorithm.id") + SIGN_TEMPLATE_FILE_SUFIX; + + // try to load template from file this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); + + if(this.sign_request_template == null) + { + sign_request_filename = getConnectorValueFromProfile(settings, profile, SIGN_REQUEST_TEMPLATE_KEY); + this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); + } + + log.debug("\r\n\r\n" + sign_request_filename + "\r\n\r\n"); + + //this.sign_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(sign_request_filename)); if (this.sign_request_template == null) { // TODO make this a settings exception @@ -412,17 +444,34 @@ public class DetachedLocRefMOAConnector implements Connector } this.sign_url = getConnectorValueFromProfile(settings, profile, SIGN_URL_KEY); - - String verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY); + + String verify_request_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moa.algorithm.id") + VERIFY_REQUEST_TEMPLATE_FILE_SUFIX; + + // try to load template file for verifing this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename)); + + if(this.verify_request_template == null) + { + verify_request_filename = getConnectorValueFromProfile(settings, profile, VERIFY_REQUEST_TEMPLATE_KEY); + this.verify_request_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_request_filename)); + } + if (this.verify_request_template == null) { // TODO make this a settings exception throw new ConnectorException(300, "Can not read the verify xml request template"); //$NON-NLS-1$ } - - String verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); + + // load template key file + String verify_filename = TEMPLATE_FILE_PREFIX + settings.getValueFromKey("default.moa.algorithm.id") + VERIFY_TEMPLATE_SUFIX; this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); + + if(this.verify_template == null) + { + verify_filename = getConnectorValueFromProfile(settings, profile, VERIFY_TEMPLATE_KEY); + this.verify_template = FileHelper.readFromFile(SettingsReader.relocateFile(verify_filename)); + } + if (this.verify_template == null) { // TODO make this a settings exception diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedIdFormatter.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedIdFormatter.java index 7220857..7e67d0d 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedIdFormatter.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedIdFormatter.java @@ -21,7 +21,10 @@ public class DetachedIdFormatter implements IdFormatter */ public static String SIG_ID_PREFIX = "etsi-bka-1.0"; //$NON-NLS-1$ - public static final String SIG_ID_KEY = "default.bku.algorithm.id"; + /** + * Key value in property file + */ + public static final String SIG_ID_PROPERTY_KEY = "default.bku.algorithm.id"; /** * The log. @@ -33,13 +36,13 @@ public class DetachedIdFormatter implements IdFormatter */ public String formatIds(String[] ids) { - // read SIG_ID_PREFIX from config file + // read id from property file and use it try { - SIG_ID_PREFIX = SettingsReader.getInstance().getValueFromKey(SIG_ID_KEY); + SIG_ID_PREFIX = SettingsReader.getInstance().getValueFromKey(SIG_ID_PROPERTY_KEY); } catch (SettingsException e) { e.printStackTrace(); } - + // ids algorithm: String join = ""; //$NON-NLS-1$ String base = null; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java index ec6d054..cc28adc 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/DetachedLocRefMOAIdFormatter.java @@ -17,23 +17,27 @@ public class DetachedLocRefMOAIdFormatter implements IdFormatter * Default value: etsi-bka-moa-1.0 */ public static String SIG_ID_PREFIX = "etsi-bka-moa-1.0"; //$NON-NLS-1$ - public static String SIG_ID_KEY = "default.moa.algorithm.id"; + + /** + * Key value in property file + */ + public static final String SIG_ID_PROPERTY_KEY = "default.moa.algorithm.id"; /** * @see at.knowcenter.wag.egov.egiz.sig.sigid.IdFormatter#formatIds(java.lang.String[]) */ public String formatIds(String[] ids) { - String tmp = null; - - try { - tmp = SettingsReader.getInstance().getValueFromKey(SIG_ID_KEY); - if(tmp != null) - SIG_ID_PREFIX = tmp; - } catch (SettingsException e) { - e.printStackTrace(); - } - + // read id from property file and use it + + try + { + SIG_ID_PREFIX = SettingsReader.getInstance().getValueFromKey(SIG_ID_PROPERTY_KEY); + } catch (SettingsException e) + { + e.printStackTrace(); + } + return SIG_ID_PREFIX; } } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/OldMOAIdFormatter.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/OldMOAIdFormatter.java index 05f5db8..ab322d9 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/OldMOAIdFormatter.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigid/OldMOAIdFormatter.java @@ -15,7 +15,8 @@ public class OldMOAIdFormatter implements IdFormatter */ public String formatIds(String[] ids) { - return null; + return "etsi-bka-moa-1.0"; } } + diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java index e751248..f2ec571 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/sigkz/SigKZIDHelper.java @@ -46,22 +46,14 @@ public final class SigKZIDHelper return sig_id == null; } - // :begin - if(sig_id == null) return true; - if(sig_id.equals("")) - return true; - - // :end - // new signature - sig_id decides String [] ids = sig_id.split("@"); String prefix = ids[0]; if (prefix.equals(DetachedLocRefMOAIdFormatter.SIG_ID_PREFIX)) - //if(!prefix.equals("")) { return true; } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java index 3a79939..1ab89ed 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyPreviewServlet.java @@ -561,7 +561,7 @@ public class VerifyPreviewServlet extends HttpServlet URL loc_ref_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); - List results = PdfAS.verifySignatureHoldersWeb(holders_to_verify, si.connector, loc_ref_url); + List results = PdfAS.verifySignatureHoldersWeb(holders_to_verify, si, loc_ref_url); boolean backbutton = true; if (verify_which >= 0) { @@ -697,7 +697,7 @@ public class VerifyPreviewServlet extends HttpServlet URL loc_ref_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); - List results = PdfAS.verifySignatureHoldersWeb(holders_to_verify, si.connector, loc_ref_url); + List results = PdfAS.verifySignatureHoldersWeb(holders_to_verify, si, loc_ref_url); dispatchToResults(results, request, response, true); } catch (FileUploadException e) diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java index ba740d0..3ae5d1b 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/servlets/VerifyServlet.java @@ -111,9 +111,7 @@ public class VerifyServlet extends HttpServlet si.signature_holders = signature_holders; request.getSession().setAttribute(SessionAttributes.ATTRIBUTE_SESSION_INFORMATION, si); - System.out.println("\n\n-----------------------------------------------------------------------"); - System.out.println(); - System.out.println("-----------------------------------------------------------------------\n\n"); + if (ud.preview) { dispatch(request, response, "/jsp/verifylist.jsp"); @@ -133,7 +131,7 @@ public class VerifyServlet extends HttpServlet URL loc_ref_URL = new URL(request.getScheme(), host, request.getServerPort(), request.getContextPath() + "/RetrieveSignatureData"); String loc_ref_url = response.encodeURL(loc_ref_URL.toString()); - List results = PdfAS.verifySignatureHoldersWeb(signature_holders, si.connector, loc_ref_url); + List results = PdfAS.verifySignatureHoldersWeb(signature_holders, si, loc_ref_url); dispatchToResults(results, request, response); } -- cgit v1.2.3