Exemple #1
0
  protected void respondWithToken(LockToken tok, Request request, Response response) {
    response.setStatus(Status.SC_OK);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    XmlWriter writer = new XmlWriter(out);
    writer.writeXMLHeader();
    String d = WebDavProtocol.DAV_PREFIX;
    writer.open(d + ":prop  xmlns:" + d + "=\"DAV:\"");
    writer.newLine();
    writer.open(d + ":lockdiscovery");
    writer.newLine();
    writer.open(d + ":activelock");
    writer.newLine();
    lockWriterHelper.appendType(writer, tok.info.type);
    lockWriterHelper.appendScope(writer, tok.info.scope);
    lockWriterHelper.appendDepth(writer, tok.info.depth);
    lockWriterHelper.appendOwner(writer, tok.info.lockedByUser);
    lockWriterHelper.appendTimeout(writer, tok.timeout.getSeconds());
    lockWriterHelper.appendTokenId(writer, tok.tokenId);
    String url = PropFindPropertyBuilder.fixUrlForWindows(request.getAbsoluteUrl());
    lockWriterHelper.appendRoot(writer, url);
    writer.close(d + ":activelock");
    writer.close(d + ":lockdiscovery");
    writer.close(d + ":prop");
    writer.flush();

    LogUtils.debug(log, "lock response: ", out);
    response.setEntity(new ByteArrayEntity(out.toByteArray()));
    //        response.close();

  }
 @Override
 public void processExistingResource(
     HttpManager manager, Request request, Response response, Resource resource)
     throws NotAuthorizedException, BadRequestException, ConflictException {
   try {
     org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
     // Prevent possibily of malicious clients using remote the parser to load remote resources
     builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
     org.jdom.Document doc = builder.build(request.getInputStream());
     String reportName = doc.getRootElement().getName();
     Report r = reports.get(reportName);
     if (r == null) {
       log.error("report not known: " + reportName);
       throw new BadRequestException(resource);
     } else {
       log.info("process report: " + reportName + " with : " + r.getClass());
       String xml = r.process(request.getHostHeader(), request.getAbsolutePath(), resource, doc);
       if (log.isTraceEnabled()) {
         log.trace("Report XML:\n" + xml);
       }
       response.setStatus(Response.Status.SC_MULTI_STATUS);
       response.setContentTypeHeader("text/xml");
       response.setEntity(new ByteArrayEntity(xml.getBytes("UTF-8")));
     }
   } catch (JDOMException ex) {
     java.util.logging.Logger.getLogger(ReportHandler.class.getName()).log(Level.SEVERE, null, ex);
   } catch (ReadingException ex) {
     throw new RuntimeException(ex);
   } catch (WritingException ex) {
     throw new RuntimeException(ex);
   } catch (IOException ex) {
     throw new RuntimeException(ex);
   }
 }
 @Override
 public void respondWithOptions(
     Resource resource, Response response, Request request, List<String> methodsAllowed) {
   setRespondCommonHeaders(response, resource, Status.SC_OK, request.getAuthorization());
   response.setAllowHeader(methodsAllowed);
   response.setContentLengthHeader((long) 0);
 }
 @Override
 public void respondHead(Resource resource, Response response, Request request) {
   // setRespondContentCommonHeaders(response, resource, Response.Status.SC_NO_CONTENT,
   // request.getAuthorization());
   setRespondContentCommonHeaders(
       response, resource, Response.Status.SC_OK, request.getAuthorization());
   if (!(resource instanceof GetableResource)) {
     return;
   }
   GetableResource gr = (GetableResource) resource;
   Long contentLength = gr.getContentLength();
   if (contentLength != null) {
     response.setContentLengthHeader(contentLength);
   } else {
     log.trace("No content length is available for HEAD request");
   }
   String acc = request.getAcceptHeader();
   String ct = gr.getContentType(acc);
   if (ct != null) {
     ct = pickBestContentType(ct);
     if (ct != null) {
       response.setContentTypeHeader(ct);
     }
   }
 }
 protected void setRespondCommonHeaders(
     Response response, Resource resource, Response.Status status, Auth auth) {
   response.setStatus(status);
   response.setNonStandardHeader("Server", "milton.io-" + miltonVerson);
   response.setDateHeader(new Date());
   response.setNonStandardHeader("Accept-Ranges", "bytes");
   String etag = eTagGenerator.generateEtag(resource);
   if (etag != null) {
     response.setEtag(etag);
   }
 }
 @Override
 public void respondUnauthorised(Resource resource, Response response, Request request) {
   if (authenticationService.canUseExternalAuth(resource, request)) {
     log.info("respondUnauthorised: use external authentication");
     initiateExternalAuth(resource, request, response);
   } else {
     log.info("respondUnauthorised: return staus: " + Response.Status.SC_UNAUTHORIZED);
     response.setStatus(Response.Status.SC_UNAUTHORIZED);
     List<String> challenges = authenticationService.getChallenges(resource, request);
     response.setAuthenticateHeader(challenges);
   }
 }
  @Override
  public void respondContent(
      Resource resource, Response response, Request request, Map<String, String> params)
      throws NotAuthorizedException, BadRequestException, NotFoundException {
    log.debug("respondContent: " + resource.getClass());
    Auth auth = request.getAuthorization();
    setRespondContentCommonHeaders(response, resource, auth);
    if (resource instanceof GetableResource) {
      GetableResource gr = (GetableResource) resource;
      String acc = request.getAcceptHeader();
      String ct = gr.getContentType(acc);
      if (ct != null) {
        ct = pickBestContentType(ct);
        response.setContentTypeHeader(ct);
      }
      cacheControlHelper.setCacheControl(gr, response, request.getAuthorization());

      Long contentLength = gr.getContentLength();
      Boolean doBuffering = null;
      if (resource instanceof BufferingControlResource) {
        BufferingControlResource bcr = (BufferingControlResource) resource;
        doBuffering = bcr.isBufferingRequired();
      }
      if (doBuffering == null) {
        if (buffering == null || buffering == BUFFERING.whenNeeded) {
          doBuffering =
              (contentLength
                  == null); // if no content length then we buffer content to find content length
        } else {
          doBuffering =
              (buffering
                  == BUFFERING
                      .always); // if not null or whenNeeded then buffering is explicitly enabled or
                                // disabled
        }
      }
      if (!doBuffering) {
        log.trace("sending content with known content length: " + contentLength);
        if (contentLength != null) {
          response.setContentLengthHeader(contentLength);
        }
        response.setEntity(new GetableResourceEntity(gr, params, ct));
      } else {
        BufferingGetableResourceEntity e =
            new BufferingGetableResourceEntity(gr, params, ct, contentLength, getMaxMemorySize());
        response.setEntity(e);
      }
    }
  }
 /**
  * @param resource
  * @param response
  * @param message - optional message to output in the body content
  */
 @Override
 public void respondConflict(
     Resource resource, Response response, Request request, String message) {
   log.debug("respondConflict");
   response.setStatus(Response.Status.SC_CONFLICT);
   contentGenerator.generate(resource, request, response, Status.SC_CONFLICT);
 }
  @Override
  public void respondNotModified(GetableResource resource, Response response, Request request) {
    log.trace("respondNotModified");
    response.setStatus(Response.Status.SC_NOT_MODIFIED);
    response.setDateHeader(new Date());
    String etag = eTagGenerator.generateEtag(resource);
    if (etag != null) {
      response.setEtag(etag);
    }

    // Note that we use a simpler modified date handling here then when
    // responding with content, because in a not-modified situation the
    // modified date MUST be that of the actual resource
    Date modDate = resource.getModifiedDate();
    response.setLastModifiedHeader(modDate);

    cacheControlHelper.setCacheControl(resource, response, request.getAuthorization());
  }
 @Override
 public void respondMethodNotAllowed(Resource res, Response response, Request request) {
   log.debug(
       "method not allowed. handler: "
           + this.getClass().getName()
           + " resource: "
           + res.getClass().getName());
   response.setStatus(Response.Status.SC_METHOD_NOT_ALLOWED);
   contentGenerator.generate(res, request, response, Status.SC_METHOD_NOT_ALLOWED);
 }
 @Override
 public void respondRedirect(Response response, Request request, String redirectUrl) {
   if (redirectUrl == null) {
     throw new NullPointerException("redirectUrl cannot be null");
   }
   log.trace("respondRedirect");
   // delegate to the response, because this can be server dependent
   response.sendRedirect(redirectUrl);
   //        response.setStatus(Response.Status.SC_MOVED_TEMPORARILY);
   //        response.setLocationHeader(redirectUrl);
 }
