View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   */
15  
16  package org.fourthline.cling.test.model;
17  
18  import org.fourthline.cling.model.Constants;
19  import org.fourthline.cling.model.Location;
20  import org.fourthline.cling.model.NetworkAddress;
21  import org.fourthline.cling.model.types.NotificationSubtype;
22  import org.fourthline.cling.model.message.header.HostHeader;
23  import org.fourthline.cling.model.message.header.MaxAgeHeader;
24  import org.fourthline.cling.model.message.header.USNRootDeviceHeader;
25  import org.fourthline.cling.model.message.header.UpnpHeader;
26  import org.fourthline.cling.model.message.header.ServerHeader;
27  import org.fourthline.cling.model.message.header.EXTHeader;
28  import org.fourthline.cling.model.message.header.InterfaceMacHeader;
29  import org.fourthline.cling.model.message.UpnpMessage;
30  import org.fourthline.cling.model.message.UpnpRequest;
31  import org.fourthline.cling.model.message.OutgoingDatagramMessage;
32  import org.fourthline.cling.model.message.discovery.OutgoingNotificationRequestRootDevice;
33  import org.fourthline.cling.test.data.SampleData;
34  import org.fourthline.cling.test.data.SampleDeviceRoot;
35  import org.fourthline.cling.transport.spi.DatagramProcessor;
36  import org.fourthline.cling.transport.impl.NetworkAddressFactoryImpl;
37  import org.fourthline.cling.DefaultUpnpServiceConfiguration;
38  import org.seamless.util.io.HexBin;
39  import org.testng.Assert;
40  import org.testng.annotations.Test;
41  
42  import java.net.DatagramPacket;
43  import java.net.InetAddress;
44  import java.net.InetSocketAddress;
45  
46  import static org.testng.Assert.*;
47  
48  
49  public class DatagramParsingTest {
50  
51      @Test
52      public void readSource() throws Exception {
53  
54          String source = "NOTIFY * HTTP/1.1\r\n" +
55                          "HOST: 239.255.255.250:1900\r\n" +
56                          "CACHE-CONTROL: max-age=2000\r\n" +
57                          "LOCATION: http://localhost:0/some/path/123/desc.xml\r\n" +
58                          "X-CLING-IFACE-MAC: 00:17:ab:e9:65:a0\r\n" +
59                          "NT: upnp:rootdevice\r\n" +
60                          "NTS: ssdp:alive\r\n" +
61                          "EXT:\r\n" +
62                          "SERVER: foo/1 UPnP/1.0" + // FOLDED HEADER LINE!
63                          " bar/2\r\n" +
64                          "USN: " + SampleDeviceRoot.getRootUDN().toString()+"::upnp:rootdevice\r\n\r\n";
65  
66          DatagramPacket packet = new DatagramPacket(source.getBytes(), source.getBytes().length, new InetSocketAddress("123.123.123.123", 1234));
67  
68          DatagramProcessor processor = new DefaultUpnpServiceConfiguration().getDatagramProcessor();
69  
70          UpnpMessage<UpnpRequest> msg = processor.read(InetAddress.getByName("127.0.0.1"), packet);
71  
72          assertEquals(msg.getOperation().getMethod(), UpnpRequest.Method.NOTIFY);
73  
74          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.HOST, HostHeader.class).getValue().getHost(), Constants.IPV4_UPNP_MULTICAST_GROUP);
75          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.HOST, HostHeader.class).getValue().getPort(), Constants.UPNP_MULTICAST_PORT);
76          assertEquals(
77              msg.getHeaders().getFirstHeader(UpnpHeader.Type.USN, USNRootDeviceHeader.class).getValue().getIdentifierString(),
78              SampleDeviceRoot.getRootUDN().getIdentifierString()
79          );
80          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.MAX_AGE, MaxAgeHeader.class).getValue().toString(), "2000");
81          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER, ServerHeader.class).getValue().getOsName(), "foo");
82          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER, ServerHeader.class).getValue().getOsVersion(), "1");
83          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER, ServerHeader.class).getValue().getMajorVersion(), 1);
84          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER, ServerHeader.class).getValue().getMinorVersion(), 0);
85          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER, ServerHeader.class).getValue().getProductName(), "bar");
86          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER, ServerHeader.class).getValue().getProductVersion(), "2");
87  
88          // Doesn't belong in this message but we need to test empty header values
89          assert msg.getHeaders().getFirstHeader(UpnpHeader.Type.EXT) != null;
90  
91          assertEquals(msg.getHeaders().getFirstHeader(UpnpHeader.Type.EXT_IFACE_MAC, InterfaceMacHeader.class).getString(), "00:17:AB:E9:65:A0");
92  
93      }
94  
95      @Test
96      public void parseRoundtrip() throws Exception {
97          Location location = new Location(
98                  new NetworkAddress(
99                          InetAddress.getByName("localhost"),
100                         NetworkAddressFactoryImpl.DEFAULT_TCP_HTTP_LISTEN_PORT,
101                         HexBin.stringToBytes("00:17:AB:E9:65:A0", ":")
102                 ),
103                 "/some/path/123/desc/xml"
104         );
105 
106         OutgoingDatagramMessage msg =
107                 new OutgoingNotificationRequestRootDevice(
108                         location,
109                         SampleData.createLocalDevice(),
110                         NotificationSubtype.ALIVE
111                 );
112 
113         msg.getHeaders().add(UpnpHeader.Type.EXT, new EXTHeader()); // Again, the empty header value
114 
115         DatagramProcessor processor = new DefaultUpnpServiceConfiguration().getDatagramProcessor();
116 
117         DatagramPacket packet = processor.write(msg);
118 
119         Assert.assertTrue(new String(packet.getData()).endsWith("\r\n\r\n"));
120 
121         UpnpMessage readMsg = processor.read(InetAddress.getByName("127.0.0.1"), packet);
122 
123         assertEquals(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.HOST).getString(), msg.getHeaders().getFirstHeader(UpnpHeader.Type.HOST).getString());
124         assertEquals(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.MAX_AGE).getString(), msg.getHeaders().getFirstHeader(UpnpHeader.Type.MAX_AGE).getString());
125         assertEquals(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.LOCATION).getString(), msg.getHeaders().getFirstHeader(UpnpHeader.Type.LOCATION).getString());
126         assertEquals(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.NT).getString(), msg.getHeaders().getFirstHeader(UpnpHeader.Type.NT).getString());
127         assertEquals(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.NTS).getString(), msg.getHeaders().getFirstHeader(UpnpHeader.Type.NTS).getString());
128         assertEquals(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER).getString(), msg.getHeaders().getFirstHeader(UpnpHeader.Type.SERVER).getString());
129         assertEquals(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.USN).getString(), msg.getHeaders().getFirstHeader(UpnpHeader.Type.USN).getString());
130         assertNotNull(readMsg.getHeaders().getFirstHeader(UpnpHeader.Type.EXT));
131     }
132 
133 }