📄 responseforwarding.java
字号:
/* * ResponseForwarding.java * * Created on April 16, 2003, 11:09 AM */package gov.nist.sip.proxy;import java.util.*;import javax.sip.*;import javax.sip.message.*;import javax.sip.header.*;import javax.sip.address.*;import org.apache.log4j.Logger;import gov.nist.sip.proxy.presenceserver.*;/** * * @author deruelle */public class ResponseForwarding { protected Proxy proxy; private static Logger logger = Logger.getLogger(ResponseForwarding.class); /** Creates a new instance of ResponseForwarding */ public ResponseForwarding(Proxy proxy) { this.proxy = proxy; } protected void forwardResponse(SipProvider sipProvider, Response response, ClientTransaction clientTransaction) { SipStack sipStack = proxy.getSipStack(); TransactionsMapping transactionsMapping = null; try { /** * ***************** PROXY BEHAVIOR * *********************************** */ /* * RFC 3261: 16.7. Response Processing: When a response is received * by an element, it first tries to locate a client transaction * (Section 17.1.3) matching the response. If none is found, the * element MUST process the response (even if it is an informational * response) as a stateless proxy (described below). If a match is * found, the response is handed to the client transaction. 1. Find * the appropriate response context 2. Update timer C for * provisional responses 3. Remove the topmost Via 4. Add the * response to the response context 5. Check to see if this response * should be forwarded immediately 6. When necessary, choose the * best final response from the response context 7. Aggregate * authorization header field values if necessary 8. Optionally * rewrite Record-Route header field values 9. Forward the response * 10. Generate any necessary CANCEL requests * * 16.11: Response processing as described in Section 16.7 does not * apply to a proxy behaving statelessly. When a response arrives at * a stateless proxy, the proxy MUST inspect the sent-by value in * the first (topmost) Via header field value. If that address * matches the proxy, (it equals a value this proxy has inserted * into previous requests) the proxy MUST remove that header field * value from the response and forward the result to the location * indicated in the next Via header field value. The proxy MUST NOT * add to, modify, or remove the message body. Unless specified * otherwise, the proxy MUST NOT remove any other header field * values. If the address does not match the proxy, the message MUST * be silently discarded. */ if (clientTransaction == null || clientTransaction.getDialog() == null) { if (logger.isDebugEnabled()) logger.debug("ResponseForwarding, forwardResponse(), " + " the client transaction does not exist, " + " will forward the response statelessly!"); if (ProxyUtilities.hasTopViaHeaderProxy(sipStack, response)) { ListIterator viaList = response.getHeaders(ViaHeader.NAME); response.removeHeader(ViaHeader.NAME); Vector v = new Vector(); viaList.next(); while (viaList != null && viaList.hasNext()) { ViaHeader viaHeader = (ViaHeader) viaList.next(); v.addElement(viaHeader); } for (int j = 0; j < v.size(); j++) { ViaHeader viaHeader = (ViaHeader) v.elementAt(j); response.addHeader(viaHeader); } viaList = response.getHeaders(ViaHeader.NAME); if (viaList == null || !viaList.hasNext()) { if (logger.isDebugEnabled()) logger .debug("ResponseForwarding, forwardResponse(), " + "the response does " + " not have any Via header, the response is " + "silently discarded"); } else { // let's hope the sipProvider will take the Viaheader to // forward the response... sipProvider.sendResponse(response); if (logger.isDebugEnabled()) logger .debug("ResponseForwarding, forwardResponse(), " + "the response statelessly forwarded:\n" + response.toString()); } return; } else { // If the address does not match the // proxy, the message MUST be silently discarded. if (logger.isDebugEnabled()) logger .debug("ResponseForwarding, forwardResponse(), " + "the address (Via header)does not" + " match the proxy, the message is silently discarded"); return; } } if (clientTransaction.getDialog() == null) return; else transactionsMapping = (TransactionsMapping) clientTransaction .getDialog().getApplicationData(); /** ************************************************************************ */ /** * ********************** 1. Find the appropriate response context * ******* */ /** ************************************************************************ */ /* * The proxy locates the "response context" it created before * forwarding the original request using the key described in * Section 16.6. The remaining processing steps take place in this * context. */ /** ************************************************************************* */ /** ************ 2. Update timer C for provisional responses ******* */ /** ************************************************************************* */ // I guess it is done by the stack.... /** ************************************************************************* */ /** ************* 3. Via ******* */ /** ************************************************************************* */ /* * The proxy removes the topmost Via header field value from the * response. If no Via header field values remain in the response, * the response was meant for this element and MUST NOT be * forwarded. The remainder of the processing described in this * section is not performed on this message, the UAC processing * rules described in Section 8.1.3 are followed instead (transport * layer processing has already occurred). */ ListIterator viaList = response.getHeaders(ViaHeader.NAME); viaList.next(); viaList.remove(); if (!viaList.hasNext()) { logger .debug("ResponseForwarding, forwardResponse() (STEP 3)," + " the response does not " + " contain any Via headers, the response was meant for " + " the proxy and MUST NOT be forwarded"); return; } /** ************************************************************************** */ /** ************* 4. Add response to context ******* */ /** ************************************************************************* */ // The stack takes care of that... /** ************************************************************************ */ /** ************ 5. Check response for forwarding ******* */ /** ************************************************************************ */ /* * Until a final response has been sent on the server transaction, * the following responses MUST be forwarded immediately: - Any * provisional response other than 100 (Trying) - Any 2xx response */ if (response.getStatusCode() == 100) { if (logger.isDebugEnabled()) logger .debug("ResponseForwarding, forwardResponse() (STEP 5)" + " don't forward the 100 Trying."); return; } if (response.getStatusCode() == 487) { if (logger.isDebugEnabled()) logger .debug("ResponseForwarding, forwardResponse() (STEP 5)," + " we don't forward the" + " 487 Request terminated, in statefull behavior " + " (it's for the proxy)."); return; } CSeqHeader cseqHeader = (CSeqHeader) response .getHeader(CSeqHeader.NAME);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -