// clear out any connection-related information so that it's not stale from previous use of this thread.
RequestInfo.clear(url);
// link the object up now, before we make the request, so that if we get cut off (ie: favicon.ico request and browser shuts down)
// we still have the attempt associated, even if we never got a response
HarEntry entry = new HarEntry(harPageRef);
entry.setRequest(new HarRequest(method.getMethod(), url, method.getProtocolVersion().getProtocol()));
entry.setResponse(new HarResponse(-999, "NO RESPONSE", method.getProtocolVersion().getProtocol()));
if (this.har != null && harPageRef != null) {
har.getLog().addEntry(entry);
}
String query = method.getURI().getQuery();
if (query != null) {
MultiMap<String> params = new MultiMap<String>();
UrlEncoded.decodeTo(query, params, "UTF-8");
for (String k : params.keySet()) {
for (Object v : params.getValues(k)) {
entry.getRequest().getQueryString().add(new HarNameValuePair(k, (String) v));
}
}
}
String errorMessage = null;
HttpResponse response = null;
BasicHttpContext ctx = new BasicHttpContext();
ActiveRequest activeRequest = new ActiveRequest(method, ctx, entry.getStartedDateTime());
synchronized (activeRequests) {
activeRequests.add(activeRequest);
}
// for dealing with automatic authentication
if (authType == AuthType.NTLM) {
// todo: not supported yet
//ctx.setAttribute("preemptive-auth", new NTLMScheme(new JCIFSEngine()));
} else if (authType == AuthType.BASIC) {
ctx.setAttribute("preemptive-auth", new BasicScheme());
}
StatusLine statusLine = null;
try {
// set the User-Agent if it's not already set
if (method.getHeaders("User-Agent").length == 0) {
method.addHeader("User-Agent", "BrowserMob VU/1.0");
}
// was the request mocked out?
if (mockResponseCode != -1) {
statusCode = mockResponseCode;
// TODO: HACKY!!
callback.handleHeaders(new Header[]{
new Header(){
@Override
public String getName() {
return "Content-Type";
}
@Override
public String getValue() {
return "text/plain";
}
@Override
public HeaderElement[] getElements() throws ParseException {
return new HeaderElement[0];
}
}
});
} else {
response = httpClient.execute(method, ctx);
statusLine = response.getStatusLine();
statusCode = statusLine.getStatusCode();
if (callback != null) {
callback.handleStatusLine(statusLine);
callback.handleHeaders(response.getAllHeaders());
}
if (response.getEntity() != null) {
is = response.getEntity().getContent();
}
// check for null (resp 204 can cause HttpClient to return null, which is what Google does with http://clients1.google.com/generate_204)
if (is != null) {
// deal with GZIP content!
if (decompress) {
Header contentEncodingHeader = response.getFirstHeader("Content-Encoding");
if (contentEncodingHeader != null && "gzip".equalsIgnoreCase(contentEncodingHeader.getValue())) {
is = new GZIPInputStream(is);
}
}
bytes = copyWithStats(is, os);
}
}
} catch (Exception e) {
errorMessage = e.toString();
if (callback != null) {
callback.reportError(e);
}
// only log it if we're not shutdown (otherwise, errors that happen during a shutdown can likely be ignored)
if (!shutdown) {
LOG.info(String.format("%s when requesting %s", errorMessage, url));
}
} finally {
// the request is done, get it out of here
synchronized (activeRequests) {
activeRequests.remove(activeRequest);
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
// this is OK to ignore
}
}
}
// record the response as ended
RequestInfo.get().finish();
// set the start time and other timings
entry.setStartedDateTime(RequestInfo.get().getStart());
entry.setTimings(RequestInfo.get().getTimings());
entry.setServerIPAddress(RequestInfo.get().getResolvedAddress());
entry.setTime(RequestInfo.get().getTotalTime());
// todo: where you store this in HAR?
// obj.setErrorMessage(errorMessage);
entry.getResponse().setBodySize(bytes);
entry.getResponse().getContent().setSize(bytes);
entry.getResponse().setStatus(statusCode);
if (statusLine != null) {
entry.getResponse().setStatusText(statusLine.getReasonPhrase());
}
boolean urlEncoded = false;
if (captureHeaders || captureContent) {
for (Header header : method.getAllHeaders()) {
if (header.getValue() != null && header.getValue().startsWith(URLEncodedUtils.CONTENT_TYPE)) {
urlEncoded = true;
}
entry.getRequest().getHeaders().add(new HarNameValuePair(header.getName(), header.getValue()));
}
if (response != null) {
for (Header header : response.getAllHeaders()) {
entry.getResponse().getHeaders().add(new HarNameValuePair(header.getName(), header.getValue()));
}
}
}
/* TODO
if (captureContent) {
// can we understand the POST data at all?
if (method instanceof HttpEntityEnclosingRequestBase && req.getCopy() != null) {
HttpEntityEnclosingRequestBase enclosingReq = (HttpEntityEnclosingRequestBase) method;
HttpEntity entity = enclosingReq.getEntity();
if (urlEncoded || URLEncodedUtils.isEncoded(entity)) {
try {
final String content = new String(req.getCopy().toByteArray(), "UTF-8");
if (content != null && content.length() > 0) {
List<NameValuePair> result = new ArrayList<NameValuePair>();
URLEncodedUtils.parse(result, new Scanner(content), null);
HashMap<String, String[]> params = new HashMap<String, String[]>();
obj.setPostParams(params);
for (NameValuePair nvp : result) {
String[] values = params.get(nvp.getName());
String value = nvp.getValue();
if (value == null) {
value = "";
}
if (values == null) {
values = new String[]{value};
params.put(nvp.getName(), values);
} else {
String[] oldValues = values;
values = new String[oldValues.length + 1];
System.arraycopy(oldValues, 0, values, 0, oldValues.length);
values[oldValues.length] = value;
params.put(nvp.getName(), values);
}
}
}
} catch (Exception e) {
LOG.info("Unexpected problem when parsing input copy", e);
}
}
}
}
*/
//capture request cookies
List<Cookie> cookies = (List<Cookie>) ctx.getAttribute("browsermob.http.request.cookies");
if (cookies != null) {
for (Cookie c : cookies) {
HarCookie hc = toHarCookie(c);
entry.getRequest().getCookies().add(hc);
}
}
String contentType = null;
if (response != null) {
try {
Header contentTypeHdr = response.getFirstHeader("Content-Type");
if (contentTypeHdr != null) {
contentType = contentTypeHdr.getValue();
NameValuePair nvp = contentTypeHdr.getElements()[0].getParameterByName("charset");
if (nvp != null) {
charSet = nvp.getValue();
}
}
if (os instanceof ByteArrayOutputStream) {
responseBody = ((ByteArrayOutputStream) os).toString(charSet);
if (verificationText != null) {
contentMatched = responseBody.contains(verificationText);
}
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
//capture response cookies
cookies = (List<Cookie>) ctx.getAttribute("browsermob.http.response.cookies");
if (cookies != null) {
for (Cookie c : cookies) {
HarCookie hc = toHarCookie(c);
entry.getResponse().getCookies().add(hc);
}
}
}
if (contentType != null) {
entry.getResponse().getContent().setMimeType(contentType);
}
// checking to see if the client is being redirected
boolean isRedirect = false;