Example #1
0
  /**
   * 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());
     }
   }
 }
Example #6
0
  /**
   * 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");
    }
  }
Example #8
0
  /**
   * 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;
    }
  }