31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.Locale;
37 import java.util.Map;
38 import java.util.Optional;
39 import java.util.Set;
40
41 /**
42 * Reads response headers off channel, in blocking mode. Entire header
43 * block is collected in a byte[]. The offset location of the start of
44 * each header name is recorded in an array to facilitate later searching.
45 *
46 * The location of "Content-length" is recorded explicitly. Similar approach
47 * could be taken for other common headers.
48 *
49 * This class is not thread-safe
50 */
51 class ResponseHeaders implements HttpHeaders1 {
52
53 static final int DATA_SIZE = 16 * 1024; // initial space for headers
54 static final int NUM_HEADERS = 50; // initial expected max number of headers
55
56 final HttpConnection connection;
57 byte[] data;
58 int contentlen = -2; // means not initialized
59 ByteBuffer buffer;
60
61 /**
62 * Following used for scanning the array looking for:
63 * - well known headers
64 * - end of header block
65 */
66 int[] headerOffsets; // index into data
67 int numHeaders;
68 int count;
69
70 ByteBuffer residue; // after headers processed, data may be here
71
349 Map<String,List<String>> headers = new HashMap<>();
350
351 @Override
352 public Optional<String> firstValue(String name) {
353 List<String> l = allValues(name);
354 if (l == null || l.isEmpty()) {
355 return Optional.ofNullable(null);
356 } else {
357 return Optional.of(l.get(0));
358 }
359 }
360
361 @Override
362 public List<String> allValues(String name) {
363 name = name.toLowerCase(usLocale);
364 List<String> l = headers.get(name);
365 if (l == null) {
366 l = populateMapEntry(name);
367 }
368 return Collections.unmodifiableList(l);
369 }
370
371 @Override
372 public void makeUnmodifiable() {
373 }
374
375 // Delegates map to HashMap but converts keys to lower case
376
377 static class HeaderMap implements Map<String,List<String>> {
378 Map<String,List<String>> inner;
379
380 HeaderMap(Map<String,List<String>> inner) {
381 this.inner = inner;
382 }
383 @Override
384 public int size() {
385 return inner.size();
386 }
387
388 @Override
389 public boolean isEmpty() {
390 return inner.isEmpty();
391 }
392
|
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.Locale;
37 import java.util.Map;
38 import java.util.Optional;
39 import java.util.Set;
40
41 /**
42 * Reads response headers off channel, in blocking mode. Entire header
43 * block is collected in a byte[]. The offset location of the start of
44 * each header name is recorded in an array to facilitate later searching.
45 *
46 * The location of "Content-length" is recorded explicitly. Similar approach
47 * could be taken for other common headers.
48 *
49 * This class is not thread-safe
50 */
51 class ResponseHeaders implements HttpHeaders {
52
53 static final int DATA_SIZE = 16 * 1024; // initial space for headers
54 static final int NUM_HEADERS = 50; // initial expected max number of headers
55
56 final HttpConnection connection;
57 byte[] data;
58 int contentlen = -2; // means not initialized
59 ByteBuffer buffer;
60
61 /**
62 * Following used for scanning the array looking for:
63 * - well known headers
64 * - end of header block
65 */
66 int[] headerOffsets; // index into data
67 int numHeaders;
68 int count;
69
70 ByteBuffer residue; // after headers processed, data may be here
71
349 Map<String,List<String>> headers = new HashMap<>();
350
351 @Override
352 public Optional<String> firstValue(String name) {
353 List<String> l = allValues(name);
354 if (l == null || l.isEmpty()) {
355 return Optional.ofNullable(null);
356 } else {
357 return Optional.of(l.get(0));
358 }
359 }
360
361 @Override
362 public List<String> allValues(String name) {
363 name = name.toLowerCase(usLocale);
364 List<String> l = headers.get(name);
365 if (l == null) {
366 l = populateMapEntry(name);
367 }
368 return Collections.unmodifiableList(l);
369 }
370
371 // Delegates map to HashMap but converts keys to lower case
372
373 static class HeaderMap implements Map<String,List<String>> {
374 Map<String,List<String>> inner;
375
376 HeaderMap(Map<String,List<String>> inner) {
377 this.inner = inner;
378 }
379 @Override
380 public int size() {
381 return inner.size();
382 }
383
384 @Override
385 public boolean isEmpty() {
386 return inner.isEmpty();
387 }
388
|