736 lines
22 KiB
Java
736 lines
22 KiB
Java
/*
|
|
* Conditions Of Use
|
|
*
|
|
* This software was developed by employees of the National Institute of
|
|
* Standards and Technology (NIST), an agency of the Federal Government.
|
|
* Pursuant to title 15 Untied States Code Section 105, works of NIST
|
|
* employees are not subject to copyright protection in the United States
|
|
* and are considered to be in the public domain. As a result, a formal
|
|
* license is not needed to use the software.
|
|
*
|
|
* This software is provided by NIST as a service and is expressly
|
|
* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
|
|
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
|
|
* AND DATA ACCURACY. NIST does not warrant or make any representations
|
|
* regarding the use of the software or the results thereof, including but
|
|
* not limited to the correctness, accuracy, reliability or usefulness of
|
|
* the software.
|
|
*
|
|
* Permission to use this software is contingent upon your acceptance
|
|
* of the terms of this agreement
|
|
*
|
|
* .
|
|
*
|
|
*/
|
|
/*******************************************************************************
|
|
* Product of NIST/ITL Advanced Networking Technologies Division (ANTD) *
|
|
*******************************************************************************/
|
|
package gov.nist.javax.sip.message;
|
|
|
|
import gov.nist.core.InternalErrorHandler;
|
|
import gov.nist.javax.sip.Utils;
|
|
import gov.nist.javax.sip.address.SipUri;
|
|
import gov.nist.javax.sip.header.CSeq;
|
|
import gov.nist.javax.sip.header.CallID;
|
|
import gov.nist.javax.sip.header.ContactList;
|
|
import gov.nist.javax.sip.header.ContentLength;
|
|
import gov.nist.javax.sip.header.ContentType;
|
|
import gov.nist.javax.sip.header.From;
|
|
import gov.nist.javax.sip.header.MaxForwards;
|
|
import gov.nist.javax.sip.header.ReasonList;
|
|
import gov.nist.javax.sip.header.RecordRouteList;
|
|
import gov.nist.javax.sip.header.RequireList;
|
|
import gov.nist.javax.sip.header.SIPHeader;
|
|
import gov.nist.javax.sip.header.StatusLine;
|
|
import gov.nist.javax.sip.header.To;
|
|
import gov.nist.javax.sip.header.Via;
|
|
import gov.nist.javax.sip.header.ViaList;
|
|
import gov.nist.javax.sip.header.extensions.SessionExpires;
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.text.ParseException;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
|
|
import javax.sip.header.ReasonHeader;
|
|
import javax.sip.header.ServerHeader;
|
|
import javax.sip.message.Request;
|
|
|
|
|
|
/**
|
|
* SIP Response structure.
|
|
*
|
|
* @version 1.2 $Revision: 1.29 $ $Date: 2009/10/25 03:07:52 $
|
|
* @since 1.1
|
|
*
|
|
* @author M. Ranganathan <br/>
|
|
*
|
|
*
|
|
*/
|
|
public final class SIPResponse
|
|
extends SIPMessage
|
|
implements javax.sip.message.Response, ResponseExt {
|
|
protected StatusLine statusLine;
|
|
|
|
public static String getReasonPhrase(int rc) {
|
|
String retval = null;
|
|
switch (rc) {
|
|
|
|
case TRYING :
|
|
retval = "Trying";
|
|
break;
|
|
|
|
case RINGING :
|
|
retval = "Ringing";
|
|
break;
|
|
|
|
case CALL_IS_BEING_FORWARDED :
|
|
retval = "Call is being forwarded";
|
|
break;
|
|
|
|
case QUEUED :
|
|
retval = "Queued";
|
|
break;
|
|
|
|
case SESSION_PROGRESS :
|
|
retval = "Session progress";
|
|
break;
|
|
|
|
case OK :
|
|
retval = "OK";
|
|
break;
|
|
|
|
case ACCEPTED :
|
|
retval = "Accepted";
|
|
break;
|
|
|
|
case MULTIPLE_CHOICES :
|
|
retval = "Multiple choices";
|
|
break;
|
|
|
|
case MOVED_PERMANENTLY :
|
|
retval = "Moved permanently";
|
|
break;
|
|
|
|
case MOVED_TEMPORARILY :
|
|
retval = "Moved Temporarily";
|
|
break;
|
|
|
|
case USE_PROXY :
|
|
retval = "Use proxy";
|
|
break;
|
|
|
|
case ALTERNATIVE_SERVICE :
|
|
retval = "Alternative service";
|
|
break;
|
|
|
|
case BAD_REQUEST :
|
|
retval = "Bad request";
|
|
break;
|
|
|
|
case UNAUTHORIZED :
|
|
retval = "Unauthorized";
|
|
break;
|
|
|
|
case PAYMENT_REQUIRED :
|
|
retval = "Payment required";
|
|
break;
|
|
|
|
case FORBIDDEN :
|
|
retval = "Forbidden";
|
|
break;
|
|
|
|
case NOT_FOUND :
|
|
retval = "Not found";
|
|
break;
|
|
|
|
case METHOD_NOT_ALLOWED :
|
|
retval = "Method not allowed";
|
|
break;
|
|
|
|
case NOT_ACCEPTABLE :
|
|
retval = "Not acceptable";
|
|
break;
|
|
|
|
case PROXY_AUTHENTICATION_REQUIRED :
|
|
retval = "Proxy Authentication required";
|
|
break;
|
|
|
|
case REQUEST_TIMEOUT :
|
|
retval = "Request timeout";
|
|
break;
|
|
|
|
case GONE :
|
|
retval = "Gone";
|
|
break;
|
|
|
|
case TEMPORARILY_UNAVAILABLE :
|
|
retval = "Temporarily Unavailable";
|
|
break;
|
|
|
|
case REQUEST_ENTITY_TOO_LARGE :
|
|
retval = "Request entity too large";
|
|
break;
|
|
|
|
case REQUEST_URI_TOO_LONG :
|
|
retval = "Request-URI too large";
|
|
break;
|
|
|
|
case UNSUPPORTED_MEDIA_TYPE :
|
|
retval = "Unsupported media type";
|
|
break;
|
|
|
|
case UNSUPPORTED_URI_SCHEME :
|
|
retval = "Unsupported URI Scheme";
|
|
break;
|
|
|
|
case BAD_EXTENSION :
|
|
retval = "Bad extension";
|
|
break;
|
|
|
|
case EXTENSION_REQUIRED :
|
|
retval = "Etension Required";
|
|
break;
|
|
|
|
case INTERVAL_TOO_BRIEF :
|
|
retval = "Interval too brief";
|
|
break;
|
|
|
|
case CALL_OR_TRANSACTION_DOES_NOT_EXIST :
|
|
retval = "Call leg/Transaction does not exist";
|
|
break;
|
|
|
|
case LOOP_DETECTED :
|
|
retval = "Loop detected";
|
|
break;
|
|
|
|
case TOO_MANY_HOPS :
|
|
retval = "Too many hops";
|
|
break;
|
|
|
|
case ADDRESS_INCOMPLETE :
|
|
retval = "Address incomplete";
|
|
break;
|
|
|
|
case AMBIGUOUS :
|
|
retval = "Ambiguous";
|
|
break;
|
|
|
|
case BUSY_HERE :
|
|
retval = "Busy here";
|
|
break;
|
|
|
|
case REQUEST_TERMINATED :
|
|
retval = "Request Terminated";
|
|
break;
|
|
|
|
//Issue 168, Typo fix reported by fre on the retval
|
|
case NOT_ACCEPTABLE_HERE :
|
|
retval = "Not Acceptable here";
|
|
break;
|
|
|
|
case BAD_EVENT :
|
|
retval = "Bad Event";
|
|
break;
|
|
|
|
case REQUEST_PENDING :
|
|
retval = "Request Pending";
|
|
break;
|
|
|
|
case SERVER_INTERNAL_ERROR :
|
|
retval = "Server Internal Error";
|
|
break;
|
|
|
|
case UNDECIPHERABLE :
|
|
retval = "Undecipherable";
|
|
break;
|
|
|
|
case NOT_IMPLEMENTED :
|
|
retval = "Not implemented";
|
|
break;
|
|
|
|
case BAD_GATEWAY :
|
|
retval = "Bad gateway";
|
|
break;
|
|
|
|
case SERVICE_UNAVAILABLE :
|
|
retval = "Service unavailable";
|
|
break;
|
|
|
|
case SERVER_TIMEOUT :
|
|
retval = "Gateway timeout";
|
|
break;
|
|
|
|
case VERSION_NOT_SUPPORTED :
|
|
retval = "SIP version not supported";
|
|
break;
|
|
|
|
case MESSAGE_TOO_LARGE :
|
|
retval = "Message Too Large";
|
|
break;
|
|
|
|
case BUSY_EVERYWHERE :
|
|
retval = "Busy everywhere";
|
|
break;
|
|
|
|
case DECLINE :
|
|
retval = "Decline";
|
|
break;
|
|
|
|
case DOES_NOT_EXIST_ANYWHERE :
|
|
retval = "Does not exist anywhere";
|
|
break;
|
|
|
|
case SESSION_NOT_ACCEPTABLE :
|
|
retval = "Session Not acceptable";
|
|
break;
|
|
|
|
case CONDITIONAL_REQUEST_FAILED:
|
|
retval = "Conditional request failed";
|
|
break;
|
|
|
|
default :
|
|
retval = "Unknown Status";
|
|
|
|
}
|
|
return retval;
|
|
|
|
}
|
|
|
|
/** set the status code.
|
|
*@param statusCode is the status code to set.
|
|
*@throws IlegalArgumentException if invalid status code.
|
|
*/
|
|
public void setStatusCode(int statusCode) throws ParseException {
|
|
|
|
// RFC3261 defines statuscode as 3DIGIT, 606 is the highest officially
|
|
// defined code but extensions may add others (in theory up to 999,
|
|
// but in practice up to 699 since the 6xx range is defined as 'final error')
|
|
if (statusCode < 100 || statusCode > 699)
|
|
throw new ParseException("bad status code", 0);
|
|
if (this.statusLine == null)
|
|
this.statusLine = new StatusLine();
|
|
this.statusLine.setStatusCode(statusCode);
|
|
}
|
|
|
|
/**
|
|
* Get the status line of the response.
|
|
*@return StatusLine
|
|
*/
|
|
public StatusLine getStatusLine() {
|
|
return statusLine;
|
|
}
|
|
|
|
/** Get the staus code (conveniance function).
|
|
*@return the status code of the status line.
|
|
*/
|
|
public int getStatusCode() {
|
|
return statusLine.getStatusCode();
|
|
}
|
|
|
|
/** Set the reason phrase.
|
|
*@param reasonPhrase the reason phrase.
|
|
*@throws IllegalArgumentException if null string
|
|
*/
|
|
public void setReasonPhrase(String reasonPhrase) {
|
|
if (reasonPhrase == null)
|
|
throw new IllegalArgumentException("Bad reason phrase");
|
|
if (this.statusLine == null)
|
|
this.statusLine = new StatusLine();
|
|
this.statusLine.setReasonPhrase(reasonPhrase);
|
|
}
|
|
|
|
/** Get the reason phrase.
|
|
*@return the reason phrase.
|
|
*/
|
|
public String getReasonPhrase() {
|
|
if (statusLine == null || statusLine.getReasonPhrase() == null)
|
|
return "";
|
|
else
|
|
return statusLine.getReasonPhrase();
|
|
}
|
|
|
|
/** Return true if the response is a final response.
|
|
*@param rc is the return code.
|
|
*@return true if the parameter is between the range 200 and 700.
|
|
*/
|
|
public static boolean isFinalResponse(int rc) {
|
|
return rc >= 200 && rc < 700;
|
|
}
|
|
|
|
/** Is this a final response?
|
|
*@return true if this is a final response.
|
|
*/
|
|
public boolean isFinalResponse() {
|
|
return isFinalResponse(statusLine.getStatusCode());
|
|
}
|
|
|
|
/**
|
|
* Set the status line field.
|
|
*@param sl Status line to set.
|
|
*/
|
|
public void setStatusLine(StatusLine sl) {
|
|
statusLine = sl;
|
|
}
|
|
|
|
/** Constructor.
|
|
*/
|
|
public SIPResponse() {
|
|
super();
|
|
}
|
|
/**
|
|
* Print formatting function.
|
|
*Indent and parenthesize for pretty printing.
|
|
* Note -- use the encode method for formatting the message.
|
|
* Hack here to XMLize.
|
|
*
|
|
*@return a string for pretty printing.
|
|
*/
|
|
public String debugDump() {
|
|
String superstring = super.debugDump();
|
|
stringRepresentation = "";
|
|
sprint(SIPResponse.class.getCanonicalName());
|
|
sprint("{");
|
|
if (statusLine != null) {
|
|
sprint(statusLine.debugDump());
|
|
}
|
|
sprint(superstring);
|
|
sprint("}");
|
|
return stringRepresentation;
|
|
}
|
|
|
|
/**
|
|
* Check the response structure. Must have from, to CSEQ and VIA
|
|
* headers.
|
|
*/
|
|
public void checkHeaders() throws ParseException {
|
|
if (getCSeq() == null) {
|
|
throw new ParseException(CSeq.NAME+ " Is missing ", 0);
|
|
}
|
|
if (getTo() == null) {
|
|
throw new ParseException(To.NAME+ " Is missing ", 0);
|
|
}
|
|
if (getFrom() == null) {
|
|
throw new ParseException(From.NAME+ " Is missing ", 0);
|
|
}
|
|
if (getViaHeaders() == null) {
|
|
throw new ParseException(Via.NAME+ " Is missing ", 0);
|
|
}
|
|
if (getCallId() == null) {
|
|
throw new ParseException(CallID.NAME + " Is missing ", 0);
|
|
}
|
|
|
|
|
|
if (getStatusCode() > 699) {
|
|
throw new ParseException("Unknown error code!" + getStatusCode(), 0);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Encode the SIP Request as a string.
|
|
*@return The string encoded canonical form of the message.
|
|
*/
|
|
|
|
public String encode() {
|
|
String retval;
|
|
if (statusLine != null)
|
|
retval = statusLine.encode() + super.encode();
|
|
else
|
|
retval = super.encode();
|
|
return retval ;
|
|
}
|
|
|
|
/** Encode the message except for the body.
|
|
*
|
|
*@return The string except for the body.
|
|
*/
|
|
|
|
public String encodeMessage() {
|
|
String retval;
|
|
if (statusLine != null)
|
|
retval = statusLine.encode() + super.encodeSIPHeaders();
|
|
else
|
|
retval = super.encodeSIPHeaders();
|
|
return retval ;
|
|
}
|
|
|
|
|
|
|
|
/** Get this message as a list of encoded strings.
|
|
*@return LinkedList containing encoded strings for each header in
|
|
* the message.
|
|
*/
|
|
|
|
public LinkedList getMessageAsEncodedStrings() {
|
|
LinkedList retval = super.getMessageAsEncodedStrings();
|
|
|
|
if (statusLine != null)
|
|
retval.addFirst(statusLine.encode());
|
|
return retval;
|
|
|
|
}
|
|
|
|
/**
|
|
* Make a clone (deep copy) of this object.
|
|
*@return a deep copy of this object.
|
|
*/
|
|
|
|
public Object clone() {
|
|
SIPResponse retval = (SIPResponse) super.clone();
|
|
if (this.statusLine != null)
|
|
retval.statusLine = (StatusLine) this.statusLine.clone();
|
|
return retval;
|
|
}
|
|
|
|
|
|
/**
|
|
* Compare for equality.
|
|
*@param other other object to compare with.
|
|
*/
|
|
public boolean equals(Object other) {
|
|
if (!this.getClass().equals(other.getClass()))
|
|
return false;
|
|
SIPResponse that = (SIPResponse) other;
|
|
return statusLine.equals(that.statusLine) && super.equals(other);
|
|
}
|
|
|
|
/**
|
|
* Match with a template.
|
|
*@param matchObj template object to match ourselves with (null
|
|
* in any position in the template object matches wildcard)
|
|
*/
|
|
public boolean match(Object matchObj) {
|
|
if (matchObj == null)
|
|
return true;
|
|
else if (!matchObj.getClass().equals(this.getClass())) {
|
|
return false;
|
|
} else if (matchObj == this)
|
|
return true;
|
|
SIPResponse that = (SIPResponse) matchObj;
|
|
|
|
StatusLine rline = that.statusLine;
|
|
if (this.statusLine == null && rline != null)
|
|
return false;
|
|
else if (this.statusLine == rline)
|
|
return super.match(matchObj);
|
|
else {
|
|
|
|
return statusLine.match(that.statusLine) && super.match(matchObj);
|
|
}
|
|
|
|
}
|
|
|
|
/** Encode this into a byte array.
|
|
* This is used when the body has been set as a binary array
|
|
* and you want to encode the body as a byte array for transmission.
|
|
*
|
|
*@return a byte array containing the SIPRequest encoded as a byte
|
|
* array.
|
|
*/
|
|
|
|
public byte[] encodeAsBytes( String transport ) {
|
|
byte[] slbytes = null;
|
|
if (statusLine != null) {
|
|
try {
|
|
slbytes = statusLine.encode().getBytes("UTF-8");
|
|
} catch (UnsupportedEncodingException ex) {
|
|
InternalErrorHandler.handleException(ex);
|
|
}
|
|
}
|
|
byte[] superbytes = super.encodeAsBytes( transport );
|
|
byte[] retval = new byte[slbytes.length + superbytes.length];
|
|
System.arraycopy(slbytes, 0, retval, 0, slbytes.length);
|
|
System.arraycopy(superbytes, 0, retval, slbytes.length,
|
|
superbytes.length);
|
|
return retval;
|
|
}
|
|
|
|
|
|
|
|
/** Get a dialog identifier.
|
|
* Generates a string that can be used as a dialog identifier.
|
|
*
|
|
* @param isServer is set to true if this is the UAS
|
|
* and set to false if this is the UAC
|
|
*/
|
|
public String getDialogId(boolean isServer) {
|
|
CallID cid = (CallID) this.getCallId();
|
|
From from = (From) this.getFrom();
|
|
To to = (To) this.getTo();
|
|
StringBuffer retval = new StringBuffer(cid.getCallId());
|
|
if (!isServer) {
|
|
//retval.append(COLON).append(from.getUserAtHostPort());
|
|
if (from.getTag() != null) {
|
|
retval.append(COLON);
|
|
retval.append(from.getTag());
|
|
}
|
|
//retval.append(COLON).append(to.getUserAtHostPort());
|
|
if (to.getTag() != null) {
|
|
retval.append(COLON);
|
|
retval.append(to.getTag());
|
|
}
|
|
} else {
|
|
//retval.append(COLON).append(to.getUserAtHostPort());
|
|
if (to.getTag() != null) {
|
|
retval.append(COLON);
|
|
retval.append(to.getTag());
|
|
}
|
|
//retval.append(COLON).append(from.getUserAtHostPort());
|
|
if (from.getTag() != null) {
|
|
retval.append(COLON);
|
|
retval.append(from.getTag());
|
|
}
|
|
}
|
|
return retval.toString().toLowerCase();
|
|
}
|
|
|
|
public String getDialogId(boolean isServer, String toTag) {
|
|
CallID cid = (CallID) this.getCallId();
|
|
From from = (From) this.getFrom();
|
|
StringBuffer retval = new StringBuffer(cid.getCallId());
|
|
if (!isServer) {
|
|
//retval.append(COLON).append(from.getUserAtHostPort());
|
|
if (from.getTag() != null) {
|
|
retval.append(COLON);
|
|
retval.append(from.getTag());
|
|
}
|
|
//retval.append(COLON).append(to.getUserAtHostPort());
|
|
if (toTag != null) {
|
|
retval.append(COLON);
|
|
retval.append(toTag);
|
|
}
|
|
} else {
|
|
//retval.append(COLON).append(to.getUserAtHostPort());
|
|
if (toTag != null) {
|
|
retval.append(COLON);
|
|
retval.append(toTag);
|
|
}
|
|
//retval.append(COLON).append(from.getUserAtHostPort());
|
|
if (from.getTag() != null) {
|
|
retval.append(COLON);
|
|
retval.append(from.getTag());
|
|
}
|
|
}
|
|
return retval.toString().toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Sets the Via branch for CANCEL or ACK requests
|
|
*
|
|
* @param via
|
|
* @param method
|
|
* @throws ParseException
|
|
*/
|
|
private final void setBranch( Via via, String method ) {
|
|
String branch;
|
|
if (method.equals( Request.ACK ) ) {
|
|
if (statusLine.getStatusCode() >= 300 ) {
|
|
branch = getTopmostVia().getBranch(); // non-2xx ACK uses same branch
|
|
} else {
|
|
branch = Utils.getInstance().generateBranchId(); // 2xx ACK gets new branch
|
|
}
|
|
} else if (method.equals( Request.CANCEL )) {
|
|
branch = getTopmostVia().getBranch(); // CANCEL uses same branch
|
|
} else return;
|
|
|
|
try {
|
|
via.setBranch( branch );
|
|
} catch (ParseException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the encoded first line.
|
|
*
|
|
*@return the status line encoded.
|
|
*
|
|
*/
|
|
public String getFirstLine() {
|
|
if (this.statusLine == null)
|
|
return null;
|
|
else
|
|
return this.statusLine.encode();
|
|
}
|
|
|
|
public void setSIPVersion(String sipVersion) {
|
|
this.statusLine.setSipVersion(sipVersion);
|
|
}
|
|
|
|
public String getSIPVersion() {
|
|
return this.statusLine.getSipVersion();
|
|
}
|
|
|
|
public String toString() {
|
|
if (statusLine == null) return "";
|
|
else return statusLine.encode() + super.encode();
|
|
}
|
|
|
|
/**
|
|
* Generate a request from a response.
|
|
*
|
|
* @param requestURI -- the request URI to assign to the request.
|
|
* @param via -- the Via header to assign to the request
|
|
* @param cseq -- the CSeq header to assign to the request
|
|
* @param from -- the From header to assign to the request
|
|
* @param to -- the To header to assign to the request
|
|
* @return -- the newly generated sip request.
|
|
*/
|
|
public SIPRequest createRequest(SipUri requestURI, Via via, CSeq cseq, From from, To to) {
|
|
SIPRequest newRequest = new SIPRequest();
|
|
String method = cseq.getMethod();
|
|
|
|
newRequest.setMethod(method);
|
|
newRequest.setRequestURI(requestURI);
|
|
this.setBranch( via, method );
|
|
newRequest.setHeader(via);
|
|
newRequest.setHeader(cseq);
|
|
Iterator headerIterator = getHeaders();
|
|
while (headerIterator.hasNext()) {
|
|
SIPHeader nextHeader = (SIPHeader) headerIterator.next();
|
|
// Some headers do not belong in a Request ....
|
|
if (SIPMessage.isResponseHeader(nextHeader)
|
|
|| nextHeader instanceof ViaList
|
|
|| nextHeader instanceof CSeq
|
|
|| nextHeader instanceof ContentType
|
|
|| nextHeader instanceof ContentLength
|
|
|| nextHeader instanceof RecordRouteList
|
|
|| nextHeader instanceof RequireList
|
|
|| nextHeader instanceof ContactList // JvB: added
|
|
|| nextHeader instanceof ContentLength
|
|
|| nextHeader instanceof ServerHeader
|
|
|| nextHeader instanceof ReasonHeader
|
|
|| nextHeader instanceof SessionExpires
|
|
|| nextHeader instanceof ReasonList) {
|
|
continue;
|
|
}
|
|
if (nextHeader instanceof To)
|
|
nextHeader = (SIPHeader) to;
|
|
else if (nextHeader instanceof From)
|
|
nextHeader = (SIPHeader) from;
|
|
try {
|
|
newRequest.attachHeader(nextHeader, false);
|
|
} catch (SIPDuplicateHeaderException e) {
|
|
//Should not happen!
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
try {
|
|
// JvB: all requests need a Max-Forwards
|
|
newRequest.attachHeader( new MaxForwards(70), false);
|
|
} catch (Exception d) {
|
|
|
|
}
|
|
|
|
if (MessageFactoryImpl.getDefaultUserAgentHeader() != null ) {
|
|
newRequest.setHeader(MessageFactoryImpl.getDefaultUserAgentHeader());
|
|
}
|
|
return newRequest;
|
|
|
|
}
|
|
}
|