/** * Place to put some hacks if needed on incoming requests. * * @param event the incoming request event. * @return status <code>true</code> if we don't need to process this message, just discard it and * <code>false</code> otherwise. */ private boolean applyNonConformanceHacks(RequestEvent event) { Request request = event.getRequest(); try { /* * Max-Forwards is required, yet there are UAs which do not * place it. SipProvider#getNewServerTransaction(Request) * will throw an exception in the case of a missing * Max-Forwards header and this method will eventually just * log it thus ignoring the whole event. */ if (request.getHeader(MaxForwardsHeader.NAME) == null) { // it appears that some buggy providers do send requests // with no Max-Forwards headers, as we are at application level // and we know there will be no endless loops // there is no problem of adding headers and process normally // this messages MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70); request.setHeader(maxForwards); } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } try { // using asterisk voice mail initial notify for messages // is ok, but on the fly received messages their notify comes // without subscription-state, so we add it in order to be able to // process message. if (request.getMethod().equals(Request.NOTIFY) && request.getHeader(EventHeader.NAME) != null && ((EventHeader) request.getHeader(EventHeader.NAME)) .getEventType() .equals(OperationSetMessageWaitingSipImpl.EVENT_PACKAGE) && request.getHeader(SubscriptionStateHeader.NAME) == null) { request.addHeader( new HeaderFactoryImpl().createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE)); } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } try { // receiving notify message without subscription state // used for keep-alive pings, they have done their job // and are no more need. Skip processing them to avoid // filling logs with unneeded exceptions. if (request.getMethod().equals(Request.NOTIFY) && request.getHeader(SubscriptionStateHeader.NAME) == null) { return true; } } catch (Throwable ex) { logger.warn("Cannot apply incoming request modification!", ex); } return false; }
/** * Attach any custom headers pre configured for the account. Added only to message Requests. The * header account properties are of form: ConfigHeader.N.Name=HeaderName * ConfigHeader.N.Value=HeaderValue ConfigHeader.N.Method=SIP_MethodName (optional) Where N is the * index of the header, multiple custom headers can be added. Name is the header name to use and * Value is its value. The optional property is whether to use a specific request method to attach * headers to or if missing we will attach it to all requests. * * @param message the message that we'd like to attach custom headers to. * @param protocolProvider the protocol provider to check for configured custom headers. */ static void attachConfigHeaders( Message message, ProtocolProviderServiceSipImpl protocolProvider) { if (message instanceof Response) return; Request request = (Request) message; Map<String, String> props = protocolProvider.getAccountID().getAccountProperties(); Map<String, Map<String, String>> headers = new HashMap<String, Map<String, String>>(); // parse the properties into the map where the index is the key for (Map.Entry<String, String> entry : props.entrySet()) { String pName = entry.getKey(); String prefStr = entry.getValue(); String name; String ix; if (!pName.startsWith(ACC_PROPERTY_CONFIG_HEADER) || prefStr == null) continue; prefStr = prefStr.trim(); if (pName.contains(".")) { pName = pName.replaceAll(ACC_PROPERTY_CONFIG_HEADER + ".", ""); name = pName.substring(pName.lastIndexOf('.') + 1).trim(); if (!pName.contains(".")) continue; ix = pName.substring(0, pName.lastIndexOf('.')).trim(); } else continue; Map<String, String> headerValues = headers.get(ix); if (headerValues == null) { headerValues = new HashMap<String, String>(); headers.put(ix, headerValues); } headerValues.put(name, prefStr); } // process the found custom headers for (Map<String, String> headerValues : headers.values()) { String method = headerValues.get(ACC_PROPERTY_CONFIG_HEADER_METHOD); // if there is a method setting and is different from // current request method skip this header // if any of the required properties are missing skip (Name & Value) if ((method != null && !request.getMethod().equalsIgnoreCase(method)) || !headerValues.containsKey(ACC_PROPERTY_CONFIG_HEADER_NAME) || !headerValues.containsKey(ACC_PROPERTY_CONFIG_HEADER_VALUE)) continue; try { String name = headerValues.get(ACC_PROPERTY_CONFIG_HEADER_NAME); String value = processParams(headerValues.get(ACC_PROPERTY_CONFIG_HEADER_VALUE), request); Header h = request.getHeader(name); // makes possible overriding already created headers which // are not custom one // RouteHeader is used by ProxyRouter/DefaultRouter and we // cannot use it as custom header if we want to add it if ((h != null && !(h instanceof CustomHeader)) || name.equals(SIPHeaderNames.ROUTE)) { request.setHeader(protocolProvider.getHeaderFactory().createHeader(name, value)); } else request.addHeader(new CustomHeaderList(name, value)); } catch (Exception e) { logger.error("Cannot create custom header", e); } } }