1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.transport.impl;
17
18 import java.util.logging.Logger;
19 import java.util.logging.Level;
20
21 import org.fourthline.cling.model.message.IncomingDatagramMessage;
22 import org.fourthline.cling.model.message.OutgoingDatagramMessage;
23 import org.fourthline.cling.model.message.UpnpHeaders;
24 import org.fourthline.cling.model.message.UpnpOperation;
25 import org.fourthline.cling.model.message.UpnpRequest;
26 import org.fourthline.cling.model.message.UpnpResponse;
27 import org.fourthline.cling.transport.spi.DatagramProcessor;
28 import org.fourthline.cling.model.UnsupportedDataException;
29 import org.seamless.http.Headers;
30
31 import java.io.ByteArrayInputStream;
32 import java.io.UnsupportedEncodingException;
33 import java.net.DatagramPacket;
34 import java.net.InetAddress;
35 import java.util.Locale;
36
37
38
39
40
41
42 public class DatagramProcessorImpl implements DatagramProcessor {
43
44 private static Logger log = Logger.getLogger(DatagramProcessor.class.getName());
45
46 public IncomingDatagramMessage read(InetAddress receivedOnAddress, DatagramPacket datagram) throws UnsupportedDataException {
47
48 try {
49
50 if (log.isLoggable(Level.FINER)) {
51 log.finer("===================================== DATAGRAM BEGIN ============================================");
52 log.finer(new String(datagram.getData(), "UTF-8"));
53 log.finer("-===================================== DATAGRAM END =============================================");
54 }
55
56 ByteArrayInputStream is = new ByteArrayInputStream(datagram.getData());
57
58 String[] startLine = Headers.readLine(is).split(" ");
59 if (startLine[0].startsWith("HTTP/1.")) {
60 return readResponseMessage(receivedOnAddress, datagram, is, Integer.valueOf(startLine[1]), startLine[2], startLine[0]);
61 } else {
62 return readRequestMessage(receivedOnAddress, datagram, is, startLine[0], startLine[2]);
63 }
64
65 } catch (Exception ex) {
66 throw new UnsupportedDataException("Could not parse headers: " + ex, ex, datagram.getData());
67 }
68 }
69
70 public DatagramPacket write(OutgoingDatagramMessage message) throws UnsupportedDataException {
71
72 StringBuilder statusLine = new StringBuilder();
73
74 UpnpOperation operation = message.getOperation();
75
76 if (operation instanceof UpnpRequest) {
77
78 UpnpRequest requestOperation = (UpnpRequest) operation;
79 statusLine.append(requestOperation.getHttpMethodName()).append(" * ");
80 statusLine.append("HTTP/1.").append(operation.getHttpMinorVersion()).append("\r\n");
81
82 } else if (operation instanceof UpnpResponse) {
83 UpnpResponse responseOperation = (UpnpResponse) operation;
84 statusLine.append("HTTP/1.").append(operation.getHttpMinorVersion()).append(" ");
85 statusLine.append(responseOperation.getStatusCode()).append(" ").append(responseOperation.getStatusMessage());
86 statusLine.append("\r\n");
87 } else {
88 throw new UnsupportedDataException(
89 "Message operation is not request or response, don't know how to process: " + message
90 );
91 }
92
93
94 StringBuilder messageData = new StringBuilder();
95 messageData.append(statusLine);
96
97 messageData.append(message.getHeaders().toString()).append("\r\n");
98
99 if (log.isLoggable(Level.FINER)) {
100 log.finer("Writing message data for: " + message);
101 log.finer("---------------------------------------------------------------------------------");
102 log.finer(messageData.toString().substring(0, messageData.length() - 2));
103 log.finer("---------------------------------------------------------------------------------");
104 }
105
106 try {
107
108
109 byte[] data = messageData.toString().getBytes("US-ASCII");
110
111 log.fine("Writing new datagram packet with " + data.length + " bytes for: " + message);
112 return new DatagramPacket(data, data.length, message.getDestinationAddress(), message.getDestinationPort());
113
114 } catch (UnsupportedEncodingException ex) {
115 throw new UnsupportedDataException(
116 "Can't convert message content to US-ASCII: " + ex.getMessage(), ex, messageData
117 );
118 }
119 }
120
121 protected IncomingDatagramMessage readRequestMessage(InetAddress receivedOnAddress,
122 DatagramPacket datagram,
123 ByteArrayInputStream is,
124 String requestMethod,
125 String httpProtocol) throws Exception {
126
127
128 UpnpHeaders headers = new UpnpHeaders(is);
129
130
131 IncomingDatagramMessage requestMessage;
132 UpnpRequest upnpRequest = new UpnpRequest(UpnpRequest.Method.getByHttpName(requestMethod));
133 upnpRequest.setHttpMinorVersion(httpProtocol.toUpperCase(Locale.ROOT).equals("HTTP/1.1") ? 1 : 0);
134 requestMessage = new IncomingDatagramMessage(upnpRequest, datagram.getAddress(), datagram.getPort(), receivedOnAddress);
135
136 requestMessage.setHeaders(headers);
137
138 return requestMessage;
139 }
140
141 protected IncomingDatagramMessage readResponseMessage(InetAddress receivedOnAddress,
142 DatagramPacket datagram,
143 ByteArrayInputStream is,
144 int statusCode,
145 String statusMessage,
146 String httpProtocol) throws Exception {
147
148
149 UpnpHeaders headers = new UpnpHeaders(is);
150
151
152 IncomingDatagramMessage responseMessage;
153 UpnpResponse upnpResponse = new UpnpResponse(statusCode, statusMessage);
154 upnpResponse.setHttpMinorVersion(httpProtocol.toUpperCase(Locale.ROOT).equals("HTTP/1.1") ? 1 : 0);
155 responseMessage = new IncomingDatagramMessage(upnpResponse, datagram.getAddress(), datagram.getPort(), receivedOnAddress);
156
157 responseMessage.setHeaders(headers);
158
159 return responseMessage;
160 }
161
162
163 }