1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.http.message;
29
30 import java.util.BitSet;
31 import java.util.Iterator;
32 import java.util.LinkedHashSet;
33 import java.util.Set;
34
35 import org.apache.hc.core5.http.EntityDetails;
36 import org.apache.hc.core5.http.FormattedHeader;
37 import org.apache.hc.core5.http.Header;
38 import org.apache.hc.core5.http.HeaderElement;
39 import org.apache.hc.core5.http.HttpHeaders;
40 import org.apache.hc.core5.http.HttpMessage;
41 import org.apache.hc.core5.http.HttpResponse;
42 import org.apache.hc.core5.http.HttpStatus;
43 import org.apache.hc.core5.http.MessageHeaders;
44 import org.apache.hc.core5.http.Method;
45 import org.apache.hc.core5.util.Args;
46 import org.apache.hc.core5.util.CharArrayBuffer;
47 import org.apache.hc.core5.util.TextUtils;
48 import org.apache.hc.core5.util.Tokenizer;
49
50
51
52
53
54
55 public class MessageSupport {
56
57
58
59
60 private static final String[] EMPTY_STRING_ARRAY = new String[0];
61
62 private MessageSupport() {
63
64 }
65
66 public static void formatTokens(final CharArrayBuffer dst, final String... tokens) {
67 Args.notNull(dst, "Destination");
68 for (int i = 0; i < tokens.length; i++) {
69 final String element = tokens[i];
70 if (i > 0) {
71 dst.append(", ");
72 }
73 dst.append(element);
74 }
75 }
76
77 public static void formatTokens(final CharArrayBuffer dst, final Set<String> tokens) {
78 Args.notNull(dst, "Destination");
79 if (tokens == null || tokens.isEmpty()) {
80 return;
81 }
82 formatTokens(dst, tokens.toArray(EMPTY_STRING_ARRAY));
83 }
84
85 public static Header format(final String name, final Set<String> tokens) {
86 Args.notBlank(name, "Header name");
87 if (tokens == null || tokens.isEmpty()) {
88 return null;
89 }
90 final CharArrayBufferrayBuffer.html#CharArrayBuffer">CharArrayBuffer buffer = new CharArrayBuffer(256);
91 buffer.append(name);
92 buffer.append(": ");
93 formatTokens(buffer, tokens);
94 return BufferedHeader.create(buffer);
95 }
96
97 public static Header format(final String name, final String... tokens) {
98 Args.notBlank(name, "Header name");
99 if (tokens == null || tokens.length == 0) {
100 return null;
101 }
102 final CharArrayBufferrayBuffer.html#CharArrayBuffer">CharArrayBuffer buffer = new CharArrayBuffer(256);
103 buffer.append(name);
104 buffer.append(": ");
105 formatTokens(buffer, tokens);
106 return BufferedHeader.create(buffer);
107 }
108
109 private static final BitSet COMMA = Tokenizer.INIT_BITSET(',');
110
111 public static Set<String> parseTokens(final CharSequence src, final ParserCursor cursor) {
112 Args.notNull(src, "Source");
113 Args.notNull(cursor, "Cursor");
114 final Set<String> tokens = new LinkedHashSet<>();
115 while (!cursor.atEnd()) {
116 final int pos = cursor.getPos();
117 if (src.charAt(pos) == ',') {
118 cursor.updatePos(pos + 1);
119 }
120 final String token = Tokenizer.INSTANCE.parseToken(src, cursor, COMMA);
121 if (!TextUtils.isBlank(token)) {
122 tokens.add(token);
123 }
124 }
125 return tokens;
126 }
127
128 public static Set<String> parseTokens(final Header header) {
129 Args.notNull(header, "Header");
130 if (header instanceof FormattedHeader) {
131 final CharArrayBuffer buf = ((FormattedHeader) header).getBuffer();
132 final ParserCursorsage/ParserCursor.html#ParserCursor">ParserCursor cursor = new ParserCursor(0, buf.length());
133 cursor.updatePos(((FormattedHeader) header).getValuePos());
134 return parseTokens(buf, cursor);
135 }
136 final String value = header.getValue();
137 final ParserCursorsage/ParserCursor.html#ParserCursor">ParserCursor cursor = new ParserCursor(0, value.length());
138 return parseTokens(value, cursor);
139 }
140
141 public static void addContentTypeHeader(final HttpMessage message, final EntityDetails entity) {
142 if (entity != null && entity.getContentType() != null && !message.containsHeader(HttpHeaders.CONTENT_TYPE)) {
143 message.addHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, entity.getContentType()));
144 }
145 }
146
147 public static void addContentEncodingHeader(final HttpMessage message, final EntityDetails entity) {
148 if (entity != null && entity.getContentEncoding() != null && !message.containsHeader(HttpHeaders.CONTENT_ENCODING)) {
149 message.addHeader(new BasicHeader(HttpHeaders.CONTENT_ENCODING, entity.getContentEncoding()));
150 }
151 }
152
153 public static void addTrailerHeader(final HttpMessage message, final EntityDetails entity) {
154 if (entity != null && !message.containsHeader(HttpHeaders.TRAILER)) {
155 final Set<String> trailerNames = entity.getTrailerNames();
156 if (trailerNames != null && !trailerNames.isEmpty()) {
157 message.setHeader(MessageSupport.format(HttpHeaders.TRAILER, trailerNames));
158 }
159 }
160 }
161
162 public static Iterator<HeaderElement> iterate(final MessageHeaders headers, final String name) {
163 Args.notNull(headers, "Message headers");
164 Args.notBlank(name, "Header name");
165 return new BasicHeaderElementIterator(headers.headerIterator(name));
166 }
167
168 public static HeaderElement[] parse(final Header header) {
169 Args.notNull(header, "Headers");
170 final String value = header.getValue();
171 if (value == null) {
172 return new HeaderElement[] {};
173 }
174 final ParserCursorsage/ParserCursor.html#ParserCursor">ParserCursor cursor = new ParserCursor(0, value.length());
175 return BasicHeaderValueParser.INSTANCE.parseElements(value, cursor);
176 }
177
178
179
180
181 public static boolean canResponseHaveBody(final String method, final HttpResponse response) {
182 if (Method.HEAD.isSame(method)) {
183 return false;
184 }
185 final int status = response.getCode();
186 if (Method.CONNECT.isSame(method) && status == HttpStatus.SC_OK) {
187 return false;
188 }
189 return status >= HttpStatus.SC_SUCCESS
190 && status != HttpStatus.SC_NO_CONTENT
191 && status != HttpStatus.SC_NOT_MODIFIED;
192 }
193
194 }