use of org.alfresco.service.cmr.remoteconnector.RemoteConnectorResponse in project alfresco-remote-api by Alfresco.
the class LocalWebScriptConnectorServiceImpl method executeRequest.
/**
* Executes the specified request, and return the response
*/
public RemoteConnectorResponse executeRequest(RemoteConnectorRequest request) throws IOException, AuthenticationException, RemoteConnectorClientException, RemoteConnectorServerException {
// Convert the request object
RemoteConnectorRequestImpl requestImpl = (RemoteConnectorRequestImpl) request;
Request req = new Request(request.getMethod(), request.getURL());
req.setType(request.getContentType());
if (request.getRequestBody() != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
requestImpl.getRequestBody().writeRequest(baos);
req.setBody(baos.toByteArray());
}
// Log
if (logger.isInfoEnabled())
logger.info("Performing local " + request.getMethod() + " request to " + request.getURL());
// Capture the user details, as they may be changed during the request processing
Authentication fullAuth = AuthenticationUtil.getFullAuthentication();
String runAsUser = AuthenticationUtil.getRunAsUser();
// If they've specified Authentication details in the request, clear our security context
// and switch to that user, to avoid our context confusing the real request
Header authHeader = null;
Map<String, String> headers = new HashMap<String, String>();
for (Header header : request.getRequestHeaders()) {
if (header.getName().equals("Authorization")) {
authHeader = header;
}
headers.put(header.getName(), header.getValue());
}
if (authHeader != null) {
AuthenticationUtil.clearCurrentSecurityContext();
if (logger.isDebugEnabled())
logger.debug("HTTP Authorization found for the request, clearing security context, Auth is " + authHeader);
}
req.setHeaders(headers);
// Execute the request against the WebScript Test Framework
Response resp;
try {
resp = helper.sendRequest(req, -1);
} catch (Exception e) {
throw new AlfrescoRuntimeException("Problem requesting", e);
}
// Reset the user details, now we're done performing the request
AuthenticationUtil.setFullAuthentication(fullAuth);
if (runAsUser != null && !runAsUser.equals(fullAuth.getName())) {
AuthenticationUtil.setRunAsUser(runAsUser);
}
// Log
if (logger.isInfoEnabled())
logger.info("Response to request was " + resp.getStatus() + " - " + resp);
// Check the status for specific typed exceptions
if (resp.getStatus() == Status.STATUS_UNAUTHORIZED) {
throw new AuthenticationException("Not Authorized to access this resource");
}
if (resp.getStatus() == Status.STATUS_FORBIDDEN) {
throw new AuthenticationException("Forbidden to access this resource");
}
// Check for failures where we don't care about the response body
if (resp.getStatus() >= 500 && resp.getStatus() <= 599) {
throw new RemoteConnectorServerException(resp.getStatus(), "(not available)");
}
// Convert the response into our required format
String charset = null;
String contentType = resp.getContentType();
if (contentType != null && contentType.contains("charset=")) {
int splitAt = contentType.indexOf("charset=") + "charset=".length();
charset = contentType.substring(splitAt);
}
InputStream body = new ByteArrayInputStream(resp.getContentAsByteArray());
// TODO Can't easily get the list...
Header[] respHeaders = new Header[0];
RemoteConnectorResponse response = new RemoteConnectorResponseImpl(request, contentType, charset, resp.getStatus(), respHeaders, body);
// If it's a client error, let them know what went wrong
if (resp.getStatus() >= 400 && resp.getStatus() <= 499) {
throw new RemoteConnectorClientException(resp.getStatus(), "(not available)", response);
}
// Otherwise return the response for processing
return response;
}
use of org.alfresco.service.cmr.remoteconnector.RemoteConnectorResponse in project alfresco-repository by Alfresco.
the class RemoteConnectorServiceImpl method doExecuteJSONRequest.
public static JSONObject doExecuteJSONRequest(RemoteConnectorRequest request, RemoteConnectorService service) throws ParseException, IOException, AuthenticationException {
// Set as JSON
request.setContentType(MimetypeMap.MIMETYPE_JSON);
// Perform the request
RemoteConnectorResponse response = service.executeRequest(request);
// Parse this as JSON
JSONParser parser = new JSONParser();
String jsonText = response.getResponseBodyAsString();
Object json = parser.parse(jsonText);
// Check it's the right type and return
if (json instanceof JSONObject) {
return (JSONObject) json;
} else {
throw new ParseException(0, json);
}
}
use of org.alfresco.service.cmr.remoteconnector.RemoteConnectorResponse in project alfresco-repository by Alfresco.
the class RemoteConnectorServiceImpl method executeRequest.
/**
* Executes the specified request, and return the response
*/
public RemoteConnectorResponse executeRequest(RemoteConnectorRequest request) throws IOException, AuthenticationException, RemoteConnectorClientException, RemoteConnectorServerException {
RemoteConnectorRequestImpl reqImpl = (RemoteConnectorRequestImpl) request;
HttpMethodBase httpRequest = reqImpl.getMethodInstance();
// Attach the headers to the request
for (Header hdr : request.getRequestHeaders()) {
httpRequest.addRequestHeader(hdr);
}
// Attach the body, if possible
if (httpRequest instanceof EntityEnclosingMethod) {
if (request.getRequestBody() != null) {
((EntityEnclosingMethod) httpRequest).setRequestEntity(reqImpl.getRequestBody());
}
}
// Grab our thread local HttpClient instance
// Remember - we must then clean it up!
HttpClient httpClient = HttpClientHelper.getHttpClient();
// The url should already be vetted by the RemoteConnectorRequest
URL url = new URL(request.getURL());
// Use the appropriate Proxy Host if required
if (httpProxyHost != null && url.getProtocol().equals("http") && HttpClientHelper.requiresProxy(url.getHost())) {
httpClient.getHostConfiguration().setProxyHost(httpProxyHost);
if (logger.isDebugEnabled()) {
logger.debug(" - using HTTP proxy host for: " + url);
}
if (httpProxyCredentials != null) {
httpClient.getState().setProxyCredentials(httpAuthScope, httpProxyCredentials);
if (logger.isDebugEnabled()) {
logger.debug(" - using HTTP proxy credentials for proxy: " + httpProxyHost.getHostName());
}
}
} else if (httpsProxyHost != null && url.getProtocol().equals("https") && HttpClientHelper.requiresProxy(url.getHost())) {
httpClient.getHostConfiguration().setProxyHost(httpsProxyHost);
if (logger.isDebugEnabled()) {
logger.debug(" - using HTTPS proxy host for: " + url);
}
if (httpsProxyCredentials != null) {
httpClient.getState().setProxyCredentials(httpsAuthScope, httpsProxyCredentials);
if (logger.isDebugEnabled()) {
logger.debug(" - using HTTPS proxy credentials for proxy: " + httpsProxyHost.getHostName());
}
}
} else {
// host should not be proxied remove any configured proxies
httpClient.getHostConfiguration().setProxyHost(null);
httpClient.getState().clearProxyCredentials();
}
// Log what we're doing
if (logger.isDebugEnabled()) {
logger.debug("Performing " + request.getMethod() + " request to " + request.getURL());
for (Header hdr : request.getRequestHeaders()) {
logger.debug("Header: " + hdr);
}
Object requestBody = null;
if (request != null) {
requestBody = request.getRequestBody();
}
if (requestBody != null && requestBody instanceof StringRequestEntity) {
StringRequestEntity re = (StringRequestEntity) request.getRequestBody();
// remove credentials from logs, such as "username":"John.Doe@test.com" and "password":"123456abc"
// the strings can include double quotes, therefore we should check for proper end, it can be either
// a comma "," or "}"
// REPO-1471
// returns a new string, should be safe to modify
String payload = re.getContent();
String usernameString = "\"username\"";
String passwordString = "\"password\"";
String hiddenString = "\"<hidden>\"";
List<String> matches = new LinkedList<>();
Matcher m = Pattern.compile(usernameString + ":\"(.+)\",|" + usernameString + ":\"(.+)\"}|" + passwordString + ":\"(.+)\",|" + passwordString + ":\"(.+)\"}").matcher(payload);
while (m.find()) {
matches.add(m.group());
}
for (String match : matches) {
if (match.contains(usernameString)) {
payload = payload.replace(match.substring(// 1 is semicolon
match.indexOf(usernameString) + usernameString.length() + 1, // 1 is a double quote
match.lastIndexOf("\"") + 1), hiddenString);
} else if (match.contains(passwordString)) {
payload = payload.replace(match.substring(// 1 is semicolon
match.indexOf(passwordString) + passwordString.length() + 1, // 1 is a double quote
match.lastIndexOf("\"") + 1), hiddenString);
}
}
logger.debug("Payload (string): " + payload);
} else if (requestBody != null && requestBody instanceof ByteArrayRequestEntity) {
ByteArrayRequestEntity re = (ByteArrayRequestEntity) request.getRequestBody();
logger.debug("Payload (byte array): " + re.getContent().toString());
} else {
logger.debug("Payload is not of a readable type.");
}
}
// Perform the request, and wrap the response
int status = -1;
String statusText = null;
RemoteConnectorResponse response = null;
try {
status = httpClient.executeMethod(httpRequest);
statusText = httpRequest.getStatusText();
Header[] responseHdrs = httpRequest.getResponseHeaders();
Header responseContentTypeH = httpRequest.getResponseHeader(RemoteConnectorRequestImpl.HEADER_CONTENT_TYPE);
String responseCharSet = httpRequest.getResponseCharSet();
String responseContentType = (responseContentTypeH != null ? responseContentTypeH.getValue() : null);
if (logger.isDebugEnabled()) {
logger.debug("response url=" + request.getURL() + ", length =" + httpRequest.getResponseContentLength() + ", responceContentType " + responseContentType + ", statusText =" + statusText);
}
// If we can close immediately, it makes cleanup simpler and fool-proof
if (httpRequest.getResponseContentLength() > MAX_BUFFER_RESPONSE_SIZE || httpRequest.getResponseContentLength() == -1) {
if (logger.isTraceEnabled()) {
logger.trace("large response (or don't know length) url=" + request.getURL());
}
// Need to wrap the InputStream in something that'll close
InputStream wrappedStream = new HttpClientReleasingInputStream(httpRequest);
httpRequest = null;
// Now build the response
response = new RemoteConnectorResponseImpl(request, responseContentType, responseCharSet, status, responseHdrs, wrappedStream);
} else {
if (logger.isTraceEnabled()) {
logger.debug("small response for url=" + request.getURL());
}
// Fairly small response, just keep the bytes and make life simple
response = new RemoteConnectorResponseImpl(request, responseContentType, responseCharSet, status, responseHdrs, httpRequest.getResponseBody());
// Now we have the bytes, we can close the HttpClient resources
httpRequest.releaseConnection();
httpRequest = null;
}
} finally {
// This is important because we use a thread local HttpClient instance
if (httpRequest != null) {
httpRequest.releaseConnection();
httpRequest = null;
}
}
// Log the response
if (logger.isDebugEnabled())
logger.debug("Response was " + status + " " + statusText);
// Decide if we should throw an exception
if (status >= 300) {
// Tidy if needed
if (httpRequest != null)
httpRequest.releaseConnection();
// Specific exceptions
if (status == Status.STATUS_FORBIDDEN || status == Status.STATUS_UNAUTHORIZED) {
// TODO Need to get error message into the AuthenticationException
throw new AuthenticationException(statusText);
}
// Server side exceptions
if (status >= 500 && status <= 599) {
logger.error("executeRequest: remote connector server exception: [" + status + "] " + statusText);
throw new RemoteConnectorServerException(status, statusText);
}
if (status == Status.STATUS_PRECONDITION_FAILED) {
logger.error("executeRequest: remote connector client exception: [" + status + "] " + statusText);
throw new RemoteConnectorClientException(status, statusText, response);
} else {
// Client request exceptions
if (httpRequest != null) {
// Response wasn't too big and is available, supply it
logger.error("executeRequest: remote connector client exception: [" + status + "] " + statusText);
throw new RemoteConnectorClientException(status, statusText, response);
} else {
// Response was too large, report without it
logger.error("executeRequest: remote connector client exception: [" + status + "] " + statusText);
throw new RemoteConnectorClientException(status, statusText, null);
}
}
}
// So, return our created response
return response;
}
Aggregations