View Javadoc

1   package com.bradmcevoy.http.quota;
2   
3   import com.bradmcevoy.common.Path;
4   import com.bradmcevoy.http.CollectionResource;
5   import com.bradmcevoy.http.GetableResource;
6   import com.bradmcevoy.http.QuotaResource;
7   import com.bradmcevoy.http.Request;
8   import com.bradmcevoy.http.Resource;
9   import org.slf4j.Logger;
10  import org.slf4j.LoggerFactory;
11  
12  /**
13   * Default storage checking mechanism checks to see if the nearest parent
14   * resource implements QuotaResource, and if so uses the available bytes
15   * property from that to determine whether to allow a PUT
16   *
17   * Note that there is not always information available giving the size of new content,
18   * and in the case of replacing an existing resource, we might not have that resource's
19   * size. In these cases we cant determine perfectly whether we should allow or reject
20   * a PUT request. So we allow these requests if the available storage is greater then
21   * zero, but disallow if less then or equal to zero.
22   *
23   * @author brad
24   */
25  public class DefaultStorageChecker implements StorageChecker {
26  
27      private final static Logger log = LoggerFactory.getLogger( DefaultStorageChecker.class );
28  
29      public StorageErrorReason checkStorageOnReplace( Request request, CollectionResource parent, Resource replaced, String host ) {
30          if( parent instanceof QuotaResource ) {
31              QuotaResource qr = (QuotaResource) parent;
32              Long llAvail = qr.getQuotaAvailable();
33              if( llAvail == null ) {
34                  log.debug( "no quota data available" );
35                  return null;
36              }
37              if( llAvail <= 0 ) {
38                  // new content length must be less then existing
39                  Long newContentLength = request.getContentLengthHeader();
40                  if( newContentLength == null ) {
41                      log.debug( "new content length is not available, cant check quota, reject" );
42                      return StorageErrorReason.SER_QUOTA_EXCEEDED;
43                  }
44                  if( replaced instanceof GetableResource ) {
45                      GetableResource gr = (GetableResource) replaced;
46                      Long existingLength = gr.getContentLength();
47                      if( existingLength == null ) {
48                          log.debug( "existing content length cant be determined, cant check quota, reject");
49                          return StorageErrorReason.SER_QUOTA_EXCEEDED;
50                      } else {
51                          long diff = existingLength - newContentLength;
52                          if( diff > 0 ) {
53                              return null;
54                          } else {
55                              log.debug( "new content is larger then existing content, but no quota is available, reject");
56                              return StorageErrorReason.SER_QUOTA_EXCEEDED;
57                          }
58                      }
59                  } else {
60                      log.debug( "existing content length cant be determined, cant check quota, reject");
61                      return StorageErrorReason.SER_QUOTA_EXCEEDED;
62                  }
63              } else {
64                  // difference of new content to existing must be less then available, but if in doubt allow
65                  Long newContentLength = request.getContentLengthHeader();
66                  if( newContentLength == null ) {
67                      log.debug( "new content length is not available, cant check quota, allow" );
68                      return null;
69                  }
70                  if( replaced instanceof GetableResource ) {
71                      GetableResource gr = (GetableResource) replaced;
72                      Long existingLength = gr.getContentLength();
73                      if( existingLength == null ) {
74                          log.debug( "existing content length cant be determined, cant check quota, allow");
75                          return null;
76                      } else {
77                          long diff = newContentLength - existingLength; // this is the amount extra needed
78                          if( diff <= llAvail ) {
79                              return null;
80                          } else {
81                              log.debug( "new content is larger then existing content, but no quota is available, reject");
82                              return StorageErrorReason.SER_QUOTA_EXCEEDED;
83                          }
84                      }
85                  } else {
86                      log.debug( "existing content length cant be determined, cant check quota, allow");
87                      return null;
88                  }
89              }
90              // if difference between new content and existing is less then available, then ok
91  
92  
93          } else {
94              return null;
95          }
96      }
97  
98      public StorageErrorReason checkStorageOnAdd( Request request, CollectionResource nearestParent, Path parentPath, String host ) {
99          if( nearestParent instanceof QuotaResource ) {
100             QuotaResource qr = (QuotaResource) nearestParent;
101             Long llAvail = qr.getQuotaAvailable();
102             if( llAvail == null ) {
103                 log.debug( "no quota data available" );
104                 return null;
105             }
106             if( llAvail <= 0 ) {
107                 log.debug( "no quota available, reject" );
108                 return StorageErrorReason.SER_QUOTA_EXCEEDED;
109             } else {
110                 // new content must be less then that available
111                 Long newContentLength = request.getContentLengthHeader();
112                 if( newContentLength == null ) {
113                     log.debug( "new content length is not available, cant check quota, allow" );
114                     return null;
115                 }
116                 if( newContentLength < llAvail ) {
117                     return null;
118                 } else {
119                     log.debug( "new content length is greater then available storage, reject");
120                     return StorageErrorReason.SER_QUOTA_EXCEEDED;
121                 }
122             }
123         } else {
124             return null;
125         }
126 
127     }
128 }