Fields Summary |
---|
public static final String | ACKAcknowledgement request. |
public static final String | BYEEnd of session request. |
public static final String | CANCELTerminate session request. |
public static final String | INVITEInvitation request. |
public static final String | OPTIONSOptional settings request. |
public static final String | REGISTERRegsitration request. |
public static final String | NOTIFYNotification request. |
public static final String | SUBSCRIBESubscription for notification request. |
public static final String | MESSAGEMessage request. |
public static final String | REFERRedirection request. |
public static final String | INFOBasic information request. |
public static final String | PRACKPRACK ??? RFC. |
public static final String | UPDATEUpdate request. |
public static final String | PUBLISHPublish request. |
public static final String | DEFAULT_USERDefault user name is "ip". |
public static final int | DEFAULT_TTLDefault time to live is 1 second. |
public static final String | DEFAULT_TRANSPORTDefault transport is "udp". |
public static final String | DEFAULT_METHODDefault method is to intiate an INVITE. |
private Object | transactionPointerCurrent transaction pointer. |
protected RequestLine | requestLineCurrent requestline. |
Methods Summary |
---|
protected void | checkHeaders()Checks header for constraints.
(1) Invite options and bye requests can only have SIP URIs in the
contact headers.
(2) Request must have cseq, to and from and via headers.
(3) Method in request URI must match that in CSEQ.
String prefix = "Missing Header ";
/* Check for required headers */
if (getCSeqHeader() == null) {
throw new ParseException(prefix + Header.CSEQ, 0);
}
if (getTo() == null) {
throw new ParseException(prefix + Header.TO, 0);
}
if (getFromHeader() == null) {
throw new ParseException(prefix + Header.FROM, 0);
}
if (getViaHeaders() == null) {
throw new ParseException(prefix + Header.VIA, 0);
}
/*
* BUGBUG
* Need to revisit this check later...
* for now we just leave this to the
* application to catch.
*/
if (requestLine != null && requestLine.getMethod() != null &&
getCSeqHeader().getMethod() != null &&
compareToIgnoreCase
(requestLine.getMethod(), getCSeqHeader().getMethod()) != 0) {
throw
new ParseException
("CSEQ method mismatch with Request-Line ", 0);
}
|
public java.lang.Object | clone()Makes a clone (deep copy) of this object.
You can use this if you
want to modify a request while preserving the original
Request retval = (Request) super.clone();
if (this.requestLine != null) {
retval.requestLine = (RequestLine) this.requestLine.clone();
retval.setRequestLineDefaults();
}
return retval;
|
public gov.nist.siplite.message.Request | createACKRequest()Creates an ACK request from this request. This is suitable for
generating an ACK for an INVITE client transaction.
RequestLine rl = (RequestLine) requestLine.clone();
rl.setMethod(ACK);
return createRequest(rl, false);
|
public gov.nist.siplite.message.Request | createAckRequest(ToHeader responseToHeader)Creates a default ACK Request message for this original request.
Note that the defaultACK Request does not include the
content of the original Request. If responseToHeader
is null then the toHeader of this request is used to
construct the ACK. Note that tag fields are just copied
from the original SIP Request. Added by Jeff Keyser.
Request newRequest;
Enumeration headerIterator;
Header nextHeader;
newRequest = new Request();
newRequest.setRequestLine
((RequestLine)this.requestLine.clone());
newRequest.setMethod(ACK);
headerIterator = getHeaders();
while (headerIterator.hasMoreElements()) {
nextHeader = (Header)headerIterator.nextElement();
if (nextHeader.getHeaderName().equals
(Header.ROUTE)) {
// Route header for ACK is assigned by the
// Dialog if necessary.
continue;
} else if (nextHeader.getHeaderName().equals
(Header.PROXY_AUTHORIZATION)) {
// Remove proxy auth header.
// Assigned by the Dialog if necessary.
continue;
} else if (nextHeader instanceof ContentLengthHeader) {
// Adding content is responsibility of user.
nextHeader = (Header) nextHeader.clone();
((ContentLengthHeader)nextHeader).setContentLength(0);
} else if (nextHeader instanceof ContentTypeHeader) {
// Content type header is removed since
// content length is 0. Bug fix from
// Antonis Kyardas.
continue;
} else if (nextHeader instanceof CSeqHeader) {
CSeqHeader cseq = (CSeqHeader) nextHeader.clone();
cseq.setMethod(ACK);
nextHeader = cseq;
} else if (nextHeader instanceof ToHeader) {
if (responseToHeader != null) {
nextHeader = responseToHeader;
} else {
nextHeader = (Header) nextHeader.clone();
}
} else {
nextHeader = (Header) nextHeader.clone();
}
newRequest.attachHeader(nextHeader, false);
}
return newRequest;
|
public gov.nist.siplite.message.Request | createBYERequest(boolean switchHeaders)Creates a BYE request from this request.
RequestLine rl = (RequestLine) requestLine.clone();
rl.setMethod(BYE);
return createRequest(rl, switchHeaders);
|
public gov.nist.siplite.message.Request | createCancelRequest()Creates a default SIPResquest message that would cancel
this request. Note that tag assignment and removal of
is left to the caller (we use whatever tags are present in the
original request). Acknowledgement: Added by Jeff Keyser.
Request newRequest;
Enumeration headerIterator;
Header nextHeader;
newRequest = new Request();
// JSR180: Request-URI // copy from original request
RequestLine cancelRequestLine =
(RequestLine)this.getRequestLine().clone();
cancelRequestLine.setMethod(CANCEL);
newRequest.setRequestLine(cancelRequestLine);
newRequest.setMethod(CANCEL);
// JSR180: To // copy from original request
ToHeader toHeader = this.getTo();
if (toHeader != null) {
newRequest.setHeader(toHeader);
}
// JSR180: From // copy from original request
FromHeader fromHeader = this.getFromHeader();
if (fromHeader != null) {
newRequest.setHeader(fromHeader);
}
// JSR180: CSeq // same value for the sequence
// number as was present in the original request, but
// the method parameter MUST be equal to "CANCEL"
CSeqHeader cseqHeader = (CSeqHeader)this.getCSeqHeader().clone();
if (cseqHeader != null) {
cseqHeader.setMethod(CANCEL);
newRequest.setHeader(cseqHeader);
}
// JSR180: Call-ID // copy from original request
CallIdHeader callIdHeader = this.getCallId();
if (callIdHeader != null) {
newRequest.setHeader(callIdHeader);
}
// JSR180: Via // single value equal to the
// top Via header field of the request being cancelled
ViaHeader viaHeader = this.getTopmostVia();
if (viaHeader != null) {
newRequest.setHeader(viaHeader);
}
// JSR180: Route // If the request being cancelled
// contains a Route header field, the CANCEL request MUST
// include that Route header field's values
RouteList routeList = this.getRouteHeaders();
if (routeList != null) {
newRequest.setHeaders(routeList.getHeaders());
}
// JSR180: Max-Forwards (TBD)// header field serves to limit the
// number of hops a request can transit on the way to its destination.
// Current version: copy from original request
MaxForwardsHeader mfHeader =
(MaxForwardsHeader)getHeader(Header.MAX_FORWARDS);
if (mfHeader != null) {
newRequest.setHeader(mfHeader);
}
return newRequest;
|
public gov.nist.siplite.message.Request | createRequest(RequestLine requestLine, boolean switchHeaders)Creates a new default Request from the original request. Warning:
the newly created Request, shares the headers of
this request but we generate any new headers that we need to modify
so the original request is umodified. However, if you modify the
shared headers after this request is created, then the newly
created request will also be modified.
If you want to modify the original request
without affecting the returned Request
make sure you clone it before calling this method.
Following are the differences between the original request headers
and the generated request headers.
-
Contact headers are not included in the newly created request.
Setting the appropriate sequence number is the responsibility of
the caller.
- RouteList is not copied for ACK and CANCEL
- Note that we DO NOT copy the body of the
argument into the returned header. We do not copy the content
type header from the original request either. These have to be
added seperately and the content length has to be correctly set
if necessary the content length is set to 0 in the returned header.
- Contact List is not copied from the original request.
- RecordRoute List is not included from original request.
- Via header is not included from the original request.
Request newRequest = new Request();
newRequest.requestLine = requestLine;
Enumeration headerIterator = this.getHeaders();
while (headerIterator.hasMoreElements()) {
Header nextHeader =
(Header)headerIterator.nextElement();
// For BYE and cancel set the CSeqHeader header to the
// appropriate method.
if (nextHeader instanceof CSeqHeader) {
CSeqHeader newCseq = (CSeqHeader) nextHeader.clone();
nextHeader = newCseq;
newCseq.setMethod(requestLine.getMethod());
} else if (requestLine.getMethod().equals(ACK) &&
nextHeader instanceof ContactList) {
// ACKS never get Contact headers.
continue;
} else if (nextHeader instanceof ViaList) {
ViaHeader via = (ViaHeader)
(((ViaList)nextHeader).getFirst().clone());
via.removeParameter(SIPConstants.GENERAL_BRANCH);
nextHeader = via;
// Cancel and ACK preserve the branch ID.
} else if (nextHeader instanceof RouteList) {
continue; // Route is kept by dialog.
} else if (nextHeader instanceof RecordRouteList) {
continue; // RR is added by the caller.
} else if (nextHeader instanceof ContactList) {
continue;
} else if (nextHeader instanceof ToHeader) {
ToHeader to = (ToHeader) nextHeader;
if (switchHeaders) {
nextHeader = new FromHeader(to);
((FromHeader) nextHeader).removeTag();
} else {
nextHeader = (Header) to.clone();
((ToHeader) nextHeader).removeTag();
}
} else if (nextHeader instanceof FromHeader) {
FromHeader from = (FromHeader) nextHeader;
if (switchHeaders) {
nextHeader = new ToHeader(from);
((ToHeader) nextHeader).removeTag();
} else {
nextHeader = (Header) from.clone();
((FromHeader) nextHeader).removeTag();
}
} else if (nextHeader instanceof ContentLengthHeader) {
ContentLengthHeader cl =
(ContentLengthHeader)
nextHeader.clone();
cl.setContentLength(0);
nextHeader = cl;
} else if (nextHeader instanceof ContentTypeHeader) {
continue;
} else if (nextHeader instanceof MaxForwardsHeader) {
// Header is regenerated if the request is to be switched
if (switchHeaders) {
MaxForwardsHeader mf =
(MaxForwardsHeader)
nextHeader.clone();
mf.setMaxForwards(70);
nextHeader = mf;
}
} else if (!(nextHeader instanceof CallIdHeader) &&
!(nextHeader instanceof MaxForwardsHeader)) {
// Route is kept by dialog.
// RR is added by the caller.
// Contact is added by the Caller
// Any extension headers must be added
// by the caller.
continue;
}
newRequest.attachHeader(nextHeader, false);
}
return newRequest;
|
public Response | createResponse(int statusCode)Creates a default Response message for this request. Note
You must add the necessary tags to outgoing responses if need
be. For efficiency, this method does not clone the incoming
request. If you want to modify the outgoing response, be sure
to clone the incoming request as the headers are shared and
any modification to the headers of the outgoing response will
result in a modification of the incoming request.
Tag fields are just copied from the incoming request.
Contact headers are removed from the incoming request.
Added by Jeff Keyser.
String reasonPhrase = Response.getReasonPhrase(statusCode);
return createResponse(statusCode, reasonPhrase);
|
public Response | createResponse(int statusCode, java.lang.String reasonPhrase)Creates a default Response message for this request. Note
You must add the necessary tags to outgoing responses if need
be. For efficiency, this method does not clone the incoming
request. If you want to modify the outgoing response, be sure
to clone the incoming request as the headers are shared and
any modification to the headers of the outgoing response will
result in a modification of the incoming request.
Tag fields are just copied from the incoming request.
Contact headers are removed from the incoming request.
Added by Jeff Keyser. Route headers are not added to the
response.
Response newResponse;
Enumeration headerIterator;
Header nextHeader;
newResponse = new Response();
try {
newResponse.setStatusCode(statusCode);
} catch (ParseException ex) {
throw new IllegalArgumentException("Bad code " + statusCode);
}
if (reasonPhrase != null) {
newResponse.setReasonPhrase(reasonPhrase);
} else {
newResponse.setReasonPhrase(Response.getReasonPhrase(statusCode));
}
headerIterator = super.getHeaders();
// Time stamp header should be stamped with delay but
// we dont support this.
while (headerIterator.hasMoreElements()) {
nextHeader = (Header)headerIterator.nextElement();
if (nextHeader instanceof FromHeader ||
nextHeader instanceof ToHeader ||
nextHeader instanceof ViaList ||
nextHeader instanceof CallIdHeader ||
nextHeader instanceof RecordRouteList ||
nextHeader instanceof CSeqHeader ||
// RFC 3265, 3.1.1 200-class responses to SUBSCRIBE
// requests also MUST contain an "Expires" header.
nextHeader instanceof ExpiresHeader ||
Utils.equalsIgnoreCase(nextHeader.getName(),
Header.TIMESTAMP)) {
try {
newResponse.attachHeader(nextHeader, false);
} catch (SipException ex) {
if (Logging.REPORT_LEVEL <= Logging.ERROR) {
Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
"Request.createResponse(): can't attach header '" +
nextHeader.getHeaderName() + "'.");
ex.printStackTrace();
}
}
} else if (Utils.equalsIgnoreCase(nextHeader.getName(),
Header.REQUIRE)) {
/*
* RFC3262, SECTION 3
* If the next header contains "Require" header with option
* tag as "100rel", we should add this header and also include
* RSeq header field
*/
boolean isReliableProvResponse = Header.isReliableTagPresent(
nextHeader.getHeaderValue());
if (isReliableProvResponse) {
try {
newResponse.attachHeader(nextHeader, true);
} catch (SipException ex) {
if (Logging.REPORT_LEVEL <= Logging.ERROR) {
Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
"Request.createResponse(): can't attach header"
+ nextHeader.getHeaderName() + "'.");
// ex.printStackTrace();
}
}
}
}
}
// RFC 3903, p. 5:
// The Record-Route header field has no meaning in PUBLISH
// requests or responses, and MUST be ignored if present.
//
// RFC 3261, p. 63:
// Registrars MUST ignore the Record-Route header field if it is
// included in a REGISTER request. Registrars MUST NOT include a
// Record-Route header field in any response to a REGISTER request.
String method = getMethod();
if (method.equals(Request.PUBLISH) ||
method.equals(Request.REGISTER)) {
newResponse.removeHeader(Header.RECORD_ROUTE);
}
return newResponse;
|
public java.lang.String | encode()Encodes the SIP Request as a string.
String retval;
if (requestLine != null) {
this.setRequestLineDefaults();
retval = requestLine.encode() + super.encode();
} else
retval = super.encode();
return retval;
|
public byte[] | encodeAsBytes()Encodes 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.
byte[] rlbytes = null;
if (requestLine != null) {
try {
rlbytes = requestLine.encode().getBytes("UTF-8");
} catch (UnsupportedEncodingException ex) {
InternalErrorHandler.handleException(ex);
}
}
byte[] superbytes = super.encodeAsBytes();
byte[] retval = new byte[rlbytes.length + superbytes.length];
int i = 0;
System.arraycopy(rlbytes, 0, retval, 0, rlbytes.length);
System.arraycopy
(superbytes, 0, retval, rlbytes.length, superbytes.length);
return retval;
|
public boolean | equals(java.lang.Object other)Compares for equality.
if (! this.getClass().equals(other.getClass()))
return false;
Request that = (Request) other;
boolean retval = requestLine.equals(that.requestLine) &&
super.equals(other);
if (Logging.REPORT_LEVEL <= Logging.INFORMATION && !retval) {
Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
"this ... >>>>" + encode());
Logging.report(Logging.INFORMATION, LogChannels.LC_JSR180,
"other ... >>>>" + that.encode());
}
return retval;
|
public AcceptContactHeader | getAcceptContact()Gets the Accept-Contact header (null if one does not exist).
return (AcceptContactHeader) getHeader(Header.ACCEPT_CONTACT);
|
public java.lang.String | getFirstLine()Gets the first line encoded.
if (requestLine == null)
return null;
else
return this.requestLine.encode();
|
public java.lang.String | getMethod()Gets the method from the request line.
if (requestLine == null)
return null;
else
return requestLine.getMethod();
|
public RequestLine | getRequestLine()Gets the Request Line of the Request.
return requestLine;
|
public URI | getRequestURI()A conveniance function to access the Request URI.
if (this.requestLine == null)
return null;
else
return this.requestLine.getUri();
|
public java.lang.String | getSIPVersion()Gets the SIP version.
return this.requestLine.getSipVersion();
|
public java.lang.Object | getTransaction()Gets the transaction pointer.
// Return an opaque pointer to the transaction object.
// This is for consistency checking and quick lookup.
return this.transactionPointer;
|
public java.lang.String | getViaHost()Gets the host from the topmost via header.
ViaHeader via = (ViaHeader) this.getViaHeaders().getFirst();
return via.getHost();
|
public int | getViaPort()Gets the port from the topmost via header.
ViaHeader via = (ViaHeader) this.getViaHeaders().getFirst();
if (via.hasPort())
return via.getPort();
else
return 5060;
|
protected void | setDefaults()Sets the default values in the request URI if necessary.
// The request line may be unparseable (set to null by the
// exception handler.
if (requestLine == null)
return;
String method = requestLine.getMethod();
// The requestLine may be malformed!
if (method == null)
return;
URI u = requestLine.getUri();
if (u == null)
return;
if (method.compareTo(REGISTER) == 0
|| method.compareTo(INVITE) == 0) {
if (u instanceof SipURI) {
SipURI sipUri = (SipURI) u;
sipUri.setUserParam(DEFAULT_USER);
try {
sipUri.setTransportParam(DEFAULT_TRANSPORT);
} catch (ParseException ex) {}
}
}
|
public void | setMethod(java.lang.String method)Sets the method.
if (method == null)
throw new IllegalArgumentException("null method");
if (this.requestLine == null) {
this.requestLine = new RequestLine();
}
this.requestLine.setMethod(method);
if (this.cSeqHeader != null) {
this.cSeqHeader.setMethod(method);
}
|
public void | setRequestLine(RequestLine requestLine)Sets the request line of the SIP Request.
this.requestLine = requestLine;
|
protected void | setRequestLineDefaults()Patch up the request line as necessary.
String method = requestLine.getMethod();
if (method == null) {
CSeqHeader cseq = (CSeqHeader) this.getCSeqHeader();
if (cseq != null) {
method = cseq.getMethod();
requestLine.setMethod(method);
}
}
|
public void | setRequestURI(URI uri)Sets the RequestURI of Request. The Request-URI is a SIP or
SIPS URI or a general URI. It indicates the user or service to which
this request is being addressed. SIP elements MAY support
Request-URIs with schemes other than "sip" and "sips", for
example the "tel" URI scheme. SIP elements MAY translate
non-SIP URIs using any mechanism at their disposal, resulting
in SIP URI, SIPS URI, or some other scheme.
if (this.requestLine == null) {
this.requestLine = new RequestLine();
}
this.requestLine.setUri((URI)uri);
|
public void | setSIPVersion(java.lang.String sipVersion)Sets the sip version.
if (sipVersion == null || !sipVersion.equals("SIP/2.0"))
throw new ParseException("sipVersion", 0);
this.requestLine.setSIPVersion(sipVersion);
|
public void | setTransaction(java.lang.Object transaction)Sets the transaction pointer.
this.transactionPointer = transaction;
|
public java.lang.String | toString()Alias for encode above. return this.encode();
|