| /* |
| * Copyright (C) 2013 Square, Inc. |
| * |
| * 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. |
| */ |
| package com.squareup.okhttp.internal.http; |
| |
| import com.squareup.okhttp.Request; |
| import com.squareup.okhttp.Response; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.HttpURLConnection; |
| import java.util.ArrayList; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.LinkedBlockingQueue; |
| import java.util.concurrent.ThreadPoolExecutor; |
| import java.util.concurrent.TimeUnit; |
| |
| public final class Dispatcher { |
| // TODO: thread pool size should be configurable; possibly configurable per host. |
| private final ThreadPoolExecutor executorService = new ThreadPoolExecutor( |
| 8, 8, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); |
| private final Map<Object, List<Job>> enqueuedJobs = new LinkedHashMap<Object, List<Job>>(); |
| |
| public synchronized void enqueue( |
| HttpURLConnection connection, Request request, Response.Receiver responseReceiver) { |
| Job job = new Job(this, connection, request, responseReceiver); |
| List<Job> jobsForTag = enqueuedJobs.get(request.tag()); |
| if (jobsForTag == null) { |
| jobsForTag = new ArrayList<Job>(2); |
| enqueuedJobs.put(request.tag(), jobsForTag); |
| } |
| jobsForTag.add(job); |
| executorService.execute(job); |
| } |
| |
| public synchronized void cancel(Object tag) { |
| List<Job> jobs = enqueuedJobs.remove(tag); |
| if (jobs == null) return; |
| for (Job job : jobs) { |
| executorService.remove(job); |
| } |
| } |
| |
| synchronized void finished(Job job) { |
| List<Job> jobs = enqueuedJobs.get(job.request.tag()); |
| if (jobs != null) jobs.remove(job); |
| } |
| |
| static class RealResponseBody extends Response.Body { |
| private final HttpURLConnection connection; |
| private final InputStream in; |
| |
| RealResponseBody(HttpURLConnection connection, InputStream in) { |
| this.connection = connection; |
| this.in = in; |
| } |
| |
| @Override public String contentType() { |
| return connection.getHeaderField("Content-Type"); |
| } |
| |
| @Override public long contentLength() { |
| return connection.getContentLength(); // TODO: getContentLengthLong |
| } |
| |
| @Override public InputStream byteStream() throws IOException { |
| return in; |
| } |
| } |
| } |