I am using HP-ALM 12.01 which seems to be stock full of issues. I cannot update to another version at this time.
I am trying to get access to the rest api to upload test results automatically from JUnit. I am using the infrastructure shown here (example application -> Infrastructure). From which, my connection scripts passes base64 encoded login info to authentication-point/authenticate and I am retrieving a valid LWSSO cookie. However, when I use this cookie to connect to rest/site-session to receive my QCSession cookies, I am receiving a 411 Length Required error. I have attempted to hard code the Content-Length into the headers as shown here
public void GetQCSession(){
String qcsessionurl = con.buildUrl("rest/site-session");
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Content-Type", "application/xml");
requestHeaders.put("Accept", "application/xml");
requestHeaders.put("Content-Length", "0");
try {
Response resp = con.httpPost(qcsessionurl, null, requestHeaders);
con.updateCookies(resp);
System.out.println(resp.getStatusCode());
} catch (Exception e) {
e.printStackTrace();
}
}
This did not work. I have also tried modifying the infrastructure to automatically inject the Content-Length header, as shown here
private void prepareHttpRequest(
HttpURLConnection con,
Map<String, String> headers,
byte[] bytes,
String cookieString) throws IOException {
String contentType = null;
//attach cookie information if such exists
if ((cookieString != null) && !cookieString.isEmpty()) {
con.setRequestProperty("Cookie", cookieString);
}
//send data from headers
if (headers != null) {
//Skip the content-type header - should only be sent
//if you actually have any content to send. see below.
contentType = headers.remove("Content-Type");
Iterator<Entry<String, String>>
headersIterator = headers.entrySet().iterator();
while (headersIterator.hasNext()) {
Entry<String, String> header = headersIterator.next();
con.setRequestProperty(header.getKey(), header.getValue());
}
}
// If there's data to attach to the request, it's handled here.
// Note that if data exists, we take into account previously removed
// content-type.
if ((bytes != null) && (bytes.length > 0)) {
con.setDoOutput(true);
//warning: if you add content-type header then you MUST send
// information or receive error.
//so only do so if you're writing information...
if (contentType != null) {
con.setRequestProperty("Content-Type", contentType);
}
OutputStream out = con.getOutputStream();
out.write(bytes);
out.flush();
out.close();
con.setRequestProperty("Content-Length", Integer.toString(bytes.length));
} else {
con.setRequestProperty("Content-Length", "0");
}
}
which also does not work. note that setRequestProperty simply does a .set(key, value) to a MessageHeader
Has anyone dealt with this issue before or know how to resolve it?
Note that none of these issues occurs with postman. All 4 cookies are generated after a site-session post.
The issue is that Java's HttpURLConnection ignores certain properties when manually set. One of these is Content-Length. This is because it automatically sets it itself. However, if you're not sending any data it simply doesn't send it, which ALM is not accepting due its outdated http protocols, as it expects to receive a Content-Length of 0.
To work around this you have to tell java to allow restrticted headers. This is done by running
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
for more information, look here Why does Content-Length HTTP header field use a value other than the one given in Java code?