Example #1
0
void testWrite(dmlite_context* context)
{
  dmlite_fd*       file;
  dmlite_any_dict* dict = dmlite_any_dict_new();
  char             buffer[64];
  
  SECTION("Read");
  
  /* Good to open */
  dmlite_any* token = dmlite_any_new_string("987654321");
  dmlite_any_dict_insert(dict, "token", token);
  dmlite_any_free(token);
  TEST_CONTEXT_CALL_PTR(file, context, dmlite_fopen, "/file", O_RDWR, dict);
  
  /* Write a chunk */
  TEST_ASSERT_EQUAL(10, dmlite_fwrite(file, "123456789", 10));
  
  /* Seek and read it back */
  TEST_ASSERT_EQUAL(0, dmlite_fseek(file, 0, SEEK_SET));
  TEST_ASSERT_EQUAL(10, dmlite_fread(file, buffer, 10));
  TEST_ASSERT_STR_EQUAL("123456789", buffer);
  
  
  /* Free */
  TEST_ASSERT_EQUAL(0, dmlite_fclose(file));
  dmlite_any_dict_free(dict);
}
Example #2
0
void testRead(dmlite_context* context)
{
  dmlite_fd*       file;
  dmlite_any_dict* dict = dmlite_any_dict_new();
  char             buffer[64];
  memset(buffer, 0, sizeof(buffer));
  
  SECTION("Read");
  
  /* Bad token */
  file = dmlite_fopen(context, "/file", O_RDONLY, dict);
  TEST_ASSERT_EQUAL(NULL, file);
  TEST_ASSERT_EQUAL(DM_FORBIDDEN, dmlite_errno(context));
          
  /* Open non-existing */
  file = dmlite_fopen(context, "/does-not-exist", O_RDONLY, dict);
  TEST_ASSERT_EQUAL(NULL, file);
  TEST_ASSERT_EQUAL(DM_NO_SUCH_FILE, dmlite_errno(context));
  
  /* Good to open */
  dmlite_any* token = dmlite_any_new_string("123456789");
  dmlite_any_dict_insert(dict, "token", token);
  dmlite_any_free(token);
  TEST_CONTEXT_CALL_PTR(file, context, dmlite_fopen, "/file", O_RDONLY, dict);
  
  /* Read */
  TEST_ASSERT_EQUAL(4, dmlite_fread(file, buffer, 4));
  buffer[5] = '\0';
  TEST_ASSERT_STR_EQUAL("abcd", buffer);
  TEST_ASSERT_EQUAL(4, dmlite_fread(file, buffer, 4));
  buffer[5] = '\0';
  TEST_ASSERT_STR_EQUAL("efgh", buffer);
  
  /* Seek and read */
  TEST_ASSERT_EQUAL(0, dmlite_fseek(file, 10, SEEK_SET));
  TEST_ASSERT_EQUAL(4, dmlite_fread(file, buffer, 4));
  buffer[5] = '\0';
  TEST_ASSERT_STR_EQUAL("klmn", buffer);
  
  TEST_ASSERT_EQUAL(14, dmlite_ftell(file));
  
  TEST_ASSERT_EQUAL(0, dmlite_feof(file));
  
  /* Free */
  TEST_ASSERT_EQUAL(0, dmlite_fclose(file));
  dmlite_any_dict_free(dict);
}
Example #3
0
void testPut(dmlite_context* context)
{
  char buffer[64];
  
  SECTION("PUT");
  
  /* Mock returns always one single location with one token */
  dmlite_location* loc;
  TEST_CONTEXT_CALL_PTR(loc, context, dmlite_put, "/file");
  
  TEST_ASSERT_EQUAL(1, loc->nchunks);
  
  TEST_ASSERT_STR_EQUAL("host1.cern.ch", loc->chunks[0].host);
  TEST_ASSERT_STR_EQUAL("/storage/chunk01", loc->chunks[0].path);
  TEST_ASSERT_EQUAL(0, loc->chunks[0].offset);
  TEST_ASSERT_EQUAL(0, loc->chunks[0].size);
  
    
  dmlite_any*  extra = dmlite_any_dict_get(loc->chunks[0].extra, "token");
  dmlite_any_to_string(extra, buffer, sizeof(buffer));
  TEST_ASSERT_STR_EQUAL("987654321", buffer);
  dmlite_any_free(extra);
  
  dmlite_location_free(context, loc);
  
  /* A donewriting without token will fail */
  dmlite_any_dict* dict = dmlite_any_dict_new();
  TEST_ASSERT_EQUAL(DM_FORBIDDEN, dmlite_donewriting(context,
                                                     "/storage/chunk01", dict));
  
  /* With token */
  dmlite_any* token = dmlite_any_new_string("987654321");
  dmlite_any_dict_insert(dict, "token", token);
  
  TEST_CONTEXT_CALL(context, dmlite_donewriting,
                    "/storage/chunk01", dict);
  
  dmlite_any_free(token);
  dmlite_any_dict_free(dict);
}
Example #4
0
/**
 * Open a stream. Used for PUT
 * @param resource The resource to open
 * @param mode     The mode (basically, trucate or random, which we don't support)
 * @param stream   Where to put the created structure
 * @return         NULL on success
 */
