/** Copyright 2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * * @author <a href='mailto:th33musk3t33rs@gmail.com'>3.musket33rs</a> * * @since 0.1 */ package org.threemusketeers.eventsource; import io.netty.handler.codec.http.HttpResponseStatus; import java.util.*; import java.util.regex.Matcher; public class EventSourceHandshaker { boolean handshakeStarted; String error; String contentType = Constants.EVENT_STREAM; boolean complete = false; public boolean continueHandshake(String content) { if (!Constants.EMPTY_LINE.equals(content)) { if(!handshakeStarted) { // Find the http status OK Matcher m = Constants.HTTP_STATUS.matcher(content); if (m.find()) { int httpStatus = Integer.parseInt(m.group(1)); // HTTP 305 Use Proxy, 401 Unauthorized, and 407 Proxy Authentication Required should be treated // transparently as for any other subresource. // HTTP 301 Moved Permanently, 302 Found, 303 See Other, and 307 Temporary Redirect responses are // handled by the fetching and CORS algorithms. In the case of 301 redirects, // the user agent must also remember the new URL so that subsequent requests for this resource // for this EventSource object start with the URL given for the last 301 seen for requests for this object. // Any other HTTP response code not listed here must cause the user agent to fail the connection. // TOBE IMPLEMENTED if (httpStatus == HttpResponseStatus.OK.code()){ handshakeStarted = true; } else { error = "HTTP Status is incorrect " + httpStatus; complete = true; return true; } } } else { Matcher m = Constants.CONTENT_TYPE.matcher(content); if (m.find()) { // Find the MIME Type javax.activation.MimeType does not exist in android String contentTypeFound = m.group(1); String basetype = null; String subtype = null; String[] mimeTypeSplitted = contentTypeFound.split(";"); if (mimeTypeSplitted.length > 0) { String mime = mimeTypeSplitted[0].toLowerCase(Locale.ENGLISH); mime = mime.replace("\\", ""); if (!mime.contains("/")) { error = "Unsupported Content Type " + contentTypeFound; complete = true; return true; } else { String[] split = mime.split("/"); basetype = split[0]; subtype = split[1]; } } ArrayList<String> parameters = new ArrayList<String>(Arrays.asList(mimeTypeSplitted)); HashMap<String, String> parametersFormatted = new HashMap<String, String>(); parameters.remove(0); for (Iterator<String> iterator = parameters.iterator(); iterator.hasNext();) { String param = iterator.next(); String[] splitParam = param.split("="); if (splitParam.length == 2) { String name = splitParam[0]; name = name.toLowerCase(Locale.ENGLISH); String value = splitParam[1]; if (value.startsWith("\"") && value.endsWith("\"")) { value = value.substring(1, value.length()); value = value.substring(0, value.length() - 1); } value = value.toLowerCase(Locale.ENGLISH); parametersFormatted.put(name, value); } } if (Constants.EVENT_STREAM.equals(basetype + "/" + subtype)) { contentType = Constants.EVENT_STREAM; String charSetValue = parametersFormatted.get(Constants.CHARSET); if (charSetValue != null) { if (!charSetValue.equals(Constants.UTF8)) { error = "Unsupported Content Type " + contentTypeFound; complete = true; return true; } } } else if (Constants.JSON.equals(contentTypeFound)) { contentType = Constants.JSON; } else { //error error = "Unsupported Content Type " + contentTypeFound; complete = true; return true; } } } return false; } else { // Check an empty line which means the end of the header if (!handshakeStarted) { error = "Unable to get an HTTP Status for the connection"; } complete = true; return true; } } public boolean isHandshakeComplete() { return complete; } }