Mercurial Hosting > luan
comparison src/org/eclipse/jetty/http/HttpFields.java @ 1020:6be43ef1eb96
HttpHeaderValues uses StringCache
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 31 Oct 2016 22:24:41 -0600 |
parents | f126d30e04a4 |
children | e350c11242be |
comparison
equal
deleted
inserted
replaced
1019:f126d30e04a4 | 1020:6be43ef1eb96 |
---|---|
275 | 275 |
276 | 276 |
277 | 277 |
278 private final ArrayList<Field> _fields = new ArrayList<Field>(20); | 278 private final ArrayList<Field> _fields = new ArrayList<Field>(20); |
279 private final HashMap<Buffer,Field> _names = new HashMap<Buffer,Field>(32); | 279 private final HashMap<Buffer,Field> _names = new HashMap<Buffer,Field>(32); |
280 | 280 /* |
281 /* ------------------------------------------------------------ */ | |
282 /** | |
283 * Constructor. | |
284 */ | |
285 public HttpFields() | |
286 { | |
287 } | |
288 | |
289 // TODO externalize this cache so it can be configurable | |
290 private static ConcurrentMap<String, Buffer> __cache = new ConcurrentHashMap<String, Buffer>(); | |
291 private static int __cacheSize = Integer.getInteger("org.eclipse.jetty.http.HttpFields.CACHE",2000); | |
292 | |
293 /* -------------------------------------------------------------- */ | |
294 private Buffer convertValue(String value) | 281 private Buffer convertValue(String value) |
295 { | 282 { |
296 Buffer buffer = __cache.get(value); | |
297 if (buffer!=null) | |
298 return buffer; | |
299 | |
300 try | 283 try |
301 { | 284 { |
302 buffer = new ByteArrayBuffer(value,StringUtil.__ISO_8859_1); | 285 return new ByteArrayBuffer(value,StringUtil.__ISO_8859_1); |
303 | |
304 if (__cacheSize>0) | |
305 { | |
306 if (__cache.size()>__cacheSize) | |
307 __cache.clear(); | |
308 Buffer b=__cache.putIfAbsent(value,buffer); | |
309 if (b!=null) | |
310 buffer=b; | |
311 } | |
312 | |
313 return buffer; | |
314 } | 286 } |
315 catch (UnsupportedEncodingException e) | 287 catch (UnsupportedEncodingException e) |
316 { | 288 { |
317 throw new RuntimeException(e); | 289 throw new RuntimeException(e); |
318 } | 290 } |
319 } | 291 } |
292 */ | |
320 | 293 |
321 /* -------------------------------------------------------------- */ | 294 /* -------------------------------------------------------------- */ |
322 /** | 295 /** |
323 * Get Collection of header names. | 296 * Get Collection of header names. |
324 */ | 297 */ |
421 return field==null?null:field.getValue(); | 394 return field==null?null:field.getValue(); |
422 } | 395 } |
423 | 396 |
424 /* -------------------------------------------------------------- */ | 397 /* -------------------------------------------------------------- */ |
425 /** | 398 /** |
426 * @return the value of a field, or null if not found. For multiple fields of the same name, | |
427 * only the first is returned. | |
428 * @param name the case-insensitive field name | |
429 */ | |
430 public Buffer get(Buffer name) | |
431 { | |
432 Field field = getField(name); | |
433 return field==null?null:field._value; | |
434 } | |
435 | |
436 | |
437 /* -------------------------------------------------------------- */ | |
438 /** | |
439 * Get multi headers | 399 * Get multi headers |
440 * | 400 * |
441 * @return Enumeration of the values, or null if no such header. | 401 * @return Enumeration of the values, or null if no such header. |
442 * @param name the case-insensitive field name | 402 * @param name the case-insensitive field name |
443 */ | 403 */ |
444 public Collection<String> getValuesCollection(String name) | 404 public Collection<String> getValuesCollection(String name) |
445 { | 405 { |
446 Field field = getField(name); | 406 Field field = getField(name); |
447 if (field==null) | 407 if (field==null) |
448 return null; | 408 return null; |
449 | 409 |
450 final List<String> list = new ArrayList<String>(); | 410 final List<String> list = new ArrayList<String>(); |
451 | 411 |
452 while(field!=null) | 412 while(field!=null) |
453 { | 413 { |
454 list.add(field.getValue()); | 414 list.add(field.getValue()); |
455 field=field._next; | 415 field=field._next; |
456 } | 416 } |
457 return list; | 417 return list; |
458 } | 418 } |
459 | 419 |
460 /* -------------------------------------------------------------- */ | 420 /* -------------------------------------------------------------- */ |
461 /** | 421 /** |
462 * Get multi headers | 422 * Get multi headers |
582 if (value==null) | 542 if (value==null) |
583 remove(name); | 543 remove(name); |
584 else | 544 else |
585 { | 545 { |
586 Buffer n = HttpHeaders.CACHE.lookup(name); | 546 Buffer n = HttpHeaders.CACHE.lookup(name); |
587 Buffer v = convertValue(value); | 547 put(n, value); |
588 put(n, v); | |
589 } | 548 } |
590 } | 549 } |
591 | 550 |
592 /* -------------------------------------------------------------- */ | 551 /* -------------------------------------------------------------- */ |
593 /** | 552 /** |
596 * @param name the name of the field | 555 * @param name the name of the field |
597 * @param value the value of the field. If null the field is cleared. | 556 * @param value the value of the field. If null the field is cleared. |
598 */ | 557 */ |
599 public void put(Buffer name, String value) | 558 public void put(Buffer name, String value) |
600 { | 559 { |
560 /* | |
601 Buffer n = HttpHeaders.CACHE.lookup(name); | 561 Buffer n = HttpHeaders.CACHE.lookup(name); |
602 Buffer v = convertValue(value); | 562 Buffer v = convertValue(value); |
603 put(n, v); | 563 put(n, v); |
604 } | 564 */ |
605 | |
606 /* -------------------------------------------------------------- */ | |
607 /** | |
608 * Set a field. | |
609 * | |
610 * @param name the name of the field | |
611 * @param value the value of the field. If null the field is cleared. | |
612 */ | |
613 public void put(Buffer name, Buffer value) | |
614 { | |
615 remove(name); | 565 remove(name); |
616 if (value == null) | 566 if (value == null) |
617 return; | 567 return; |
618 | 568 |
619 if (!(name instanceof BufferCache.CachedBuffer)) | 569 if (!(name instanceof BufferCache.CachedBuffer)) |
620 name = HttpHeaders.CACHE.lookup(name); | 570 name = HttpHeaders.CACHE.lookup(name); |
571 int valueOrdinal = HttpHeaderValues.CACHE.getOrdinal(value); | |
572 | |
573 // new value; | |
574 Field field = new Field(name, value, valueOrdinal); | |
575 _fields.add(field); | |
576 _names.put(name, field); | |
577 } | |
578 | |
579 /* -------------------------------------------------------------- */ | |
580 /** | |
581 * Set a field. | |
582 * | |
583 * @param name the name of the field | |
584 * @param value the value of the field. If null the field is cleared. | |
585 */ | |
586 public void put(Buffer name, Buffer value) | |
587 { | |
588 /* | |
589 remove(name); | |
590 if (value == null) | |
591 return; | |
592 | |
593 if (!(name instanceof BufferCache.CachedBuffer)) | |
594 name = HttpHeaders.CACHE.lookup(name); | |
621 if (!(value instanceof CachedBuffer)) | 595 if (!(value instanceof CachedBuffer)) |
622 value= HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer(); | 596 value = HttpHeaderValues.CACHE.lookup(value).asImmutableBuffer(); |
623 | 597 |
624 // new value; | 598 // new value; |
625 Field field = new Field(name, value); | 599 Field field = new Field(name, value); |
626 _fields.add(field); | 600 _fields.add(field); |
627 _names.put(name, field); | 601 _names.put(name, field); |
628 } | 602 */ |
629 | 603 String s = value==null ? null : value.toString(); |
630 /* -------------------------------------------------------------- */ | 604 put(name,s); |
631 /** | |
632 * Set a field. | |
633 * | |
634 * @param name the name of the field | |
635 * @param list the List value of the field. If null the field is cleared. | |
636 */ | |
637 public void put(String name, List<?> list) | |
638 { | |
639 if (list == null || list.size() == 0) | |
640 { | |
641 remove(name); | |
642 return; | |
643 } | |
644 Buffer n = HttpHeaders.CACHE.lookup(name); | |
645 | |
646 Object v = list.get(0); | |
647 if (v != null) | |
648 put(n, HttpHeaderValues.CACHE.lookup(v.toString())); | |
649 else | |
650 remove(n); | |
651 | |
652 if (list.size() > 1) | |
653 { | |
654 java.util.Iterator<?> iter = list.iterator(); | |
655 iter.next(); | |
656 while (iter.hasNext()) | |
657 { | |
658 v = iter.next(); | |
659 if (v != null) put(n, HttpHeaderValues.CACHE.lookup(v.toString())); | |
660 } | |
661 } | |
662 } | 605 } |
663 | 606 |
664 /* -------------------------------------------------------------- */ | 607 /* -------------------------------------------------------------- */ |
665 /** | 608 /** |
666 * Add to or set a field. If the field is allowed to have multiple values, add will add multiple | 609 * Add to or set a field. If the field is allowed to have multiple values, add will add multiple |
674 public void add(String name, String value) throws IllegalArgumentException | 617 public void add(String name, String value) throws IllegalArgumentException |
675 { | 618 { |
676 if (value==null) | 619 if (value==null) |
677 return; | 620 return; |
678 Buffer n = HttpHeaders.CACHE.lookup(name); | 621 Buffer n = HttpHeaders.CACHE.lookup(name); |
679 Buffer v = convertValue(value); | 622 add(n, value); |
680 add(n, v); | |
681 } | 623 } |
682 | 624 |
683 /* -------------------------------------------------------------- */ | 625 /* -------------------------------------------------------------- */ |
684 /** | 626 /** |
685 * Add to or set a field. If the field is allowed to have multiple values, add will add multiple | 627 * Add to or set a field. If the field is allowed to have multiple values, add will add multiple |
688 * @param name the name of the field | 630 * @param name the name of the field |
689 * @param value the value of the field. | 631 * @param value the value of the field. |
690 * @exception IllegalArgumentException If the name is a single valued field and already has a | 632 * @exception IllegalArgumentException If the name is a single valued field and already has a |
691 * value. | 633 * value. |
692 */ | 634 */ |
693 public void add(Buffer name, Buffer value) throws IllegalArgumentException | 635 public void add(Buffer name, String value) throws IllegalArgumentException |
694 { | 636 { |
695 if (value == null) throw new IllegalArgumentException("null value"); | 637 if (value == null) throw new IllegalArgumentException("null value"); |
696 | 638 |
697 if (!(name instanceof CachedBuffer)) | 639 if (!(name instanceof CachedBuffer)) |
698 name = HttpHeaders.CACHE.lookup(name); | 640 name = HttpHeaders.CACHE.lookup(name); |
699 name=name.asImmutableBuffer(); | 641 name=name.asImmutableBuffer(); |
700 | 642 /* |
701 if (!(value instanceof CachedBuffer) && HttpHeaderValues.hasKnownValues(HttpHeaders.CACHE.getOrdinal(name))) | 643 if (!(value instanceof CachedBuffer) && HttpHeaderValues.hasKnownValues(HttpHeaders.CACHE.getOrdinal(name))) |
702 value= HttpHeaderValues.CACHE.lookup(value); | 644 value= HttpHeaderValues.CACHE.lookup(value); |
703 value=value.asImmutableBuffer(); | 645 value=value.asImmutableBuffer(); |
704 | 646 */ |
705 Field field = _names.get(name); | 647 Field field = _names.get(name); |
706 Field last = null; | 648 Field last = null; |
707 while (field != null) | 649 while (field != null) |
708 { | 650 { |
709 last = field; | 651 last = field; |
710 field = field._next; | 652 field = field._next; |
711 } | 653 } |
712 | 654 |
713 // create the field | 655 // create the field |
714 field = new Field(name, value); | 656 int valueOrdinal = HttpHeaderValues.CACHE.getOrdinal(value); |
657 field = new Field(name, value, valueOrdinal); | |
715 _fields.add(field); | 658 _fields.add(field); |
716 | 659 |
717 // look for chain to add too | 660 // look for chain to add too |
718 if (last != null) | 661 if (last != null) |
719 last._next = field; | 662 last._next = field; |
789 { | 732 { |
790 Field field = getField(name); | 733 Field field = getField(name); |
791 if (field == null) | 734 if (field == null) |
792 return -1; | 735 return -1; |
793 | 736 |
794 String val = valueParameters(BufferUtil.to8859_1_String(field._value), null); | 737 String val = valueParameters(field._value, null); |
795 if (val == null) | 738 if (val == null) |
796 return -1; | 739 return -1; |
797 | 740 |
798 final long date = __dateParser.get().parse(val); | 741 final long date = __dateParser.get().parse(val); |
799 if (date==-1) | 742 if (date==-1) |
808 * @param name the field name | 751 * @param name the field name |
809 * @param value the field long value | 752 * @param value the field long value |
810 */ | 753 */ |
811 public void putLongField(Buffer name, long value) | 754 public void putLongField(Buffer name, long value) |
812 { | 755 { |
813 Buffer v = BufferUtil.toBuffer(value); | 756 // Buffer v = BufferUtil.toBuffer(value); |
757 String v = Long.toString(value); | |
814 put(name, v); | 758 put(name, v); |
815 } | 759 } |
816 | 760 |
817 /* -------------------------------------------------------------- */ | 761 /* -------------------------------------------------------------- */ |
818 /** | 762 /** |
822 * @param value the field long value | 766 * @param value the field long value |
823 */ | 767 */ |
824 public void putLongField(String name, long value) | 768 public void putLongField(String name, long value) |
825 { | 769 { |
826 Buffer n = HttpHeaders.CACHE.lookup(name); | 770 Buffer n = HttpHeaders.CACHE.lookup(name); |
827 Buffer v = BufferUtil.toBuffer(value); | 771 // Buffer v = BufferUtil.toBuffer(value); |
772 String v = Long.toString(value); | |
828 put(n, v); | 773 put(n, v); |
829 } | 774 } |
830 | 775 |
831 /* -------------------------------------------------------------- */ | 776 /* -------------------------------------------------------------- */ |
832 /** | 777 /** |
836 * @param value the field long value | 781 * @param value the field long value |
837 */ | 782 */ |
838 public void addLongField(String name, long value) | 783 public void addLongField(String name, long value) |
839 { | 784 { |
840 Buffer n = HttpHeaders.CACHE.lookup(name); | 785 Buffer n = HttpHeaders.CACHE.lookup(name); |
841 Buffer v = BufferUtil.toBuffer(value); | 786 // Buffer v = BufferUtil.toBuffer(value); |
787 String v = Long.toString(value); | |
842 add(n, v); | 788 add(n, v); |
843 } | 789 } |
844 | 790 |
845 /* -------------------------------------------------------------- */ | 791 /* -------------------------------------------------------------- */ |
846 /** | 792 /** |
849 * @param name the field name | 795 * @param name the field name |
850 * @param value the field long value | 796 * @param value the field long value |
851 */ | 797 */ |
852 public void addLongField(Buffer name, long value) | 798 public void addLongField(Buffer name, long value) |
853 { | 799 { |
854 Buffer v = BufferUtil.toBuffer(value); | 800 // Buffer v = BufferUtil.toBuffer(value); |
801 String v = Long.toString(value); | |
855 add(name, v); | 802 add(name, v); |
856 } | 803 } |
857 | 804 |
858 /* -------------------------------------------------------------- */ | 805 /* -------------------------------------------------------------- */ |
859 /** | 806 /** |
891 */ | 838 */ |
892 public void addDateField(String name, long date) | 839 public void addDateField(String name, long date) |
893 { | 840 { |
894 String d=formatDate(date); | 841 String d=formatDate(date); |
895 Buffer n = HttpHeaders.CACHE.lookup(name); | 842 Buffer n = HttpHeaders.CACHE.lookup(name); |
896 Buffer v = new ByteArrayBuffer(d); | 843 // Buffer v = new ByteArrayBuffer(d); |
897 add(n, v); | 844 add(n, d); |
898 } | 845 } |
899 | 846 |
900 /* ------------------------------------------------------------ */ | 847 /* ------------------------------------------------------------ */ |
901 /** | 848 /** |
902 * Format a set cookie value | 849 * Format a set cookie value |
1026 } | 973 } |
1027 last=field; | 974 last=field; |
1028 field=field._next; | 975 field=field._next; |
1029 } | 976 } |
1030 | 977 |
1031 add(HttpHeaders.SET_COOKIE_BUFFER, new ByteArrayBuffer(name_value_params)); | 978 add(HttpHeaders.SET_COOKIE_BUFFER, name_value_params); |
1032 | 979 |
1033 // Expire responses with set-cookie headers so they do not get cached. | 980 // Expire responses with set-cookie headers so they do not get cached. |
1034 put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER); | 981 put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER); |
1035 } | 982 } |
1036 | 983 |
1037 /* -------------------------------------------------------------- */ | 984 @Override |
1038 public void putTo(Buffer buffer) throws IOException | |
1039 { | |
1040 for (int i = 0; i < _fields.size(); i++) | |
1041 { | |
1042 Field field = _fields.get(i); | |
1043 if (field != null) | |
1044 field.putTo(buffer); | |
1045 } | |
1046 BufferUtil.putCRLF(buffer); | |
1047 } | |
1048 | |
1049 /* -------------------------------------------------------------- */ | |
1050 public String toString() | 985 public String toString() |
1051 { | 986 { |
1052 try | 987 try |
1053 { | 988 { |
1054 StringBuffer buffer = new StringBuffer(); | 989 StringBuffer buffer = new StringBuffer(); |
1219 } | 1154 } |
1220 ql.clear(); | 1155 ql.clear(); |
1221 return vl; | 1156 return vl; |
1222 } | 1157 } |
1223 | 1158 |
1224 /* ------------------------------------------------------------ */ | 1159 |
1225 /* ------------------------------------------------------------ */ | |
1226 /* ------------------------------------------------------------ */ | |
1227 public static final class Field | 1160 public static final class Field |
1228 { | 1161 { |
1229 private Buffer _name; | 1162 private final Buffer _name; |
1230 private Buffer _value; | 1163 private final String _value; |
1164 private final int _valueOrdinal; | |
1231 private Field _next; | 1165 private Field _next; |
1232 | 1166 |
1233 /* ------------------------------------------------------------ */ | 1167 private Field(Buffer name, String value, int valueOrdinal) |
1234 private Field(Buffer name, Buffer value) | |
1235 { | 1168 { |
1236 _name = name; | 1169 _name = name; |
1237 _value = value; | 1170 _value = value; |
1171 _valueOrdinal = valueOrdinal; | |
1238 _next = null; | 1172 _next = null; |
1239 } | 1173 } |
1240 | 1174 /* |
1241 /* ------------------------------------------------------------ */ | 1175 private Field(Buffer name, Buffer value) |
1176 { | |
1177 this(name,value.toString(),HttpHeaderValues.CACHE.getOrdinal(value)); | |
1178 } | |
1179 */ | |
1242 public void putTo(Buffer buffer) throws IOException | 1180 public void putTo(Buffer buffer) throws IOException |
1243 { | 1181 { |
1244 int o=(_name instanceof CachedBuffer)?((CachedBuffer)_name).getOrdinal():-1; | 1182 int o=(_name instanceof CachedBuffer)?((CachedBuffer)_name).getOrdinal():-1; |
1245 if (o>=0) | 1183 if (o>=0) |
1246 buffer.put(_name); | 1184 buffer.put(_name); |
1264 } | 1202 } |
1265 | 1203 |
1266 buffer.put((byte) ':'); | 1204 buffer.put((byte) ':'); |
1267 buffer.put((byte) ' '); | 1205 buffer.put((byte) ' '); |
1268 | 1206 |
1269 o=(_value instanceof CachedBuffer)?((CachedBuffer)_value).getOrdinal():-1; | 1207 o = _valueOrdinal; |
1208 byte[] valueBytes = StringUtil.getBytes(_value); | |
1270 if (o>=0) | 1209 if (o>=0) |
1271 buffer.put(_value); | 1210 buffer.put(valueBytes); |
1272 else | 1211 else |
1273 { | 1212 { |
1274 int s=_value.getIndex(); | 1213 for( byte b : valueBytes ) { |
1275 int e=_value.putIndex(); | |
1276 while (s<e) | |
1277 { | |
1278 byte b=_value.peek(s++); | |
1279 switch(b) | 1214 switch(b) |
1280 { | 1215 { |
1281 case '\r': | 1216 case '\r': |
1282 case '\n': | 1217 case '\n': |
1283 continue; | 1218 continue; |
1288 } | 1223 } |
1289 | 1224 |
1290 BufferUtil.putCRLF(buffer); | 1225 BufferUtil.putCRLF(buffer); |
1291 } | 1226 } |
1292 | 1227 |
1293 /* ------------------------------------------------------------ */ | 1228 private String getName() |
1294 public String getName() | |
1295 { | 1229 { |
1296 return BufferUtil.to8859_1_String(_name); | 1230 return BufferUtil.to8859_1_String(_name); |
1297 } | 1231 } |
1298 | 1232 |
1299 /* ------------------------------------------------------------ */ | |
1300 Buffer getNameBuffer() | |
1301 { | |
1302 return _name; | |
1303 } | |
1304 | |
1305 /* ------------------------------------------------------------ */ | |
1306 public int getNameOrdinal() | 1233 public int getNameOrdinal() |
1307 { | 1234 { |
1308 return HttpHeaders.CACHE.getOrdinal(_name); | 1235 return HttpHeaders.CACHE.getOrdinal(_name); |
1309 } | 1236 } |
1310 | 1237 |
1311 /* ------------------------------------------------------------ */ | |
1312 public String getValue() | 1238 public String getValue() |
1313 { | 1239 { |
1314 return BufferUtil.to8859_1_String(_value); | |
1315 } | |
1316 | |
1317 /* ------------------------------------------------------------ */ | |
1318 public Buffer getValueBuffer() | |
1319 { | |
1320 return _value; | 1240 return _value; |
1321 } | 1241 } |
1322 | 1242 |
1323 /* ------------------------------------------------------------ */ | |
1324 public int getValueOrdinal() | 1243 public int getValueOrdinal() |
1325 { | 1244 { |
1326 return HttpHeaderValues.CACHE.getOrdinal(_value); | 1245 return _valueOrdinal; |
1327 } | 1246 } |
1328 | 1247 |
1329 /* ------------------------------------------------------------ */ | |
1330 public int getIntValue() | 1248 public int getIntValue() |
1331 { | 1249 { |
1332 return (int) getLongValue(); | 1250 return (int) getLongValue(); |
1333 } | 1251 } |
1334 | 1252 |
1335 /* ------------------------------------------------------------ */ | |
1336 public long getLongValue() | 1253 public long getLongValue() |
1337 { | 1254 { |
1338 return BufferUtil.toLong(_value); | 1255 return BufferUtil.toLong(_value); |
1339 } | 1256 } |
1340 | 1257 |
1341 /* ------------------------------------------------------------ */ | 1258 @Override |
1342 public String toString() | 1259 public String toString() |
1343 { | 1260 { |
1344 return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]"); | 1261 return ("[" + getName() + "=" + _value + (_next == null ? "" : "->") + "]"); |
1345 } | 1262 } |
1346 } | 1263 } |