001: package test.unit.gov.nist.javax.sip.stack;
002:
003: import gov.nist.javax.sip.message.MessageFactoryImpl;
004:
005: import java.text.ParseException;
006: import java.util.ArrayList;
007: import java.util.Properties;
008:
009: import javax.security.sasl.SaslException;
010: import javax.sip.ClientTransaction;
011: import javax.sip.Dialog;
012: import javax.sip.DialogTerminatedEvent;
013: import javax.sip.IOExceptionEvent;
014: import javax.sip.ListeningPoint;
015: import javax.sip.PeerUnavailableException;
016: import javax.sip.RequestEvent;
017: import javax.sip.ResponseEvent;
018: import javax.sip.ServerTransaction;
019: import javax.sip.SipFactory;
020: import javax.sip.SipListener;
021: import javax.sip.SipProvider;
022: import javax.sip.SipStack;
023: import javax.sip.Transaction;
024: import javax.sip.TransactionTerminatedEvent;
025: import javax.sip.address.Address;
026: import javax.sip.address.AddressFactory;
027: import javax.sip.address.SipURI;
028: import javax.sip.header.CSeqHeader;
029: import javax.sip.header.CallIdHeader;
030: import javax.sip.header.ContactHeader;
031: import javax.sip.header.ContentTypeHeader;
032: import javax.sip.header.FromHeader;
033: import javax.sip.header.Header;
034: import javax.sip.header.HeaderFactory;
035: import javax.sip.header.MaxForwardsHeader;
036: import javax.sip.header.ToHeader;
037: import javax.sip.header.ViaHeader;
038: import javax.sip.message.MessageFactory;
039: import javax.sip.message.Request;
040: import javax.sip.message.Response;
041:
042: import junit.framework.TestCase;
043:
044: public class DeliverRequestEventWithBadHeaderTest extends TestCase {
045: public class Shootme implements SipListener {
046:
047: private AddressFactory addressFactory;
048:
049: private MessageFactory messageFactory;
050:
051: private HeaderFactory headerFactory;
052:
053: private SipStack sipStack;
054:
055: private static final String myAddress = "127.0.0.1";
056:
057: private static final int myPort = 5070;
058:
059: private Dialog dialog;
060:
061: private boolean sawInvite;
062:
063: public static final boolean callerSendsBye = true;
064:
065: public void processRequest(RequestEvent requestEvent) {
066: Request request = requestEvent.getRequest();
067: ServerTransaction serverTransactionId = requestEvent
068: .getServerTransaction();
069:
070: System.out.println("\n\nRequest " + request.getMethod()
071: + " received at " + sipStack.getStackName()
072: + " with server transaction id "
073: + serverTransactionId);
074:
075: if (request.getMethod().equals(Request.INVITE)) {
076: processInvite(requestEvent, serverTransactionId);
077: }
078:
079: }
080:
081: public void processResponse(ResponseEvent responseEvent) {
082: }
083:
084: /**
085: * Process the ACK request. Send the bye and complete the call flow.
086: */
087: public void processAck(RequestEvent requestEvent,
088: ServerTransaction serverTransaction) {
089: try {
090: System.out.println("shootme: got an ACK! ");
091: System.out.println("Dialog State = "
092: + dialog.getState());
093: SipProvider provider = (SipProvider) requestEvent
094: .getSource();
095: if (!callerSendsBye) {
096: Request byeRequest = dialog
097: .createRequest(Request.BYE);
098: ClientTransaction ct = provider
099: .getNewClientTransaction(byeRequest);
100: dialog.sendRequest(ct);
101: }
102: } catch (Exception ex) {
103: ex.printStackTrace();
104: }
105:
106: }
107:
108: /**
109: * Process the invite request.
110: */
111: public void processInvite(RequestEvent requestEvent,
112: ServerTransaction serverTransaction) {
113: SipProvider sipProvider = (SipProvider) requestEvent
114: .getSource();
115: Request request = requestEvent.getRequest();
116: this .sawInvite = true;
117: try {
118:
119: Response okResponse = messageFactory.createResponse(
120: Response.OK, request);
121: Address address = addressFactory
122: .createAddress("Shootme <sip:" + myAddress
123: + ":" + myPort + ">");
124: ContactHeader contactHeader = headerFactory
125: .createContactHeader(address);
126: ToHeader toHeader = (ToHeader) okResponse
127: .getHeader(ToHeader.NAME);
128: toHeader.setTag("4321"); // Application is supposed to set.
129: okResponse.addHeader(contactHeader);
130: sipProvider.sendResponse(okResponse); // Send it through the
131: // Provider.
132:
133: } catch (Exception ex) {
134: ex.printStackTrace();
135: System.exit(0);
136: }
137: }
138:
139: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
140: Transaction transaction;
141: if (timeoutEvent.isServerTransaction()) {
142: transaction = timeoutEvent.getServerTransaction();
143: } else {
144: transaction = timeoutEvent.getClientTransaction();
145: }
146: System.out.println("state = " + transaction.getState());
147: System.out.println("dialog = " + transaction.getDialog());
148: System.out.println("dialogState = "
149: + transaction.getDialog().getState());
150: System.out.println("Transaction Time out");
151: }
152:
153: public void init() {
154: SipFactory sipFactory = null;
155: sipStack = null;
156: sipFactory = SipFactory.getInstance();
157: sipFactory.setPathName("gov.nist");
158: Properties properties = new Properties();
159: properties.setProperty("javax.sip.STACK_NAME", "shootme");
160: // You need 16 for logging traces. 32 for debug + traces.
161: // Your code will limp at 32 but it is best for debugging.
162: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
163: "32");
164: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
165: "shootmedebug.txt");
166: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
167: "shootmelog.txt");
168:
169: try {
170: // Create SipStack object
171: sipStack = sipFactory.createSipStack(properties);
172: System.out.println("sipStack = " + sipStack);
173: } catch (PeerUnavailableException e) {
174: // could not find
175: // gov.nist.jain.protocol.ip.sip.SipStackImpl
176: // in the classpath
177: e.printStackTrace();
178: System.err.println(e.getMessage());
179: if (e.getCause() != null)
180: e.getCause().printStackTrace();
181: System.exit(0);
182: }
183:
184: try {
185: headerFactory = sipFactory.createHeaderFactory();
186: addressFactory = sipFactory.createAddressFactory();
187: messageFactory = sipFactory.createMessageFactory();
188: ((MessageFactoryImpl) messageFactory).setTest(true);
189: ListeningPoint lp = sipStack.createListeningPoint(
190: "127.0.0.1", myPort, "udp");
191:
192: Shootme listener = this ;
193:
194: SipProvider sipProvider = sipStack
195: .createSipProvider(lp);
196: System.out.println("udp provider " + sipProvider);
197: sipProvider.addSipListener(listener);
198:
199: } catch (Exception ex) {
200: ex.printStackTrace();
201: fail("Unexpected exception");
202: }
203:
204: }
205:
206: public void processIOException(IOExceptionEvent exceptionEvent) {
207: fail("IOException");
208:
209: }
210:
211: public void processTransactionTerminated(
212: TransactionTerminatedEvent transactionTerminatedEvent) {
213: if (transactionTerminatedEvent.isServerTransaction())
214: System.out
215: .println("Transaction terminated event recieved"
216: + transactionTerminatedEvent
217: .getServerTransaction());
218: else
219: System.out.println("Transaction terminated "
220: + transactionTerminatedEvent
221: .getClientTransaction());
222:
223: }
224:
225: public void processDialogTerminated(
226: DialogTerminatedEvent dialogTerminatedEvent) {
227: Dialog d = dialogTerminatedEvent.getDialog();
228: System.out.println("Local Party = " + d.getLocalParty());
229:
230: }
231:
232: public void terminate() {
233: this .sipStack.stop();
234: }
235:
236: }
237:
238: public class Shootist implements SipListener {
239:
240: private SipProvider sipProvider;
241:
242: private AddressFactory addressFactory;
243:
244: private MessageFactory messageFactory;
245:
246: private HeaderFactory headerFactory;
247:
248: private SipStack sipStack;
249:
250: private ContactHeader contactHeader;
251:
252: private ListeningPoint udpListeningPoint;
253:
254: private Dialog dialog;
255:
256: private boolean timeoutRecieved;
257:
258: boolean sawOk;
259:
260: public void processRequest(RequestEvent requestReceivedEvent) {
261:
262: }
263:
264: public void processResponse(ResponseEvent responseReceivedEvent) {
265: try {
266: if (responseReceivedEvent.getResponse().getStatusCode() == Response.OK) {
267: this .sawOk = true;
268: Dialog dialog = responseReceivedEvent.getDialog();
269: long cseq = ((CSeqHeader) responseReceivedEvent
270: .getResponse().getHeader(CSeqHeader.NAME))
271: .getSeqNumber();
272: Request ack = dialog.createAck(cseq);
273: dialog.sendAck(ack);
274: }
275: } catch (Exception ex) {
276: fail("Unexpected exception");
277:
278: }
279:
280: }
281:
282: public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
283:
284: System.out.println("Got a timeout "
285: + timeoutEvent.getClientTransaction());
286:
287: this .timeoutRecieved = true;
288: }
289:
290: public void init() {
291: SipFactory sipFactory = null;
292: sipStack = null;
293: sipFactory = SipFactory.getInstance();
294: sipFactory.setPathName("gov.nist");
295: Properties properties = new Properties();
296: // If you want to try TCP transport change the following to
297: String transport = "udp";
298: String peerHostPort = "127.0.0.1:5070";
299: properties.setProperty("javax.sip.OUTBOUND_PROXY",
300: peerHostPort + "/" + transport);
301: // If you want to use UDP then uncomment this.
302: properties.setProperty("javax.sip.STACK_NAME", "shootist");
303:
304: // The following properties are specific to nist-sip
305: // and are not necessarily part of any other jain-sip
306: // implementation.
307: // You can set a max message size for tcp transport to
308: // guard against denial of service attack.
309: properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
310: "shootistdebug.txt");
311: properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
312: "shootistlog.txt");
313:
314: // Drop the client connection after we are done with the
315: // transaction.
316: properties.setProperty(
317: "gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS",
318: "false");
319: // Set to 0 (or NONE) in your production code for max speed.
320: // You need 16 (or TRACE) for logging traces. 32 (or DEBUG) for
321: // debug + traces.
322: // Your code will limp at 32 but it is best for debugging.
323: properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL",
324: "DEBUG");
325:
326: try {
327: // Create SipStack object
328: sipStack = sipFactory.createSipStack(properties);
329: System.out.println("createSipStack " + sipStack);
330: } catch (PeerUnavailableException e) {
331: // could not find
332: // gov.nist.jain.protocol.ip.sip.SipStackImpl
333: // in the classpath
334: e.printStackTrace();
335: System.err.println(e.getMessage());
336: fail("Problem with setup");
337: }
338:
339: try {
340: headerFactory = sipFactory.createHeaderFactory();
341: addressFactory = sipFactory.createAddressFactory();
342: messageFactory = sipFactory.createMessageFactory();
343: udpListeningPoint = sipStack.createListeningPoint(
344: "127.0.0.1", 5060, "udp");
345: sipProvider = sipStack
346: .createSipProvider(udpListeningPoint);
347: Shootist listener = this ;
348: sipProvider.addSipListener(listener);
349:
350: String badRequest = "INVITE sip:LittleGuy@127.0.0.1:5070 SIP/2.0\r\n"
351: + "Call-ID: 7a3cd620346e3fa199cb397fe6b6fc16@127.0.0.1\r\n"
352: + "CSeq: 1 INVITE\r\n"
353: + "From: \"The Master Blaster\" <sip:BigGuy@here.com>;tag=12345\r\n"
354: + "To: \"The Little Blister\" <sip:LittleGuy@there.com>\r\n"
355: + "Via: SIP/2.0/UDP 127.0.0.1:5060\r\n"
356: + "Max-Forwards: 70\r\n"
357: + "Date: 123 GMT 789\r\n"
358: + "Contact: <127.0.0.1:5060>\r\n"
359: + "Content-Length: 0\r\n\r\n";
360:
361: System.out.println("Parsing message \n" + badRequest);
362: boolean sawParseException = false;
363: Request request = null;
364: try {
365: request = messageFactory.createRequest(badRequest);
366: } catch (ParseException ex) {
367: sawParseException = true;
368: }
369:
370: assertTrue("Should not see a parse exception ",
371: !sawParseException);
372:
373: assertTrue("Should see unparsed headder", request
374: .getUnrecognizedHeaders().hasNext()
375: && ((String) request.getUnrecognizedHeaders()
376: .next()).equals("Date: 123 GMT 789"));
377:
378: ClientTransaction inviteTid = sipProvider
379: .getNewClientTransaction(request);
380:
381: // send the request out.
382: inviteTid.sendRequest();
383:
384: dialog = inviteTid.getDialog();
385:
386: } catch (Exception ex) {
387: ex.printStackTrace();
388: fail("cannot create or send initial invite");
389: }
390: }
391:
392: public void processIOException(IOExceptionEvent exceptionEvent) {
393: System.out.println("IOException happened for "
394: + exceptionEvent.getHost() + " port = "
395: + exceptionEvent.getPort());
396:
397: }
398:
399: public void processTransactionTerminated(
400: TransactionTerminatedEvent transactionTerminatedEvent) {
401: System.out.println("Transaction terminated event recieved");
402: }
403:
404: public void processDialogTerminated(
405: DialogTerminatedEvent dialogTerminatedEvent) {
406: System.out.println("dialogTerminatedEvent");
407:
408: }
409:
410: public void terminate() {
411: this .sipStack.stop();
412: }
413: }
414:
415: private Shootme shootme;
416: private Shootist shootist;
417:
418: public void setUp() {
419: this .shootme = new Shootme();
420: this .shootist = new Shootist();
421:
422: }
423:
424: public void tearDown() {
425: shootist.terminate();
426: shootme.terminate();
427: }
428:
429: public void testSendInviteWithBadHeader() {
430: this .shootme.init();
431: this .shootist.init();
432: try {
433: Thread.sleep(5000);
434: } catch (Exception ex) {
435:
436: }
437: assertTrue("Should see reuqest at shootme ", shootme.sawInvite);
438: assertTrue("Should see response at shootist", shootist.sawOk);
439: }
440:
441: }
|