package com.wm.remusic.proxy.utils; import android.content.Context; import android.util.Log; import java.io.IOException; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; import java.util.Locale; import java.util.StringTokenizer; /** * 代理 * * @author 阿伦 */ public class MediaPlayerProxy implements Runnable { private static final String LOG_TAG = MediaPlayerProxy.class.getSimpleName(); private int port; private ServerSocket socket; private Thread thread; private boolean isRunning = true; protected static RequestDealThread downloadThread; private Context mContext; public MediaPlayerProxy(Context mContext) { this.mContext = mContext; } /** * 创建ServerSocket,使用自动分配端口 */ public void init() { try { socket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1})); socket.setSoTimeout(5000); port = socket.getLocalPort(); Log.d(LOG_TAG, "port " + port + " obtained"); } catch (UnknownHostException e) { Log.e(LOG_TAG, "Error initializing server", e); } catch (IOException e) { Log.e(LOG_TAG, "Error initializing server", e); } } public void start() { if (socket == null) { throw new IllegalStateException("Cannot start proxy; it has not been initialized."); } thread = new Thread(this); thread.start(); } public void stop() { isRunning = false; if (thread == null) { throw new IllegalStateException("Cannot stop proxy; it has not been started."); } thread.interrupt(); try { thread.join(5000); } catch (InterruptedException e) { e.printStackTrace(); } Log.d(LOG_TAG, "stop"); } public String getProxyURL(String url) { //return String.format("http://127.0.0.1:%d/%s", port, url); return String.format(Locale.getDefault(), "http://127.0.0.1:%d/%s", port, url); } @Override public void run() { Log.d(LOG_TAG, "running"); while (isRunning) { try { final Socket client = socket.accept(); if (client == null) { continue; } Log.d(LOG_TAG, "client connected"); HttpURLConnection request = readRequest(client); if (request != null) { downloadThread = new RequestDealThread(mContext, request, client); downloadThread.start(); } } catch (SocketTimeoutException e) { // Do nothing } catch (IOException e) { Log.e(LOG_TAG, "Error connecting to client", e); } } Log.d(LOG_TAG, "Proxy interrupted. Shutting down."); } void http() { URLConnection rulConnection = null; try { URL url = new URL("http://localhost:8080/TestHttpURLConnectionPro/index.jsp"); rulConnection = url.openConnection(); } catch (IOException e) { e.printStackTrace(); } // 此处的urlConnection对象实际上是根据URL的 // 请求协议(此处是http)生成的URLConnection类 // 的子类HttpURLConnection,故此处最好将其转化 // 为HttpURLConnection类型的对象,以便用到 // HttpURLConnection更多的API.如下: HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection; } private HttpURLConnection readRequest(Socket client) { // 得到Request String HttpURLConnection request = null; int bytes_read; byte[] local_request = new byte[1024]; String requestStr = ""; try { while ((bytes_read = client.getInputStream().read(local_request)) != -1) { byte[] tmpBuffer = new byte[bytes_read]; System.arraycopy(local_request, 0, tmpBuffer, 0, bytes_read); String str = new String(tmpBuffer); Log.i(LOG_TAG + " Header-> ", str); requestStr = requestStr + str; if (requestStr.contains("GET") && requestStr.contains(Constants.HTTP_END)) { break; } } } catch (IOException e) { Log.e(LOG_TAG, "获取Request Header异常", e); return request; } if (requestStr == "") { Log.i(LOG_TAG, "请求头为空,获取异常"); return request; } // 将Request String组合为HttpUriRequest String[] requestParts = requestStr.split(Constants.LINE_BREAK); StringTokenizer st = new StringTokenizer(requestParts[0]); String method = st.nextToken(); String uri = st.nextToken(); Log.d(LOG_TAG + " URL-> ", uri); // request = new HttpGet(uri.substring(1)); URLConnection rulConnection = null; try { URL url = new URL(uri.substring(1)); rulConnection = url.openConnection(); } catch (IOException e) { e.printStackTrace(); } // 此处的urlConnection对象实际上是根据URL的 // 请求协议(此处是http)生成的URLConnection类 // 的子类HttpURLConnection,故此处最好将其转化 // 为HttpURLConnection类型的对象,以便用到 // HttpURLConnection更多的API.如下: request = (HttpURLConnection) rulConnection; for (int i = 1; i < requestParts.length; i++) { int separatorLocation = requestParts[i].indexOf(":"); String name = requestParts[i].substring(0, separatorLocation).trim(); String value = requestParts[i].substring(separatorLocation + 1).trim(); // 不添加Host Header,因为URL的Host为127.0.0.1 if (!name.equals(Constants.HOST)) { try { request.setRequestProperty(name, value); } catch (NullPointerException e) { e.printStackTrace(); } } } // 如果没有Range,统一添加默认Range,方便后续处理 try { request.setRequestProperty(Constants.RANGE, Constants.RANGE_PARAMS_0); } catch (Exception e) { e.printStackTrace(); } return request; } }