Exemple #12
0
  private void processCreateAndLock(
      HttpManager manager, Request request, Response response, Resource parentResource, String name)
      throws NotAuthorizedException {
    if (parentResource instanceof LockingCollectionResource) {
      log.debug("parent supports lock-null. doing createAndLock");
      LockingCollectionResource lockingParent = (LockingCollectionResource) parentResource;
      LockTimeout timeout = LockTimeout.parseTimeout(request);
      response.setContentTypeHeader(Response.XML);

      LockInfo lockInfo;
      try {
        lockInfo = LockInfoSaxHandler.parseLockInfo(request);
      } catch (SAXException ex) {
        throw new RuntimeException("Exception reading request body", ex);
      } catch (IOException ex) {
        throw new RuntimeException("Exception reading request body", ex);
      }

      // TODO: this should be refactored to return a LockResult as for existing entities

      log.debug("Creating lock on unmapped resource: " + name);
      LockToken tok = lockingParent.createAndLock(name, timeout, lockInfo);
      if (tok == null) {
        throw new RuntimeException(
            "createAndLock returned null, from resource of type: "
                + lockingParent.getClass().getCanonicalName());
      }
      response.setStatus(Status.SC_CREATED);
      response.setLockTokenHeader(
          "<opaquelocktoken:" + tok.tokenId + ">"); // spec says to set response header. See 8.10.1
      respondWithToken(tok, request, response);

    } else {
      log.debug("parent does not support lock-null, respondong method not allowed");
      responseHandler.respondMethodNotImplemented(parentResource, response, request);
    }
  }
 /**
  * The modified date response header is used by the client for content caching. It seems obvious
  * that if we have a modified date on the resource we should set it. BUT, because of the
  * interaction with max-age we should always set it to the current date if we have max-age The
  * problem, is that if we find that a condition GET has an expired mod-date (based on maxAge) then
  * we want to respond with content (even if our mod-date hasnt changed. But if we use the actual
  * mod-date in that case, then the browser will continue to use the old mod-date, so will forever
  * more respond with content. So we send a mod-date of now to ensure that future requests will be
  * given a 304 not modified.*
  *
  * @param response
  * @param resource
  * @param auth
  */
 public static void setModifiedDate(Response response, Resource resource, Auth auth) {
   Date modDate = resource.getModifiedDate();
   if (modDate != null) {
     // HACH - see if this helps IE
     response.setLastModifiedHeader(modDate);
     //            if (resource instanceof GetableResource) {
     //                GetableResource gr = (GetableResource) resource;
     //                Long maxAge = gr.getMaxAgeSeconds(auth);
     //                if (maxAge != null && maxAge > 0) {
     //                    log.trace("setModifiedDate: has a modified date and a positive maxAge,
     // so adjust modDate");
     //                    long tm = System.currentTimeMillis() - 60000; // modified 1 minute ago
     //                    modDate = new Date(tm); // have max-age, so use current date
     //                }
     //            }
     //            response.setLastModifiedHeader(modDate);
   }
 }