static dav_error *dav_ns_open_stream(const dav_resource *resource,
                                      dav_stream_mode mode,
                                      dav_stream **stream)
{
  dav_resource_private     *info;
  unsigned                  has_range;
  const char               *range, *length;
  int                       e;

  info = resource->info;
  
  /* Must be writable (if we are here, they want to write) */
  if (!(info->d_conf->flags & DAV_NS_WRITE))
    return dav_shared_new_error(info->request, NULL, HTTP_FORBIDDEN,
                                "Configured as read-only endpoint (%s)",
                                resource->uri);

  /* If content-length is 0, call create instead of put! */
  length = apr_table_get(info->request->headers_in, "content-length");
  if (length != NULL) {
    size_t clen = atol(length);
    if (clen == 0) {
      ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0,
                    info->request,
                    "PUT with content-length 0. Creating ns entry.");

      if (dmlite_create(info->ctx, info->sfn, 0644) != 0)
        return dav_shared_new_error(info->request, info->ctx, 0,
                                    "Could not create empty file %s", info->sfn);

      *stream = (dav_stream*)calloc(1, sizeof(dav_stream));

      return NULL;
    }
  }

  /* NS alone doesn't support PUTs with content! */
  if (info->s_conf->type == DAV_NS_NODE_LFC)
    return dav_shared_new_error(info->request, NULL, HTTP_NOT_IMPLEMENTED,
                                "LFC does not support PUTs");

  /*  Range header? */
  range = apr_table_get(info->request->headers_in, "content-range");
  has_range = (range != NULL);
  if (has_range) {
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0,
                  info->request,
                  "Range: %s", range);
  }

  /* If token not set, call dm_put and see where do we have to go */
  if (info->space_token != NULL) {
    dmlite_any* any = dmlite_any_new_string(info->space_token);
    e = dmlite_set(info->ctx, "SpaceToken", any);
    dmlite_any_free(any);
    if (e)
      return dav_shared_new_error(info->request, info->ctx, 0,
                                 "Could not set the space token %s", info->space_token);
  }
  
  dmlite_location *location; 
  location = dmlite_put(info->ctx, info->sfn);
  switch (dmlite_errno(info->ctx)) {
    case 0:
      break;
    case DM_INVALID_VALUE:
      return dav_shared_new_error(info->request, info->ctx, HTTP_BAD_REQUEST,
                                  "Can not get the space token %s",
                                  info->space_token);
    default:
      return dav_shared_new_error(info->request, info->ctx, 0, "Can not put %s",
                                  info->sfn);
  }      

  /* Redirect */
  info->redirect = apr_psprintf(resource->pool, "%s://%s%s%s",
                                info->d_conf->redir_scheme,
                                location->chunks[0].host,
                                location->chunks[0].path,
                                dav_shared_build_extra(resource->pool,
                                                       location->chunks[0].extra));

  ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0,
                info->request,
                "PUT request to be done in %s",
                info->redirect);

  apr_table_set(info->request->headers_out,
                "Location", info->redirect);
  
  dmlite_location_free(info->ctx, location);
  
  /* Standard says 301/302, but some clients will retry in that case with a GET.
   * 307 is unambiguous */
  return dav_new_error(resource->pool, HTTP_TEMPORARY_REDIRECT, 0,
                       info->redirect);
}