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.model.profile;
17  
18  import org.fourthline.cling.model.message.Connection;
19  import org.fourthline.cling.model.message.StreamRequestMessage;
20  import org.fourthline.cling.model.message.UpnpHeaders;
21  import org.fourthline.cling.model.message.header.UpnpHeader;
22  import org.fourthline.cling.model.message.header.UserAgentHeader;
23  import org.seamless.http.RequestInfo;
24  
25  import java.net.InetAddress;
26  
27  /**
28   * Encapsulates information about a remote control point, the client.
29   *
30   * <p>
31   * The {@link #getExtraResponseHeaders()} method offers modifiable HTTP headers which will
32   * be added to the responses and returned to the client.
33   * </p>
34   *
35   * @author Christian Bauer
36   */
37  public class RemoteClientInfo extends ClientInfo {
38  
39      final protected Connection connection;
40      final protected UpnpHeaders extraResponseHeaders = new UpnpHeaders();
41  
42      public RemoteClientInfo() {
43          this(null);
44      }
45  
46      public RemoteClientInfo(StreamRequestMessage requestMessage) {
47          this(requestMessage != null ? requestMessage.getConnection() : null,
48              requestMessage != null ? requestMessage.getHeaders() : new UpnpHeaders());
49      }
50  
51      public RemoteClientInfo(Connection connection, UpnpHeaders requestHeaders) {
52          super(requestHeaders);
53          this.connection = connection;
54      }
55  
56      public Connection getConnection() {
57          return connection;
58      }
59  
60      /**
61       * <p>
62       * Check if the remote client's connection is still open.
63       * </p>
64       * <p>
65       * How connection checking is actually performed is transport-implementation dependent. Usually,
66       * the {@link org.fourthline.cling.transport.spi.StreamServer} will send meaningless heartbeat
67       * data to the client on its (open) socket. If that fails, the client's connection has been
68       * closed. Note that some HTTP clients can <em>NOT</em> handle such garbage data in HTTP
69       * responses, hence calling this method might cause compatibility issues.
70       * </p>
71       * @return <code>true</code> if the remote client's connection was closed.
72       */
73      public boolean isRequestCancelled() {
74          return !getConnection().isOpen();
75      }
76  
77      /**
78       * @throws InterruptedException if {@link #isRequestCancelled()} returns <code>true</code>.
79       */
80      public void throwIfRequestCancelled() throws InterruptedException{
81          if(isRequestCancelled())
82               throw new InterruptedException("Client's request cancelled");
83      }
84  
85      public InetAddress getRemoteAddress() {
86          return getConnection().getRemoteAddress();
87      }
88  
89      public InetAddress getLocalAddress() {
90          return getConnection().getLocalAddress();
91      }
92  
93      public UpnpHeaders getExtraResponseHeaders() {
94          return extraResponseHeaders;
95      }
96  
97      public void setResponseUserAgent(String userAgent) {
98          setResponseUserAgent(new UserAgentHeader(userAgent));
99      }
100 
101     public void setResponseUserAgent(UserAgentHeader userAgentHeader) {
102         getExtraResponseHeaders().add(
103             UpnpHeader.Type.USER_AGENT,
104             userAgentHeader
105         );
106     }
107 
108     // TODO: Remove this once we know how ClientProfile will look like
109     public boolean isWMPRequest() {
110         return RequestInfo.isWMPRequest(getRequestUserAgent());
111     }
112 
113     public boolean isXbox360Request() {
114         return RequestInfo.isXbox360Request(
115             getRequestUserAgent(),
116             getRequestHeaders().getFirstHeaderString(UpnpHeader.Type.SERVER)
117         );
118     }
119 
120     public boolean isPS3Request() {
121     	return RequestInfo.isPS3Request(
122             getRequestUserAgent(),
123             getRequestHeaders().getFirstHeaderString(UpnpHeader.Type.EXT_AV_CLIENT_INFO)
124         );
125     }
126 
127     @Override
128     public String toString() {
129         return "(" + getClass().getSimpleName() + ") Remote Address: " + getRemoteAddress();
130     }
131 }