/** * Allows filtering before its handling by the target Restlet. Does nothing by default. * * @param request The request to filter. * @param response The response to filter. * @return The continuation status. */ @Override public int beforeHandle(Request request, Response response) { // Check if encoding of the request entity is needed if (isEncodingRequest() && canEncode(request.getEntity())) { request.setEntity(encode(request.getClientInfo(), request.getEntity())); } return CONTINUE; }
@Override public void init(Context context, Request request, Response response) { // System.out.println("init" + request + " " + response); // System.out.println("Content-Type: " + // request.getEntity().getMediaType()); if (request.getMethod().compareTo(Method.GET) == 0) { Representation entity = request.getEntity(); System.out.println( "Entity " + entity + " Content-Type: " + request.getEntity().getMediaType()); request.setEntity(new StringRepresentation("")); } super.init(context, request, response); }
@Override protected int beforeHandle(Request request, Response response) { Cookie cookie = request.getCookies().getFirst("Credentials"); if (cookie != null) { // Extract the challenge response from the cookie String[] credentials = cookie.getValue().split("="); if (credentials.length == 2) { String identifier = credentials[0]; String secret = credentials[1]; request.setChallengeResponse( new ChallengeResponse(ChallengeScheme.HTTP_COOKIE, identifier, secret)); } } else if (Method.POST.equals(request.getMethod()) && request.getResourceRef().getQueryAsForm().getFirst("login") != null) { // Intercepting a login form Form credentials = new Form(request.getEntity()); String identifier = credentials.getFirstValue("identifier"); String secret = credentials.getFirstValue("secret"); request.setChallengeResponse( new ChallengeResponse(ChallengeScheme.HTTP_COOKIE, identifier, secret)); // Continue call processing to return the target representation if // authentication is successful or a new login page request.setMethod(Method.GET); } return super.beforeHandle(request, response); }
@Override protected void addHeaders(Series<Header> headers) { Request request = getMessage().getRequest(); addGeneralHeaders(headers); addEntityHeaders(request.getEntity(), headers); // NOTE: This must stay at the end because the AWS challenge // scheme requires access to all HTTP headers addRequestHeaders(headers); }
/** * Decodes form parameters that are sent double encoded by performing one decode step on their * values, if their restlet framework decoded value starts with an "%". * * @param request a restlet request * @throws IOException did not occur during tests but may. * @throws IllegalArgumentException if an Encode representation is received. */ void decodeFormParamsIfDoubleEncoded(Request request) throws IOException { Representation r = request.getEntity(); if (r instanceof EncodeRepresentation) throw new IllegalArgumentException( "Received an Encode representation." + " This filter must be after the Encoder filter. please check your filter chain order."); if (!(r instanceof EmptyRepresentation)) { ContentType c = new ContentType(r); if (MediaType.APPLICATION_WWW_FORM.equals(c.getMediaType(), true)) { Form form = new Form(r); Form newform = new Form(r); Map<String, String> valuesMap = form.getValuesMap(); for (Map.Entry<String, String> e : valuesMap.entrySet()) { if (DBG) ThreadLocalStopwatch.now("" + e.getKey() + " - " + e.getValue()); String shouldBeDecodedValue = e.getValue(); if (shouldBeDecodedValue.startsWith("%")) { shouldBeDecodedValue = URLDecoder.decode(e.getValue(), DECODER_CHAR_SET); totalDecodings.incrementAndGet(); if (DBG) { ThreadLocalStopwatch.now("DECODED " + request.getResourceRef()); ThreadLocalStopwatch.now( "DECODED " + totalDecodings.get() + " : " + e.getKey() + " - " + shouldBeDecodedValue); } } newform.add(e.getKey(), shouldBeDecodedValue); } // we must always set the entity, because above getEntitiy call causes // NPEs later if repeated by the framework. request.setEntity(newform.encode(), c.getMediaType()); } } }
/** * Handle the call and follow redirection for safe methods. * * @param request The request to send. * @param response The response to update. * @param references The references that caused a redirection to prevent infinite loops. * @param retryAttempt The number of remaining attempts. * @param next The next handler handling the call. */ private void handle( Request request, Response response, List<Reference> references, int retryAttempt, Uniform next) { if (next != null) { // Actually handle the call next.handle(request, response); // Check for redirections if (isFollowingRedirects() && response.getStatus().isRedirection() && (response.getLocationRef() != null)) { boolean doRedirection = false; if (request.getMethod().isSafe()) { doRedirection = true; } else { if (Status.REDIRECTION_SEE_OTHER.equals(response.getStatus())) { // The user agent is redirected using the GET method request.setMethod(Method.GET); request.setEntity(null); doRedirection = true; } else if (Status.REDIRECTION_USE_PROXY.equals(response.getStatus())) { doRedirection = true; } } if (doRedirection) { Reference newTargetRef = response.getLocationRef(); if ((references != null) && references.contains(newTargetRef)) { getLogger().warning("Infinite redirection loop detected with URI: " + newTargetRef); } else if (request.getEntity() != null && !request.isEntityAvailable()) { getLogger() .warning( "Unable to follow the redirection because the request entity isn't available anymore."); } else { if (references == null) { references = new ArrayList<Reference>(); } // Add to the list of redirection reference // to prevent infinite loops references.add(request.getResourceRef()); request.setResourceRef(newTargetRef); handle(request, response, references, 0, next); } } } else if (isRetryOnError() && response.getStatus().isRecoverableError() && request.getMethod().isIdempotent() && (retryAttempt < getRetryAttempts()) && ((request.getEntity() == null) || request.getEntity().isAvailable())) { getLogger() .log( Level.INFO, "A recoverable error was detected (" + response.getStatus().getCode() + "), attempting again in " + getRetryDelay() + " ms."); // Wait before attempting again if (getRetryDelay() > 0) { try { Thread.sleep(getRetryDelay()); } catch (InterruptedException e) { getLogger().log(Level.FINE, "Retry delay sleep was interrupted", e); } } // Retry the call handle(request, response, references, ++retryAttempt, next); } } }
/** * Handles a call. * * @param request The request to handle. * @param response The response to update. */ @Override public void handle(Request request, Response response) { Connection connection = null; if (request.getMethod().equals(Method.POST)) { try { // Parse the JDBC URI String connectionURI = request.getResourceRef().toString(); // Parse the request to extract necessary info DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document requestDoc = docBuilder.parse(new InputSource(request.getEntity().getReader())); Element rootElt = (Element) requestDoc.getElementsByTagName("request").item(0); Element headerElt = (Element) rootElt.getElementsByTagName("header").item(0); Element connectionElt = (Element) headerElt.getElementsByTagName("connection").item(0); // Read the connection pooling setting Node usePoolingNode = connectionElt.getElementsByTagName("usePooling").item(0); boolean usePooling = usePoolingNode.getTextContent().equals("true") ? true : false; // Read the paging setting Node startNode = headerElt.getElementsByTagName("start").item(0); int start = startNode != null && startNode.getTextContent().trim().length() > 0 ? Integer.parseInt(startNode.getTextContent()) : 0; Node limitNode = headerElt.getElementsByTagName("limit").item(0); int limit = limitNode != null && limitNode.getTextContent().trim().length() > 0 ? Integer.parseInt(limitNode.getTextContent()) : -1; // Read the connection properties NodeList propertyNodes = connectionElt.getElementsByTagName("property"); Node propertyNode = null; Properties properties = null; String name = null; String value = null; for (int i = 0; i < propertyNodes.getLength(); i++) { propertyNode = propertyNodes.item(i); if (properties == null) { properties = new Properties(); } name = propertyNode.getAttributes().getNamedItem("name").getTextContent(); value = propertyNode.getTextContent(); properties.setProperty(name, value); } Node returnGeneratedKeysNode = headerElt.getElementsByTagName("returnGeneratedKeys").item(0); boolean returnGeneratedKeys = returnGeneratedKeysNode.getTextContent().equals("true") ? true : false; // Read the SQL body and get the list of sql statements Element bodyElt = (Element) rootElt.getElementsByTagName("body").item(0); NodeList statementNodes = bodyElt.getElementsByTagName("statement"); List<String> sqlRequests = new ArrayList<String>(); for (int i = 0; i < statementNodes.getLength(); i++) { String sqlRequest = statementNodes.item(i).getTextContent(); sqlRequests.add(sqlRequest); } // Execute the List of SQL requests connection = getConnection(connectionURI, properties, usePooling); JdbcResult result = handleSqlRequests(connection, returnGeneratedKeys, sqlRequests); response.setEntity(new RowSetRepresentation(result, start, limit)); } catch (SQLException se) { getLogger().log(Level.WARNING, "Error while processing the SQL request", se); response.setStatus(Status.SERVER_ERROR_INTERNAL, se); } catch (ParserConfigurationException pce) { getLogger().log(Level.WARNING, "Error with XML parser configuration", pce); response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, pce); } catch (SAXException se) { getLogger().log(Level.WARNING, "Error while parsing the XML document", se); response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, se); } catch (IOException ioe) { getLogger().log(Level.WARNING, "Input/Output exception", ioe); response.setStatus(Status.SERVER_ERROR_INTERNAL, ioe); } } else { throw new IllegalArgumentException("Only the POST method is supported"); } }
/** * Handles a PUT call. * * @param request The request to answer. * @param response The response to update. * @param file The Zip archive file. * @param entryName The Zip archive entry name. */ protected void handlePut(Request request, Response response, File file, String entryName) { boolean zipExists = file.exists(); ZipOutputStream zipOut = null; if ("".equals(entryName) && request.getEntity() != null && request.getEntity().getDisposition() != null) { entryName = request.getEntity().getDisposition().getFilename(); } if (entryName == null) { response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "Must specify an entry name."); return; } // boolean canAppend = true; boolean canAppend = !zipExists; boolean isDirectory = entryName.endsWith("/"); boolean wrongReplace = false; try { if (zipExists) { ZipFile zipFile = new ZipFile(file); // Already exists ? canAppend &= null == zipFile.getEntry(entryName); // Directory with the same name ? if (isDirectory) { wrongReplace = null != zipFile.getEntry(entryName.substring(0, entryName.length() - 1)); } else { wrongReplace = null != zipFile.getEntry(entryName + "/"); } canAppend &= !wrongReplace; zipFile.close(); } Representation entity; if (isDirectory) { entity = null; } else { entity = request.getEntity(); } if (canAppend) { try { // zipOut = new ZipOutputStream(new BufferedOutputStream(new // FileOutputStream(file, true))); zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file))); writeEntityStream(entity, zipOut, entryName); zipOut.close(); } catch (Exception e) { response.setStatus(Status.SERVER_ERROR_INTERNAL, e); return; } finally { if (zipOut != null) zipOut.close(); } response.setStatus(Status.SUCCESS_CREATED); } else { if (wrongReplace) { response.setStatus( Status.CLIENT_ERROR_BAD_REQUEST, "Directory cannot be replace by a file or file by a directory."); } else { File writeTo = null; ZipFile zipFile = null; try { writeTo = File.createTempFile("restlet_zip_", "zip"); zipFile = new ZipFile(file); zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(writeTo))); Enumeration<? extends ZipEntry> entries = zipFile.entries(); boolean replaced = false; while (entries.hasMoreElements()) { ZipEntry e = entries.nextElement(); if (!replaced && entryName.equals(e.getName())) { writeEntityStream(entity, zipOut, entryName); replaced = true; } else { zipOut.putNextEntry(e); BioUtils.copy(new BufferedInputStream(zipFile.getInputStream(e)), zipOut); zipOut.closeEntry(); } } if (!replaced) { writeEntityStream(entity, zipOut, entryName); } zipFile.close(); zipOut.close(); } finally { try { if (zipFile != null) zipFile.close(); } finally { if (zipOut != null) zipOut.close(); } } if (!(BioUtils.delete(file) && writeTo.renameTo(file))) { if (!file.exists()) file.createNewFile(); FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(writeTo); fos = new FileOutputStream(file); // ByteUtils.write(fis.getChannel(), // fos.getChannel()); BioUtils.copy(fis, fos); response.setStatus(Status.SUCCESS_OK); } finally { try { if (fis != null) fis.close(); } finally { if (fos != null) fos.close(); } } } else { response.setStatus(Status.SUCCESS_OK); } } } } catch (Exception e) { response.setStatus(Status.SERVER_ERROR_INTERNAL, e); return; } }