Exemple #14
0
  protected void processNewLock(
      HttpManager milton,
      Request request,
      Response response,
      LockableResource r,
      LockTimeout timeout)
      throws NotAuthorizedException {
    LockInfo lockInfo;
    try {
      lockInfo = LockInfoSaxHandler.parseLockInfo(request);
    } catch (SAXException ex) {
      throw new RuntimeException("Exception reading request body", ex);
    } catch (IOException ex) {
      throw new RuntimeException("Exception reading request body", ex);
    }

    if (handlerHelper.isLockedOut(request, r)) {
      this.responseHandler.respondLocked(request, response, r);
      return;
    }

    log.debug("locking: " + r.getName());
    LockResult result;
    try {
      result = r.lock(timeout, lockInfo);
    } catch (PreConditionFailedException ex) {
      responseHandler.respondPreconditionFailed(request, response, r);
      return;
    } catch (LockedException ex) {
      responseHandler.respondLocked(request, response, r);
      return;
    }

    if (result.isSuccessful()) {
      LockToken tok = result.getLockToken();
      log.debug("..locked ok: " + tok.tokenId);
      response.setLockTokenHeader(
          "<opaquelocktoken:" + tok.tokenId + ">"); // spec says to set response header. See 8.10.1
      respondWithToken(tok, request, response);
    } else {
      respondWithLockFailure(result, request, response);
    }
  }
 @Override
 public void respondPartialContent(
     GetableResource resource,
     Response response,
     Request request,
     Map<String, String> params,
     Range range)
     throws NotAuthorizedException, BadRequestException, NotFoundException {
   log.debug("respondPartialContent: " + range.getStart() + " - " + range.getFinish());
   response.setStatus(Response.Status.SC_PARTIAL_CONTENT);
   long st = range.getStart() == null ? 0 : range.getStart();
   long fn;
   Long cl = resource.getContentLength();
   if (range.getFinish() == null) {
     if (cl != null) {
       fn = cl.longValue() - 1; // position is one less then length
     } else {
       log.warn(
           "Couldnt calculate range end position because the resource is not reporting a content length, and no end position was requested by the client: "
               + resource.getName()
               + " - "
               + resource.getClass());
       fn = -1;
     }
   } else {
     fn = range.getFinish();
   }
   response.setContentRangeHeader(st, fn, cl);
   long contentLength = fn - st + 1;
   response.setContentLengthHeader(contentLength);
   response.setDateHeader(new Date());
   String etag = eTagGenerator.generateEtag(resource);
   if (etag != null) {
     response.setEtag(etag);
   }
   String acc = request.getAcceptHeader();
   String ct = resource.getContentType(acc);
   if (ct != null) {
     response.setContentTypeHeader(ct);
   }
   response.setEntity(new GetableResourceEntity(resource, range, params, ct));
 }
Exemple #16
0
  /**
   * (from the spec) 7.4 Write Locks and Null Resources
   *
   * <p>It is possible to assert a write lock on a null resource in order to lock the name.
   *
   * <p>A write locked null resource, referred to as a lock-null resource, MUST respond with a 404
   * (Not Found) or 405 (Method Not Allowed) to any HTTP/1.1 or DAV methods except for PUT, MKCOL,
   * OPTIONS, PROPFIND, LOCK, and UNLOCK. A lock-null resource MUST appear as a member of its parent
   * collection. Additionally the lock-null resource MUST have defined on it all mandatory DAV
   * properties. Most of these properties, such as all the get* properties, will have no value as a
   * lock-null resource does not support the GET method. Lock-Null resources MUST have defined
   * values for lockdiscovery and supportedlock properties.
   *
   * <p>Until a method such as PUT or MKCOL is successfully executed on the lock-null resource the
   * resource MUST stay in the lock-null state. However, once a PUT or MKCOL is successfully
   * executed on a lock-null resource the resource ceases to be in the lock-null state.
   *
   * <p>If the resource is unlocked, for any reason, without a PUT, MKCOL, or similar method having
   * been successfully executed upon it then the resource MUST return to the null state.
   *
   * @param manager
   * @param request
   * @param response
   * @param host
   * @param url
   */
  private void processNonExistingResource(
      HttpManager manager, Request request, Response response, String host, String url)
      throws NotAuthorizedException, BadRequestException {
    String name;

    Path parentPath = Path.path(url);
    name = parentPath.getName();
    parentPath = parentPath.getParent();
    url = parentPath.toString();

    Resource r = manager.getResourceFactory().getResource(host, url);
    if (r != null) {
      if (!handlerHelper.checkAuthorisation(manager, r, request)) {
        responseHandler.respondUnauthorised(r, response, request);
        return;
      } else {
        processCreateAndLock(manager, request, response, r, name);
      }
    } else {
      log.debug("couldnt find parent to execute lock-null, returning not found");
      // respondNotFound(response,request);
      response.setStatus(Status.SC_CONFLICT);
    }
  }
Exemple #17
0
  protected void processExistingResource(
      HttpManager manager, Request request, Response response, Resource resource)
      throws NotAuthorizedException {
    if (handlerHelper.isNotCompatible(resource, request.getMethod()) || !isCompatible(resource)) {
      responseHandler.respondMethodNotImplemented(resource, response, request);
      return;
    }
    if (!handlerHelper.checkAuthorisation(manager, resource, request)) {
      responseHandler.respondUnauthorised(resource, response, request);
      return;
    }

    handlerHelper.checkExpects(responseHandler, request, response);

    LockableResource r = (LockableResource) resource;
    LockTimeout timeout = LockTimeout.parseTimeout(request);
    String ifHeader = request.getIfHeader();
    response.setContentTypeHeader(Response.XML);
    if (ifHeader == null || ifHeader.length() == 0) {
      processNewLock(manager, request, response, r, timeout);
    } else {
      processRefresh(manager, request, response, r, timeout, ifHeader);
    }
  }
 @Override
 public void respondNotFound(Response response, Request request) {
   response.setStatus(Response.Status.SC_NOT_FOUND);
   response.setContentTypeHeader("text/html");
   contentGenerator.generate(null, request, response, Status.SC_NOT_FOUND);
 }
 @Override
 public void respondPreconditionFailed(Request request, Response response, Resource resource) {
   response.setStatus(Status.SC_PRECONDITION_FAILED);
 }
 @Override
 public void respondDeleteFailed(
     Request request, Response response, Resource resource, Status status) {
   response.setStatus(status);
 }
 @Override
 public void respondForbidden(Resource resource, Response response, Request request) {
   response.setStatus(Response.Status.SC_FORBIDDEN);
 }
 @Override
 public void respondBadRequest(Resource resource, Response response, Request request) {
   response.setStatus(Response.Status.SC_BAD_REQUEST);
 }
 @Override
 public void respondMethodNotImplemented(Resource resource, Response response, Request request) {
   response.setStatus(Response.Status.SC_NOT_IMPLEMENTED);
   contentGenerator.generate(resource, request, response, Status.SC_NOT_IMPLEMENTED);
 }
 @Override
 public void respondServerError(Request request, Response response, String reason) {
   response.setStatus(Status.SC_INTERNAL_SERVER_ERROR);
   contentGenerator.generate(null, request, response, Status.SC_INTERNAL_SERVER_ERROR);
 }
 @Override
 public void respondExpectationFailed(Response response, Request request) {
   response.setStatus(Response.Status.SC_EXPECTATION_FAILED);
 }
