⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 responseforwarding.java

📁 The source code for this package is located in src/gov/nist/sip/proxy. The proxy is a pure JAIN-SIP
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			/** ************************************************************************* */			/** ************* 6. Choosing the best response ******* */			/** ************************************************************************* */			/*			 * A proxy MUST NOT insert a tag into the To header field of a 1xx			 * or 2xx response if the request did not contain one. A proxy MUST			 * NOT modify the tag in the To header field of a 1xx or 2xx			 * response.			 * 			 * An element SHOULD preserve the To tag when simply forwarding a			 * 3-6xx response to a request that did not contain a To tag.			 * 			 * A proxy MUST NOT modify the To tag in any forwarded response to a			 * request that contains a To tag.			 */			/** ************************************************************************** */			/**			 * ************** 7. Aggregate Authorization Header Field Values			 * *******			 */			/** ************************************************************************* */			/** ************************************************************************* */			/** ************** 8. Record-Route ******* */			/** ************************************************************************* */			// we don't modify the record-route...			/** ************************************************************************** */			/** ************** 9. Forward response ******* */			/** ************************************************************************** */			/*			 * 16.7. 9. Forward response: The proxy MUST pass the response to			 * the server transaction associated with the response context. This			 * will result in the response being sent to the location now			 * indicated in the topmost Via header field value. If the server			 * transaction is no longer available to handle the transmission,			 * the element MUST forward the response statelessly by sending it			 * to the server transport. The server transaction might indicate			 * failure to send the response or signal a timeout in its state			 * machine. These errors would be logged for diagnostic purposes as			 * appropriate, but the protocol requires no remedial action from			 * the proxy.			 */			ServerTransaction serverTransaction = transactionsMapping					.getServerTransaction(clientTransaction);			// For forking:			if ((response.getStatusCode() == 401 || response.getStatusCode() == 603)					&& serverTransaction != null) {				// check the busy or decline				Vector clientsTransactionList = transactionsMapping						.getClientTransactions(serverTransaction);				if (clientsTransactionList != null						&& clientsTransactionList.size() > 1) {					if (logger.isDebugEnabled())						logger								.debug("ResponseForwarding, forwardResponse() (STEP 9), "										+ "the BUSY or DECLINE corresponds to a forked call, "										+ " so we drop it and wait for"										+ " the others responses.");					transactionsMapping.removeMapping(clientTransaction);				}			}			// For forking:			if (response.getStatusCode() == 200 && serverTransaction != null ) {			  // Already responded to the server transaction with an OK.				if (serverTransaction.getState() == TransactionState.TERMINATED) {					if (logger.isDebugEnabled())						logger								.debug("ResponseForwarding, forwardResponse() (STEP 9), "										+ "the 200 OK corresponds to a forked call, "										+ "so we drop it and send a BYE");					Request byeRequest = (Request) clientTransaction							.getRequest().clone();					byeRequest.setMethod(Request.BYE);					ToHeader toHeader = (ToHeader) response							.getHeader(ToHeader.NAME);					byeRequest.setHeader((ToHeader) toHeader.clone());					ClientTransaction ct = sipProvider							.getNewClientTransaction(byeRequest);					ct.sendRequest();					if (logger.isDebugEnabled())						logger								.debug("ResponseForwarding, forwardResponse() (STEP 9), "										+ "BYE created and sent for 200 OK (forking):\n"										+ byeRequest.toString());					return;				} 			}			if (serverTransaction == null) {				sipProvider.sendResponse(response);				if (logger.isDebugEnabled())					logger							.debug("ResponseForwarding, forwardResponse() (STEP 9), the "									+ " response is statelessly"									+ " forwarded:\n" + response.toString());				return;			} else {				serverTransaction.sendResponse(response);				if (logger.isDebugEnabled())					logger							.debug("ResponseForwarding, forwardResponse() (STEP 9), the "									+ " response is statefully forwarded: \n"									+ response.toString());			}			/** ************************************************************************ */			/** ************ 10. Generate CANCELs ******* */			/** ************************************************************************* */			/*			 * If the forwarded response was a final response, the proxy MUST			 * generate a CANCEL request for all pending client transactions			 * associated with this response context. A proxy SHOULD also			 * generate a CANCEL request for all pending client transactions			 * associated with this response context when it receives a 6xx			 * response. A pending client transaction is one that has received a			 * provisional response, but no final response (it is in the			 * proceeding state) and has not had an associated CANCEL generated			 * for it. Generating CANCEL requests is described in Section 9.1.			 */			if (response.getStatusCode() == 200					|| (response.getStatusCode() >= 600 && response							.getStatusCode() <= 606) && cseqHeader.getMethod().equals("INVITE")) {				Vector clientsTransactionList = transactionsMapping						.getClientTransactions(serverTransaction);				for (Enumeration e = clientsTransactionList.elements(); e						.hasMoreElements();) {					ClientTransaction ctr = (ClientTransaction) e.nextElement();					if (ctr != clientTransaction) {						TransactionState transactionState = ctr.getState();						if (transactionState == null								|| transactionState == TransactionState.PROCEEDING) {							/*							 * 9.1: The following procedures are used to							 * construct a CANCEL request. The Request-URI,							 * Call-ID, To, the numeric part of CSeq, and From							 * header fields in the CANCEL request MUST be							 * identical to those in the request being							 * cancelled, including tags. A CANCEL constructed							 * by a client MUST have only a single Via header							 * field value matching the top Via value in the							 * request being cancelled. Using the same values							 * for these header fields allows the CANCEL to be							 * matched with the request it cancels (Section 9.2							 * indicates how such matching occurs). However, the							 * method part of the CSeq header field MUST have a							 * value of CANCEL. This allows it to be identified							 * and processed as a transaction in its own right							 * (See Section 17).							 * 							 * If the request being cancelled contains a Route							 * header field, the CANCEL request MUST include							 * that Route header field's values.							 */							Request cancelRequest = ctr.createCancel();							// Let's keep only the top most via header:							ListIterator cancelViaList = cancelRequest									.getHeaders(ViaHeader.NAME);							cancelRequest.removeHeader(ViaHeader.NAME);							cancelRequest.addHeader((ViaHeader) cancelViaList									.next());							ClientTransaction ct = sipProvider									.getNewClientTransaction(cancelRequest);							ct.sendRequest();							if (logger.isDebugEnabled())								logger										.debug("ResponseForwarding, forwardResponse()"												+ " (STEP 10), CANCEL created"												+ " and sent for cancel the pending "												+ "transactions:\n"												+ cancelRequest.toString());						}					}				}			}		} catch (Exception ex) {			logger.error(					"ResponseForwarding, forwardResponse(), internal error, "							+ "exception raised:", ex);		} finally {			if (clientTransaction != null					&& ( clientTransaction.getState().equals(							TransactionState.COMPLETED) ||					clientTransaction.getState() == TransactionState.TERMINATED) ) {				transactionsMapping = (TransactionsMapping) clientTransaction						.getApplicationData();				if (transactionsMapping != null)					transactionsMapping.removeMapping(clientTransaction);			}		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -