4 * License : The MIT License
5 * Copyright(c) 2008 olyutorskii
8 package jp.sourceforge.jindolf;
10 import java.io.IOException;
11 import java.net.HttpURLConnection;
12 import java.net.URLConnection;
13 import java.text.NumberFormat;
14 import java.util.regex.Matcher;
15 import java.util.regex.Pattern;
20 public final class HttpUtils{
22 private static final String TOKEN_REGEX =
23 "([^\\(\\)<>@,;:\\\"/\\[\\]\\?=\\{\\}\\p{Blank}\\p{Cntrl}]+)";
24 private static final String MTYPE_REGEX =
26 + TOKEN_REGEX + "/" + TOKEN_REGEX
28 private static final String PARAM_REGEX =
29 "[\\p{Blank}]*;[\\p{Blank}]*"
31 + "[\\p{Blank}]*=[\\p{Blank}]*"
32 + "(" + TOKEN_REGEX + "|" + "(\"[^\\p{Cntrl}\\\"]*\")" + ")";
33 private static final Pattern MTYPE_PATTERN = Pattern.compile(MTYPE_REGEX);
34 private static final Pattern ATTR_PATTERN = Pattern.compile(PARAM_REGEX);
36 private static final NumberFormat THROUGHPUT_FORMAT;
37 private static final NumberFormat SIZE_FORMAT;
40 THROUGHPUT_FORMAT = NumberFormat.getInstance();
41 THROUGHPUT_FORMAT.setMaximumFractionDigits(1);
42 THROUGHPUT_FORMAT.setMinimumFractionDigits(1);
43 THROUGHPUT_FORMAT.setGroupingUsed(true);
44 SIZE_FORMAT = NumberFormat.getInstance();
45 SIZE_FORMAT.setGroupingUsed(true);
55 throw new AssertionError();
60 * ネットワークのスループット報告用文字列を生成する。
61 * @param size 転送サイズ(バイト数)
62 * @param nano 所要時間(ナノ秒)
65 public static String throughput(long size, long nano){
66 if(size <= 0 || nano <= 0) return "";
68 double sec = ((double)nano) / (1000.0 * 1000.0 * 1000.0);
69 double rate = ((double)size) / sec;
81 String result = SIZE_FORMAT.format(size) + "Bytes "
82 + THROUGHPUT_FORMAT.format(rate) + unit
88 * HTTPセッションの各種結果を文字列化する。
89 * @param conn HTTPコネクション
91 * @param nano 転送に要したナノ秒
94 public static String formatHttpStat(HttpURLConnection conn,
97 String method = conn.getRequestMethod();
98 String url = conn.getURL().toString();
102 responseCode = String.valueOf(conn.getResponseCode());
103 }catch(IOException e){
104 responseCode = "???";
107 String responseMessage;
109 responseMessage = conn.getResponseMessage();
110 }catch(IOException e){
111 responseMessage = "???";
114 String throughput = throughput(size, nano);
116 String message = method
118 + " [" + responseCode
119 + " " + responseMessage + "]"
129 public static String getUserAgentName(){
130 StringBuilder result = new StringBuilder();
131 result.append(Jindolf.TITLE).append("/").append(Jindolf.VERSION);
133 StringBuilder rawComment = new StringBuilder();
134 if(EnvInfo.OS_NAME != null){
135 if(rawComment.length() > 0) rawComment.append("; ");
136 rawComment.append(EnvInfo.OS_NAME);
138 if(EnvInfo.OS_VERSION != null){
139 if(rawComment.length() > 0) rawComment.append("; ");
140 rawComment.append(EnvInfo.OS_VERSION);
142 if(EnvInfo.OS_ARCH != null){
143 if(rawComment.length() > 0) rawComment.append("; ");
144 rawComment.append(EnvInfo.OS_ARCH);
146 if(EnvInfo.JAVA_VENDOR != null){
147 if(rawComment.length() > 0) rawComment.append("; ");
148 rawComment.append(EnvInfo.JAVA_VENDOR);
150 if(EnvInfo.JAVA_VERSION != null){
151 if(rawComment.length() > 0) rawComment.append("; ");
152 rawComment.append(EnvInfo.JAVA_VERSION);
155 CharSequence comment = escapeHttpComment(rawComment);
156 if(comment != null) result.append(" ").append(comment);
158 return result.toString();
162 * 与えられた文字列からHTTPコメントを生成する。
163 * @param comment コメント
166 public static String escapeHttpComment(CharSequence comment){
167 if(comment == null) return null;
168 if(comment.length() <= 0) return null;
170 String result = comment.toString();
171 result = result.replaceAll("\\(", "\\\\(");
172 result = result.replaceAll("\\)", "\\\\)");
173 result = result.replaceAll("[\\u0000-\\u001f]", "?");
174 result = result.replaceAll("[\\u007f-\\uffff]", "?");
175 result = "(" + result + ")";
181 * HTTP応答からCharsetを取得する。
182 * @param connection HTTP接続
185 public static String getHTMLCharset(URLConnection connection){
186 String contentType = connection.getContentType();
187 if(contentType == null) return null;
188 return getHTMLCharset(contentType);
192 * ContentTypeからCharsetを取得する。
193 * @param contentType ContentType
196 public static String getHTMLCharset(String contentType){
201 matcher = MTYPE_PATTERN.matcher(contentType);
202 matchResult = matcher.lookingAt();
203 if(!matchResult) return null;
204 lastPos = matcher.end();
205 String type = matcher.group(1);
206 String subtype = matcher.group(2);
208 if(!type.equalsIgnoreCase("text")) return null;
209 if(!subtype.equalsIgnoreCase("html")) return null;
211 matcher.usePattern(ATTR_PATTERN);
213 String charset = null;
215 matchResult = matcher.find(lastPos);
216 if(!matchResult) break;
217 lastPos = matcher.end();
218 String attribute = matcher.group(1);
219 String value = matcher.group(2);
220 if(attribute.equalsIgnoreCase("charset")) charset = value;