Exemple #1
0
/**
 * build headers from request
 *
 * @param req
 * @param headersp
 *
 * @return
 */
dpl_status_t
dpl_cdmi_req_build(const dpl_req_t *req,
                   dpl_dict_t **headersp,
                   char **body_strp,
                   int *body_lenp)
{
  dpl_dict_t *headers = NULL;
  int ret, ret2;
  char *method = dpl_method_str(req->method);
  json_object *body_obj = NULL;
  char *body_str = NULL;
  int body_len = 0;
  char buf[256];

  DPL_TRACE(req->ctx, DPL_TRACE_REQ, "req_build method=%s bucket=%s resource=%s subresource=%s", method, req->bucket, req->resource, req->subresource);

  headers = dpl_dict_new(13);
  if (NULL == headers)
    {
      ret = DPL_ENOMEM;
      goto end;
    }

  /*
   * per method headers
   */
  if (DPL_METHOD_GET == req->method)
    {
      //XXX ranges, conditions

      switch (req->object_type)
        {
        case DPL_FTYPE_UNDEF:
          //do nothing
          break ;
        case DPL_FTYPE_ANY:
          ret2 = dpl_dict_add(headers, "Accept", DPL_CDMI_CONTENT_TYPE_ANY, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          break ;
        case DPL_FTYPE_REG:
          ret2 = dpl_dict_add(headers, "Accept", DPL_CDMI_CONTENT_TYPE_OBJECT, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          break ;
        case DPL_FTYPE_DIR:
          ret2 = dpl_dict_add(headers, "Accept", DPL_CDMI_CONTENT_TYPE_CONTAINER, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          break ;
        case DPL_FTYPE_CAP:
          ret2 = dpl_dict_add(headers, "Accept", DPL_CDMI_CONTENT_TYPE_CAPABILITY, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          break ;
        }
    }
  else if (DPL_METHOD_PUT == req->method ||
           DPL_METHOD_POST == req->method)
    {
      body_obj = json_object_new_object();
      if (NULL == body_obj)
        {
          ret = DPL_ENOMEM;
          goto end;
        }

      if (NULL != req->cache_control)
        {
          ret2 = dpl_dict_add(headers, "Cache-Control", req->cache_control, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (NULL != req->content_disposition)
        {
          ret2 = dpl_dict_add(headers, "Content-Disposition", req->content_disposition, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (NULL != req->content_encoding)
        {
          ret2 = dpl_dict_add(headers, "Content-Encoding", req->content_encoding, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (!(req->behavior_flags & DPL_BEHAVIOR_HTTP_COMPAT))
        {
          ret2 = add_metadata_to_json_body(req->metadata, body_obj);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          
          if (NULL != req->chunk)
            {
              ret2 = add_data_to_json_body(req->chunk, body_obj);
              if (DPL_SUCCESS != ret2)
                {
                  ret = ret2;
                  goto end;
                }
            }
          
          pthread_mutex_lock(&req->ctx->lock);
          body_str = (char *) json_object_to_json_string(body_obj);
          pthread_mutex_unlock(&req->ctx->lock);
          if (NULL == body_str)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
          
          body_len = strlen(body_str);
          
          snprintf(buf, sizeof (buf), "%u", body_len);
          ret2 = dpl_dict_add(headers, "Content-Length", buf, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }
      else
        {
          snprintf(buf, sizeof (buf), "%u", req->chunk->len);
          ret2 = dpl_dict_add(headers, "Content-Length", buf, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }

      if (req->behavior_flags & DPL_BEHAVIOR_EXPECT)
        {
          ret2 = dpl_dict_add(headers, "Expect", "100-continue", 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }

      switch (req->object_type)
        {
        case DPL_FTYPE_UNDEF:
          //do nothing
          break ;
        case DPL_FTYPE_ANY:
          //error ?
          break ;
        case DPL_FTYPE_REG:
          ret2 = dpl_dict_add(headers, "Content-Type", DPL_CDMI_CONTENT_TYPE_OBJECT, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          break ;
        case DPL_FTYPE_DIR:
          ret2 = dpl_dict_add(headers, "Content-Type", DPL_CDMI_CONTENT_TYPE_CONTAINER, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          break ;
        case DPL_FTYPE_CAP:
          ret2 = dpl_dict_add(headers, "Content-Type", DPL_CDMI_CONTENT_TYPE_CAPABILITY, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
          break ;
        }
    }
  else if (DPL_METHOD_DELETE == req->method)
    {
    }
  else
    {
      ret = DPL_EINVAL;
      goto end;
    }

  /*
   * common headers
   */
  if (!(req->behavior_flags & DPL_BEHAVIOR_HTTP_COMPAT))
    {
      ret2 = dpl_dict_add(headers, "X-CDMI-Specification-Version", "1.0.1", 0);
      if (DPL_SUCCESS != ret2)
        {
          ret = ret2;
          goto end;
        }
    }

  if (req->behavior_flags & DPL_BEHAVIOR_VIRTUAL_HOSTING)
    {
      char host[1024];

      snprintf(host, sizeof (host), "%s.%s", req->bucket, req->ctx->host);

      ret2 = dpl_dict_add(headers, "Host", host, 0);
      if (DPL_SUCCESS != ret2)
        {
          ret = DPL_ENOMEM;
          goto end;
        }
    }
  else
    {
      ret2 = dpl_dict_add(headers, "Host", req->ctx->host, 0);
      if (DPL_SUCCESS != ret2)
        {
          ret = DPL_ENOMEM;
          goto end;
        }
    }

  if (req->behavior_flags & DPL_BEHAVIOR_KEEP_ALIVE)
    {
      ret2 = dpl_dict_add(headers, "Connection", "keep-alive", 0);
      if (DPL_SUCCESS != ret2)
        {
          ret = DPL_ENOMEM;
          goto end;
        }
    }

  ret2 = add_authorization_to_headers(req, headers);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  if (NULL != body_strp)
    {
      if (NULL == body_str)
        {
          *body_strp = NULL;
        }
      else
        {
          *body_strp = strdup(body_str);
          if (NULL == body_strp)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }
    }

  if (NULL != body_lenp)
    *body_lenp = body_len;

  if (NULL != headersp)
    {
      *headersp = headers;
      headers = NULL; //consume it
    }

  ret = DPL_SUCCESS;

 end:

  if (NULL != body_obj)
    json_object_put(body_obj);

  if (NULL != headers)
    dpl_dict_free(headers);

  return ret;
}
Exemple #2
0
dpl_status_t
dpl_s3_head_raw(dpl_ctx_t *ctx,
                const char *bucket,
                const char *resource,
                const char *subresource,
                const dpl_option_t *option,
                dpl_ftype_t object_type,
                const dpl_condition_t *condition,
                dpl_dict_t **metadatap,
                char **locationp)
{
  int           ret, ret2;
  dpl_conn_t   *conn = NULL;
  char          header[dpl_header_size];
  u_int         header_len;
  struct iovec  iov[10];
  int           n_iov = 0;
  int           connection_close = 0;
  dpl_dict_t    *headers_request = NULL;
  dpl_dict_t    *headers_reply = NULL;
  dpl_req_t     *req = NULL;
  dpl_s3_req_mask_t req_mask = 0u;

  DPL_TRACE(ctx, DPL_TRACE_BACKEND, "");

  req = dpl_req_new(ctx);
  if (NULL == req)
    {
      ret = DPL_ENOMEM;
      goto end;
    }

  dpl_req_set_method(req, DPL_METHOD_HEAD);

  if (NULL == bucket)
    {
      ret = DPL_EINVAL;
      goto end;
    }

  ret2 = dpl_req_set_bucket(req, bucket);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret2 = dpl_req_set_resource(req, resource);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  if (NULL != subresource)
    {
      ret2 = dpl_req_set_subresource(req, subresource);
      if (DPL_SUCCESS != ret2)
        {
          ret = ret2;
          goto end;
        }
    }

  if (NULL != condition)
    {
      dpl_req_set_condition(req, condition);
    }

  //build request
  ret2 = dpl_s3_req_build(req, req_mask, &headers_request);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret2 = dpl_try_connect(ctx, req, &conn);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret2 = dpl_add_host_to_headers(req, headers_request);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret2 = dpl_s3_add_authorization_to_headers(req, headers_request, NULL, NULL);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret2 = dpl_req_gen_http_request(ctx, req, headers_request, NULL, header, sizeof (header), &header_len);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  iov[n_iov].iov_base = header;
  iov[n_iov].iov_len = header_len;
  n_iov++;

  //final crlf
  iov[n_iov].iov_base = "\r\n";
  iov[n_iov].iov_len = 2;
  n_iov++;

  ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout);
  if (DPL_SUCCESS != ret2)
    {
      DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed");
      connection_close = 1;
      ret = ret2;
      goto end;
    }

  ret2 = dpl_read_http_reply(conn, 0, NULL, NULL, &headers_reply, &connection_close);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  if (NULL != metadatap)
    {
      *metadatap = headers_reply;
      headers_reply = NULL;
    }

  ret = DPL_SUCCESS;

 end:

  if (NULL != conn)
    {
      if (1 == connection_close)
        dpl_conn_terminate(conn);
      else
        dpl_conn_release(conn);
    }

  if (NULL != headers_reply)
    dpl_dict_free(headers_reply);

  if (NULL != headers_request)
    dpl_dict_free(headers_request);

  if (NULL != req)
    dpl_req_free(req);

  DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret);

  return ret;
}
Exemple #3
0
dpl_status_t
dpl_sproxyd_put_internal(dpl_ctx_t *ctx,
                         const char *bucket,
                         const char *resource,
                         const char *subresource,
                         const dpl_option_t *option,
                         dpl_ftype_t object_type,
                         const dpl_condition_t *condition,
                         const dpl_range_t *range,
                         const dpl_dict_t *metadata,
                         const dpl_sysmd_t *sysmd,
                         const char *data_buf,
                         unsigned int data_len,
                         int mdonly,
                         char **locationp)
{
    int           ret, ret2;
    dpl_conn_t   *conn = NULL;
    char          header[dpl_header_size];
    u_int         header_len;
    struct iovec  iov[10];
    int           n_iov = 0;
    int           connection_close = 0;
    dpl_dict_t    *headers_request = NULL;
    dpl_dict_t    *headers_reply = NULL;
    dpl_req_t     *req = NULL;
    dpl_sproxyd_req_mask_t req_mask = 0u;
    dpl_dict_t    *query_params = NULL;
    uint32_t      force_version = -1;

    DPL_TRACE(ctx, DPL_TRACE_BACKEND, "");

    req = dpl_req_new(ctx);
    if (NULL == req)
    {
        ret = DPL_ENOMEM;
        goto end;
    }

    dpl_req_set_method(req, DPL_METHOD_PUT);

    ret2 = dpl_req_set_resource(req, resource);
    if (DPL_SUCCESS != ret2)
    {
        ret = ret2;
        goto end;
    }

    if (NULL != subresource)
    {
        ret2 = dpl_req_set_subresource(req, subresource);
        if (DPL_SUCCESS != ret2)
        {
            ret = ret2;
            goto end;
        }
    }

    dpl_req_set_object_type(req, object_type);

    if (NULL != condition)
    {
        dpl_req_set_condition(req, condition);
    }

    if (option)
    {
        if (option->mask & DPL_OPTION_CONSISTENT)
            req_mask |= DPL_SPROXYD_REQ_CONSISTENT;

        if (option->mask & DPL_OPTION_EXPECT_VERSION)
        {
            req_mask = DPL_SPROXYD_REQ_EXPECT_VERSION;

            query_params = dpl_dict_new(13);
            if (NULL == query_params)
            {
                ret = DPL_ENOMEM;
                goto end;
            }

            ret2 = dpl_dict_add(query_params, "version", option->expect_version, 0);
            if (DPL_SUCCESS != ret2)
            {
                ret = ret2;
                goto end;
            }
        }

        if (option->mask & DPL_OPTION_FORCE_VERSION)
        {
            req_mask = DPL_SPROXYD_REQ_FORCE_VERSION;

            force_version = strtoul(option->force_version, NULL, 0);
        }
    }

    if (mdonly)
    {
        req_mask |= DPL_SPROXYD_REQ_MD_ONLY;
    }
    else
    {
        dpl_req_set_data(req, data_buf, data_len);
    }

    dpl_req_add_behavior(req, DPL_BEHAVIOR_MD5);

    if (NULL != metadata)
    {
        ret2 = dpl_req_add_metadata(req, metadata);
        if (DPL_SUCCESS != ret2)
        {
            ret = ret2;
            goto end;
        }
    }

    //build request
    ret2 = dpl_sproxyd_req_build(req, req_mask, force_version, &headers_request);
    if (DPL_SUCCESS != ret2)
    {
        ret = ret2;
        goto end;
    }

    //contact default host
    dpl_req_rm_behavior(req, DPL_BEHAVIOR_VIRTUAL_HOSTING);

    ret2 = dpl_try_connect(ctx, req, &conn);
    if (DPL_SUCCESS != ret2)
    {
        ret = ret2;
        goto end;
    }

    ret2 = dpl_add_host_to_headers(req, headers_request);
    if (DPL_SUCCESS != ret2)
    {
        ret = ret2;
        goto end;
    }

    ret2 = dpl_req_gen_http_request(ctx, req, headers_request, query_params, header, sizeof (header), &header_len);
    if (DPL_SUCCESS != ret2)
    {
        ret = ret2;
        goto end;
    }

    iov[n_iov].iov_base = header;
    iov[n_iov].iov_len = header_len;
    n_iov++;

    //final crlf
    iov[n_iov].iov_base = "\r\n";
    iov[n_iov].iov_len = 2;
    n_iov++;

    //buffer
    iov[n_iov].iov_base = (void *)data_buf;
    iov[n_iov].iov_len = data_len;
    n_iov++;

    ret2 = dpl_conn_writev_all(conn, iov, n_iov, conn->ctx->write_timeout);
    if (DPL_SUCCESS != ret2)
    {
        DPL_TRACE(conn->ctx, DPL_TRACE_ERR, "writev failed");
        connection_close = 1;
        ret = ret2;
        goto end;
    }

    ret2 = dpl_read_http_reply(conn, 1, NULL, NULL, &headers_reply, &connection_close);
    if (DPL_SUCCESS != ret2)
    {
        ret = ret2;
        goto end;
    }

    ret = DPL_SUCCESS;

end:

    if (NULL != conn)
    {
        if (1 == connection_close)
            dpl_conn_terminate(conn);
        else
            dpl_conn_release(conn);
    }

    if (NULL != headers_reply)
        dpl_dict_free(headers_reply);

    if (NULL != headers_request)
        dpl_dict_free(headers_request);

    if (NULL != query_params)
        dpl_dict_free(query_params);

    if (NULL != req)
        dpl_req_free(req);

    DPL_TRACE(ctx, DPL_TRACE_BACKEND, "ret=%d", ret);

    return ret;
}