Exemple #26
0
 private void respondWithLockFailure(LockResult result, Request request, Response response) {
   log.info("respondWithLockFailure: " + result.getFailureReason().name());
   response.setStatus(result.getFailureReason().status);
 }
    @Override
    public void sendContent(
        OutputStream out, Range range, Map<String, String> params, String contentType)
        throws IOException, NotAuthorizedException, BadRequestException, NotFoundException {
      MediaMetaData mmd = MediaMetaData.find(rPrimary.getHash(), SessionManager.session());
      if (mmd != null) {
        Integer durationSecs = mmd.getDurationSecs();
        if (durationSecs != null) {
          Response resp = HttpManager.response();
          if (resp != null) {
            System.out.println("set duration header: " + durationSecs);
            resp.setNonStandardHeader("X-Content-Duration", durationSecs.toString());
          }
        }
      } else {
        System.out.println("no metadata for: " + rPrimary.getHash());
      }
      try {
        boolean force = params.containsKey("force");
        if (altFormat == null || force) {
          // hack start
          if (params.containsKey("args")) {
            List<String> args = new ArrayList<>();
            for (String s : params.get("args").split(",")) {
              args.add(s);
            }
            String[] arr = new String[args.size()];
            args.toArray(arr);
            formatSpec.setConverterArgs(arr);
            System.out.println("set args: " + arr);
          }

          // hack end
          System.out.println("generate: " + getName());
          GenerateJob j =
              altFormatGenerator.getOrEnqueueJob(
                  rPrimary.getHash(), rPrimary.getName(), formatSpec);
          System.out.println("got job: " + j);

          // Wait until the file exists
          int cnt = 0;
          System.out.println("check if exists...");
          while (!j.getDestFile().exists() && !j.done()) {
            cnt++;
            System.out.println(
                "sleep..." + cnt + " .. " + j.getDestFile().exists() + " - " + j.done());
            doSleep(cnt++, 200, 70);
          }
          System.out.println("finished sleepy check");
          if (!j.getDestFile().exists()) {
            throw new RuntimeException(
                "Job did not create a destination file: " + j.getDestFile().getAbsolutePath());
          }
          System.out.println(
              "use dest file: "
                  + j.getDestFile().getAbsolutePath()
                  + " size: "
                  + j.getDestFile().length());

          FileInputStream fin = new FileInputStream(j.getDestFile());
          byte[] buf = new byte[1024];
          System.out.println("send file...");
          // Read the file until the job is done, or we run out of bytes
          int s = fin.read(buf);
          System.out.println("send file... " + s);
          long bytes = 0;
          while (!j.done() || s > 0) {
            if (s < 0) { // no bytes available, but job is not done, so wait
              System.out.println("sleep...");
              doSleep(100);
            } else {
              System.out.println("write bytes: " + s);
              bytes += s;
              out.write(buf, 0, s);
            }
            s = fin.read(buf);
          }
          System.out.println("finished sending file: " + bytes);
        } else {
          System.out.println("using pre-existing al-format");
          Combiner combiner = new Combiner();
          List<String> fanoutCrcs = getFanout().getHashes();
          combiner.combine(fanoutCrcs, hashStore, blobStore, out);
          out.flush();
        }
      } catch (Throwable e) {
        log.error("Exception sending content", e);
        throw new IOException("Exception sending content");
      }
    }