ex

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Committer:
TMBOY
Date:
Tue Jul 18 16:34:48 2017 +0800
Revision:
45:2aa9f933c8d2
?

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TMBOY 45:2aa9f933c8d2 1 /*
TMBOY 45:2aa9f933c8d2 2 * Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
TMBOY 45:2aa9f933c8d2 3 *
TMBOY 45:2aa9f933c8d2 4 * Licensed under the Apache License, Version 2.0 (the "License");
TMBOY 45:2aa9f933c8d2 5 * you may not use this file except in compliance with the License.
TMBOY 45:2aa9f933c8d2 6 * You may obtain a copy of the License at
TMBOY 45:2aa9f933c8d2 7 *
TMBOY 45:2aa9f933c8d2 8 * http://www.apache.org/licenses/LICENSE-2.0
TMBOY 45:2aa9f933c8d2 9 *
TMBOY 45:2aa9f933c8d2 10 * Unless required by applicable law or agreed to in writing, software
TMBOY 45:2aa9f933c8d2 11 * distributed under the License is distributed on an "AS IS" BASIS,
TMBOY 45:2aa9f933c8d2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
TMBOY 45:2aa9f933c8d2 13 * See the License for the specific language governing permissions and
TMBOY 45:2aa9f933c8d2 14 * limitations under the License.
TMBOY 45:2aa9f933c8d2 15 */
TMBOY 45:2aa9f933c8d2 16 package com.baidu.duer.dcs.framework.dispatcher;
TMBOY 45:2aa9f933c8d2 17
TMBOY 45:2aa9f933c8d2 18 import com.baidu.duer.dcs.framework.message.DcsResponseBody;
TMBOY 45:2aa9f933c8d2 19 import com.baidu.duer.dcs.http.HttpConfig;
TMBOY 45:2aa9f933c8d2 20
TMBOY 45:2aa9f933c8d2 21 import org.apache.commons.fileupload.MultipartStream;
TMBOY 45:2aa9f933c8d2 22 import org.apache.commons.lang3.StringUtils;
TMBOY 45:2aa9f933c8d2 23
TMBOY 45:2aa9f933c8d2 24 import java.io.BufferedReader;
TMBOY 45:2aa9f933c8d2 25 import java.io.ByteArrayOutputStream;
TMBOY 45:2aa9f933c8d2 26 import java.io.IOException;
TMBOY 45:2aa9f933c8d2 27 import java.io.InputStream;
TMBOY 45:2aa9f933c8d2 28 import java.io.StringReader;
TMBOY 45:2aa9f933c8d2 29 import java.util.HashMap;
TMBOY 45:2aa9f933c8d2 30 import java.util.Map;
TMBOY 45:2aa9f933c8d2 31
TMBOY 45:2aa9f933c8d2 32 import okhttp3.Response;
TMBOY 45:2aa9f933c8d2 33
TMBOY 45:2aa9f933c8d2 34 /**
TMBOY 45:2aa9f933c8d2 35 * 把从服务器返回multipart中json对象和二进制解析成directive对象
TMBOY 45:2aa9f933c8d2 36 * <p>
TMBOY 45:2aa9f933c8d2 37 * Created by wuruisheng on 2017/5/12.
TMBOY 45:2aa9f933c8d2 38 */
TMBOY 45:2aa9f933c8d2 39 public class MultipartParser extends Parser {
TMBOY 45:2aa9f933c8d2 40 private static final int BUFFER_SIZE = 512;
TMBOY 45:2aa9f933c8d2 41 private final IMultipartParserListener multipartParserListener;
TMBOY 45:2aa9f933c8d2 42
TMBOY 45:2aa9f933c8d2 43 public MultipartParser(IMultipartParserListener listener) {
TMBOY 45:2aa9f933c8d2 44 this.multipartParserListener = listener;
TMBOY 45:2aa9f933c8d2 45 }
TMBOY 45:2aa9f933c8d2 46
TMBOY 45:2aa9f933c8d2 47 public void parseResponse(Response response) throws IOException {
TMBOY 45:2aa9f933c8d2 48 String boundary = getBoundary(response);
TMBOY 45:2aa9f933c8d2 49 if (boundary != null) {
TMBOY 45:2aa9f933c8d2 50 parseStream(response.body().byteStream(), boundary);
TMBOY 45:2aa9f933c8d2 51 }
TMBOY 45:2aa9f933c8d2 52 }
TMBOY 45:2aa9f933c8d2 53
TMBOY 45:2aa9f933c8d2 54 private void parseStream(InputStream inputStream, String boundary) throws IOException {
TMBOY 45:2aa9f933c8d2 55 MultipartStream multipartStream = new MultipartStream(inputStream, boundary.getBytes(), BUFFER_SIZE, null);
TMBOY 45:2aa9f933c8d2 56 parseMultipartStream(multipartStream);
TMBOY 45:2aa9f933c8d2 57 }
TMBOY 45:2aa9f933c8d2 58
TMBOY 45:2aa9f933c8d2 59 private void parseMultipartStream(MultipartStream multipartStream) throws IOException {
TMBOY 45:2aa9f933c8d2 60 try {
TMBOY 45:2aa9f933c8d2 61 Boolean hasNextPart = multipartStream.skipPreamble();
TMBOY 45:2aa9f933c8d2 62 while (hasNextPart) {
TMBOY 45:2aa9f933c8d2 63 handlePart(multipartStream);
TMBOY 45:2aa9f933c8d2 64 hasNextPart = multipartStream.readBoundary();
TMBOY 45:2aa9f933c8d2 65 }
TMBOY 45:2aa9f933c8d2 66 } catch (DcsJsonProcessingException exception) {
TMBOY 45:2aa9f933c8d2 67 if (multipartParserListener != null) {
TMBOY 45:2aa9f933c8d2 68 multipartParserListener.onParseFailed(exception.getUnparsedCotent());
TMBOY 45:2aa9f933c8d2 69 }
TMBOY 45:2aa9f933c8d2 70 } catch (MultipartStream.MalformedStreamException exception) {
TMBOY 45:2aa9f933c8d2 71 // 用于处理 empty part
TMBOY 45:2aa9f933c8d2 72 }
TMBOY 45:2aa9f933c8d2 73 }
TMBOY 45:2aa9f933c8d2 74
TMBOY 45:2aa9f933c8d2 75 private void handlePart(MultipartStream multipartStream) throws IOException {
TMBOY 45:2aa9f933c8d2 76 Map<String, String> headers = getPartHeaders(multipartStream);
TMBOY 45:2aa9f933c8d2 77 if (headers != null) {
TMBOY 45:2aa9f933c8d2 78 byte[] partBytes = getPartBytes(multipartStream);
TMBOY 45:2aa9f933c8d2 79 Boolean isJsonData = isPartJSON(headers);
TMBOY 45:2aa9f933c8d2 80 if (isJsonData) {
TMBOY 45:2aa9f933c8d2 81 handleJsonData(partBytes);
TMBOY 45:2aa9f933c8d2 82 } else {
TMBOY 45:2aa9f933c8d2 83 handleAudio(headers, partBytes);
TMBOY 45:2aa9f933c8d2 84 }
TMBOY 45:2aa9f933c8d2 85 }
TMBOY 45:2aa9f933c8d2 86 }
TMBOY 45:2aa9f933c8d2 87
TMBOY 45:2aa9f933c8d2 88 private void handleJsonData(byte[] partBytes) throws IOException {
TMBOY 45:2aa9f933c8d2 89 final DcsResponseBody responseBody = parse(partBytes, DcsResponseBody.class);
TMBOY 45:2aa9f933c8d2 90 if (multipartParserListener != null) {
TMBOY 45:2aa9f933c8d2 91 multipartParserListener.onResponseBody(responseBody);
TMBOY 45:2aa9f933c8d2 92 }
TMBOY 45:2aa9f933c8d2 93 }
TMBOY 45:2aa9f933c8d2 94
TMBOY 45:2aa9f933c8d2 95 private void handleAudio(Map<String, String> headers, byte[] partBytes) {
TMBOY 45:2aa9f933c8d2 96 String contentId = getMultipartContentId(headers);
TMBOY 45:2aa9f933c8d2 97 final AudioData audioData = new AudioData(contentId, partBytes);
TMBOY 45:2aa9f933c8d2 98 if (multipartParserListener != null) {
TMBOY 45:2aa9f933c8d2 99 multipartParserListener.onAudioData(audioData);
TMBOY 45:2aa9f933c8d2 100 }
TMBOY 45:2aa9f933c8d2 101 }
TMBOY 45:2aa9f933c8d2 102
TMBOY 45:2aa9f933c8d2 103 private byte[] getPartBytes(MultipartStream multipartStream) throws IOException {
TMBOY 45:2aa9f933c8d2 104 ByteArrayOutputStream data = new ByteArrayOutputStream();
TMBOY 45:2aa9f933c8d2 105 multipartStream.readBodyData(data);
TMBOY 45:2aa9f933c8d2 106 return data.toByteArray();
TMBOY 45:2aa9f933c8d2 107 }
TMBOY 45:2aa9f933c8d2 108
TMBOY 45:2aa9f933c8d2 109 private Map<String, String> getPartHeaders(MultipartStream multipartStream) throws IOException {
TMBOY 45:2aa9f933c8d2 110 String headers = multipartStream.readHeaders();
TMBOY 45:2aa9f933c8d2 111 BufferedReader reader = new BufferedReader(new StringReader(headers));
TMBOY 45:2aa9f933c8d2 112 Map<String, String> headerMap = new HashMap<>();
TMBOY 45:2aa9f933c8d2 113 try {
TMBOY 45:2aa9f933c8d2 114 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
TMBOY 45:2aa9f933c8d2 115 line = line.trim();
TMBOY 45:2aa9f933c8d2 116 if (!StringUtils.isBlank(line) && line.contains(":")) {
TMBOY 45:2aa9f933c8d2 117 int colon = line.indexOf(":");
TMBOY 45:2aa9f933c8d2 118 String headerName = line.substring(0, colon).trim();
TMBOY 45:2aa9f933c8d2 119 String headerValue = line.substring(colon + 1).trim();
TMBOY 45:2aa9f933c8d2 120 headerMap.put(headerName.toLowerCase(), headerValue);
TMBOY 45:2aa9f933c8d2 121 }
TMBOY 45:2aa9f933c8d2 122 }
TMBOY 45:2aa9f933c8d2 123 } catch (Exception e) {
TMBOY 45:2aa9f933c8d2 124 throw e;
TMBOY 45:2aa9f933c8d2 125 }
TMBOY 45:2aa9f933c8d2 126
TMBOY 45:2aa9f933c8d2 127 return headerMap;
TMBOY 45:2aa9f933c8d2 128 }
TMBOY 45:2aa9f933c8d2 129
TMBOY 45:2aa9f933c8d2 130 private String getMultipartHeaderValue(Map<String, String> headers, String searchHeader) {
TMBOY 45:2aa9f933c8d2 131 return headers.get(searchHeader.toLowerCase());
TMBOY 45:2aa9f933c8d2 132 }
TMBOY 45:2aa9f933c8d2 133
TMBOY 45:2aa9f933c8d2 134 private String getMultipartContentId(Map<String, String> headers) {
TMBOY 45:2aa9f933c8d2 135 String contentId = getMultipartHeaderValue(headers, HttpConfig.HttpHeaders.CONTENT_ID);
TMBOY 45:2aa9f933c8d2 136 contentId = contentId.substring(1, contentId.length() - 1);
TMBOY 45:2aa9f933c8d2 137 return contentId;
TMBOY 45:2aa9f933c8d2 138 }
TMBOY 45:2aa9f933c8d2 139
TMBOY 45:2aa9f933c8d2 140 private boolean isPartJSON(Map<String, String> headers) {
TMBOY 45:2aa9f933c8d2 141 String contentType = getMultipartHeaderValue(headers, HttpConfig.HttpHeaders.CONTENT_TYPE);
TMBOY 45:2aa9f933c8d2 142 return StringUtils.contains(contentType, HttpConfig.ContentTypes.JSON);
TMBOY 45:2aa9f933c8d2 143 }
TMBOY 45:2aa9f933c8d2 144
TMBOY 45:2aa9f933c8d2 145 private static String getBoundary(Response response) {
TMBOY 45:2aa9f933c8d2 146 String headerValue = response.header(HttpConfig.HttpHeaders.CONTENT_TYPE);
TMBOY 45:2aa9f933c8d2 147 String boundary = getHeaderParameter(headerValue, HttpConfig.Parameters.BOUNDARY);
TMBOY 45:2aa9f933c8d2 148 return boundary;
TMBOY 45:2aa9f933c8d2 149 }
TMBOY 45:2aa9f933c8d2 150
TMBOY 45:2aa9f933c8d2 151 private static String getHeaderParameter(final String headerValue, final String key) {
TMBOY 45:2aa9f933c8d2 152 if ((headerValue == null) || (key == null)) {
TMBOY 45:2aa9f933c8d2 153 return null;
TMBOY 45:2aa9f933c8d2 154 }
TMBOY 45:2aa9f933c8d2 155
TMBOY 45:2aa9f933c8d2 156 String[] parts = headerValue.split(";");
TMBOY 45:2aa9f933c8d2 157 for (String part : parts) {
TMBOY 45:2aa9f933c8d2 158 part = part.trim();
TMBOY 45:2aa9f933c8d2 159 if (part.startsWith(key)) {
TMBOY 45:2aa9f933c8d2 160 return part.substring(key.length() + 1).replaceAll("(^\")|(\"$)", "").trim();
TMBOY 45:2aa9f933c8d2 161 }
TMBOY 45:2aa9f933c8d2 162 }
TMBOY 45:2aa9f933c8d2 163
TMBOY 45:2aa9f933c8d2 164 return null;
TMBOY 45:2aa9f933c8d2 165 }
TMBOY 45:2aa9f933c8d2 166
TMBOY 45:2aa9f933c8d2 167 public interface IMultipartParserListener {
TMBOY 45:2aa9f933c8d2 168 void onResponseBody(DcsResponseBody responseBody);
TMBOY 45:2aa9f933c8d2 169
TMBOY 45:2aa9f933c8d2 170 void onAudioData(AudioData audioData);
TMBOY 45:2aa9f933c8d2 171
TMBOY 45:2aa9f933c8d2 172 void onParseFailed(String unParseMessage);
TMBOY 45:2aa9f933c8d2 173 }
TMBOY 45:2aa9f933c8d2 174 }