001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.core.impl.checker; 017 018import java.io.IOException; 019import java.net.HttpURLConnection; 020import java.net.MalformedURLException; 021import java.net.ProtocolException; 022import java.net.URL; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026import java.util.Map.Entry; 027import java.util.Set; 028 029import org.apache.avalon.framework.configuration.Configurable; 030import org.apache.avalon.framework.configuration.Configuration; 031import org.apache.avalon.framework.configuration.ConfigurationException; 032import org.apache.cocoon.util.StringUtils; 033import org.apache.commons.lang.ArrayUtils; 034 035import org.ametys.runtime.model.checker.ItemChecker; 036import org.ametys.runtime.model.checker.ItemCheckerTestFailureException; 037 038/** 039 * Checks if the url written is correct and if it allows to establish a connection with the given configuration. 040 */ 041public class HttpUrlChecker implements ItemChecker, Configurable 042{ 043 /** The user agent */ 044 protected String _userAgent; 045 046 /** The method */ 047 protected String _method; 048 049 /** The timeout */ 050 protected int _timeout; 051 052 /** The acceptable response codes */ 053 protected String _okCodes; 054 055 /** The values the header must have */ 056 protected Map<String, String> _requestHeaderValues; 057 058 /** The values the header must have */ 059 protected Map<String, String> _responseHeaderValues; 060 061 /** Something to add to the parameter */ 062 protected String _additionnalURL; 063 064 public void configure(Configuration configuration) throws ConfigurationException 065 { 066 Configuration config = configuration.getChild("configuration"); 067 Configuration requestConfig = config.getChild("request"); 068 Configuration responseConfig = config.getChild("response"); 069 070 Configuration timeoutConfig = requestConfig.getChild("timeout", false); 071 072 _timeout = timeoutConfig != null ? timeoutConfig.getValueAsInteger() : -1; 073 _userAgent = requestConfig.getChild("user-agent").getValue(null); 074 _method = requestConfig.getChild("method").getValue(null); 075 _additionnalURL = requestConfig.getChild("additionnal-url").getValue(""); 076 _requestHeaderValues = new HashMap<> (); 077 for (Configuration headerChildConfig : requestConfig.getChild("header").getChildren()) 078 { 079 _requestHeaderValues.put(headerChildConfig.getName(), headerChildConfig.getValue()); 080 } 081 082 _okCodes = responseConfig.getChild("code").getValue(null); 083 084 _responseHeaderValues = new HashMap<> (); 085 for (Configuration headerChildConfig : responseConfig.getChild("header").getChildren()) 086 { 087 _responseHeaderValues.put(headerChildConfig.getName(), headerChildConfig.getValue()); 088 } 089 } 090 091 @Override 092 public void check(List<String> values) throws ItemCheckerTestFailureException 093 { 094 String configUrl = values.get(0); 095 096 try 097 { 098 HttpURLConnection httpUrlConnection = _prepareConnection(configUrl + _additionnalURL); 099 100 // Do the connection 101 int responseCode = httpUrlConnection.getResponseCode(); 102 103 _testResponseCode(httpUrlConnection, responseCode); 104 _testHeaders(httpUrlConnection); 105 } 106 catch (IOException e) 107 { 108 throw new ItemCheckerTestFailureException("Unable to contact '" + configUrl + _additionnalURL + "' (" + e.getMessage() + ")", e); 109 } 110 } 111 112 private HttpURLConnection _prepareConnection(String configUrl) throws IOException, MalformedURLException, ProtocolException 113 { 114 HttpURLConnection httpUrlConnection = (HttpURLConnection) new URL(configUrl).openConnection(); 115 116 if (_userAgent != null) 117 { 118 httpUrlConnection.setRequestProperty("User-Agent", _userAgent); 119 } 120 if (_method != null) 121 { 122 httpUrlConnection.setRequestMethod(_method); 123 } 124 if (_timeout != -1) 125 { 126 httpUrlConnection.setReadTimeout(_timeout); 127 } 128 for (Entry<String, String> headers : _requestHeaderValues.entrySet()) 129 { 130 httpUrlConnection.setRequestProperty(headers.getKey(), headers.getValue()); 131 } 132 133 return httpUrlConnection; 134 } 135 136 private void _testHeaders(HttpURLConnection httpUrlConnection) throws ItemCheckerTestFailureException 137 { 138 Set<String> keys = _responseHeaderValues.keySet(); 139 for (String key : keys) 140 { 141 if (httpUrlConnection.getHeaderField(key) == null) 142 { 143 throw new ItemCheckerTestFailureException("The header field '" + key + "' does not exist"); 144 } 145 146 if (!httpUrlConnection.getHeaderField(key).equals(_responseHeaderValues.get(key))) 147 { 148 throw new ItemCheckerTestFailureException("The header field '" + key + "' does not have the expected value '" + _responseHeaderValues.get(key) + "', found '" + httpUrlConnection.getHeaderField(key) + "' instead."); 149 } 150 } 151 } 152 153 private void _testResponseCode(HttpURLConnection httpUrlConnection, int responseCode) throws ItemCheckerTestFailureException, IOException 154 { 155 String[] okCodes = {Integer.toString(HttpURLConnection.HTTP_OK)}; 156 if (_okCodes != null) 157 { 158 okCodes = StringUtils.split(_okCodes, ","); 159 } 160 if (!ArrayUtils.contains(okCodes, Integer.toString(responseCode))) 161 { 162 throw new ItemCheckerTestFailureException("Error code " + responseCode + ". Message: " + httpUrlConnection.getResponseMessage()); 163 } 164 } 165}