#include <vlc_network.h> /* FIXME: only for vlc_getProxyUrl() */
#include "connmgr.h"
+#include "resource.h"
#include "file.h"
#include "live.h"
struct access_sys_t
{
struct vlc_http_mgr *manager;
- union
- {
- struct vlc_http_file *file;
- struct vlc_http_live *live;
- };
+ struct vlc_http_resource *resource;
};
static block_t *FileRead(access_t *access)
{
access_sys_t *sys = access->p_sys;
- block_t *b = vlc_http_file_read(sys->file);
+ block_t *b = vlc_http_file_read(sys->resource);
if (b == NULL)
access->info.b_eof = true;
return b;
access_sys_t *sys = access->p_sys;
access->info.b_eof = false;
- if (vlc_http_file_seek(sys->file, pos))
+ if (vlc_http_file_seek(sys->resource, pos))
return VLC_EGENERIC;
return VLC_SUCCESS;
}
switch (query)
{
case ACCESS_CAN_SEEK:
- *va_arg(args, bool *) = vlc_http_file_can_seek(sys->file);
+ *va_arg(args, bool *) = vlc_http_file_can_seek(sys->resource);
break;
case ACCESS_CAN_FASTSEEK:
case ACCESS_GET_SIZE:
{
- uintmax_t val = vlc_http_file_get_size(sys->file);
+ uintmax_t val = vlc_http_file_get_size(sys->resource);
if (val >= UINT64_MAX)
return VLC_EGENERIC;
break;
case ACCESS_GET_CONTENT_TYPE:
- *va_arg(args, char **) = vlc_http_file_get_type(sys->file);
+ *va_arg(args, char **) = vlc_http_file_get_type(sys->resource);
break;
case ACCESS_SET_PAUSE_STATE:
{
access_sys_t *sys = access->p_sys;
- block_t *b = vlc_http_live_read(sys->live);
+ block_t *b = vlc_http_live_read(sys->resource);
if (b == NULL) /* TODO: loop instead of EOF, see vlc_http_live_read() */
access->info.b_eof = true;
return b;
break;
case ACCESS_GET_CONTENT_TYPE:
- *va_arg(args, char **) = vlc_http_live_get_type(sys->live);
+ *va_arg(args, char **) = vlc_http_live_get_type(sys->resource);
break;
default:
return VLC_ENOMEM;
sys->manager = NULL;
- sys->file = NULL;
+ sys->resource = NULL;
void *jar = NULL;
if (var_InheritBool(obj, "http-forward-cookies"))
bool live = var_InheritBool(obj, "http-continuous");
if (live)
- sys->live = vlc_http_live_create(sys->manager, access->psz_url, ua,
- referer);
+ sys->resource = vlc_http_live_create(sys->manager, access->psz_url, ua,
+ referer);
else
- sys->file = vlc_http_file_create(sys->manager, access->psz_url, ua,
- referer);
+ sys->resource = vlc_http_file_create(sys->manager, access->psz_url, ua,
+ referer);
free(referer);
free(ua);
- char *redir;
-
- if (live)
- {
- if (sys->live == NULL)
- goto error;
-
- redir = vlc_http_live_get_redirect(sys->live);
- }
- else
- {
- if (sys->file == NULL)
- goto error;
-
- redir = vlc_http_file_get_redirect(sys->file);
- }
+ if (sys->resource == NULL)
+ goto error;
+ char *redir = vlc_http_res_get_redirect(sys->resource);
if (redir != NULL)
{
access->psz_url = redir;
ret = VLC_EGENERIC;
- int status = live ? vlc_http_live_get_status(sys->live)
- : vlc_http_file_get_status(sys->file);
+ int status = vlc_http_res_get_status(sys->resource);
if (status < 0)
{
msg_Err(access, "HTTP connection failure");
return VLC_SUCCESS;
error:
- if (sys->file != NULL)
- vlc_http_file_destroy(sys->file);
+ if (sys->resource != NULL)
+ vlc_http_res_destroy(sys->resource);
if (sys->manager != NULL)
vlc_http_mgr_destroy(sys->manager);
free(sys);
access_t *access = (access_t *)obj;
access_sys_t *sys = access->p_sys;
- if (access->pf_block == LiveRead)
- vlc_http_live_destroy(sys->live);
- else
- vlc_http_file_destroy(sys->file);
+ vlc_http_res_destroy(sys->resource);
vlc_http_mgr_destroy(sys->manager);
free(sys);
}
struct vlc_http_file
{
struct vlc_http_resource resource;
- struct vlc_http_msg *resp;
uintmax_t offset;
- bool failed;
};
-static int vlc_http_file_req(struct vlc_http_msg *req,
- const struct vlc_http_resource *res, void *opaque)
+static int vlc_http_file_req(const struct vlc_http_resource *res,
+ struct vlc_http_msg *req, void *opaque)
{
struct vlc_http_file *file = (struct vlc_http_file *)res;
const uintmax_t *offset = opaque;
- if (file->resp != NULL)
+ if (file->resource.response != NULL)
{
- const char *str = vlc_http_msg_get_header(file->resp, "ETag");
+ const char *str = vlc_http_msg_get_header(file->resource.response,
+ "ETag");
if (str != NULL)
{
if (!memcmp(str, "W/", 2))
}
else
{
- time_t mtime = vlc_http_msg_get_mtime(file->resp);
+ time_t mtime = vlc_http_msg_get_mtime(file->resource.response);
if (mtime != -1)
vlc_http_msg_add_time(req, "If-Unmodified-Since", &mtime);
}
return 0;
}
-static struct vlc_http_msg *vlc_http_file_open(struct vlc_http_file *file,
- uintmax_t offset)
+static int vlc_http_file_resp(const struct vlc_http_resource *res,
+ const struct vlc_http_msg *resp, void *opaque)
{
- struct vlc_http_msg *resp;
-
- resp = vlc_http_res_open(&file->resource, vlc_http_file_req, &offset);
- if (resp == NULL)
- return NULL;
+ const uintmax_t *offset = opaque;
- int status = vlc_http_msg_get_status(resp);
- if (status == 206)
+ if (vlc_http_msg_get_status(resp) == 206)
{
const char *str = vlc_http_msg_get_header(resp, "Content-Range");
if (str == NULL)
uintmax_t start, end;
if (sscanf(str, "bytes %ju-%ju", &start, &end) != 2
- || start != offset || start > end)
+ || start != *offset || start > end)
/* A single range response is what we asked for, but not at that
* start offset. */
goto fail;
}
- return resp;
+ (void) res;
+ return 0;
+
fail:
- vlc_http_msg_destroy(resp);
errno = EIO;
- return NULL;
+ return -1;
}
-void vlc_http_file_destroy(struct vlc_http_file *file)
+static const struct vlc_http_resource_cbs vlc_http_file_callbacks =
{
- if (file->resp != NULL)
- vlc_http_msg_destroy(file->resp);
- vlc_http_res_deinit(&file->resource);
- free(file);
-}
+ vlc_http_file_req,
+ vlc_http_file_resp,
+};
-struct vlc_http_file *vlc_http_file_create(struct vlc_http_mgr *mgr,
- const char *uri, const char *ua,
- const char *ref)
+struct vlc_http_resource *vlc_http_file_create(struct vlc_http_mgr *mgr,
+ const char *uri, const char *ua,
+ const char *ref)
{
struct vlc_http_file *file = malloc(sizeof (*file));
if (unlikely(file == NULL))
return NULL;
- if (vlc_http_res_init(&file->resource, mgr, uri, ua, ref))
+ if (vlc_http_res_init(&file->resource, &vlc_http_file_callbacks, mgr,
+ uri, ua, ref))
{
free(file);
return NULL;
}
- file->resp = NULL;
file->offset = 0;
- file->failed = false;
- return file;
+ return &file->resource;
}
-int vlc_http_file_get_status(struct vlc_http_file *file)
+uintmax_t vlc_http_file_get_size(struct vlc_http_resource *res)
{
- if (file->resp == NULL)
- {
- if (file->failed)
- return -1;
- file->resp = vlc_http_file_open(file, file->offset);
- if (file->resp == NULL)
- {
- file->failed = true;
- return -1;
- }
- }
- return vlc_http_msg_get_status(file->resp);
-}
-
-char *vlc_http_file_get_redirect(struct vlc_http_file *file)
-{
- if (vlc_http_file_get_status(file) < 0)
- return NULL;
- return vlc_http_res_get_redirect(&file->resource, file->resp);
-}
-
-uintmax_t vlc_http_file_get_size(struct vlc_http_file *file)
-{
- int status = vlc_http_file_get_status(file);
+ int status = vlc_http_res_get_status(res);
if (status < 0)
return -1;
- const char *range = vlc_http_msg_get_header(file->resp, "Content-Range");
+ const char *range = vlc_http_msg_get_header(res->response,
+ "Content-Range");
if (status == 206 /* Partial Content */)
{ /* IETF RFC7233 §4.1 */
- assert(range != NULL); /* checked by vlc_http_file_open() */
+ assert(range != NULL); /* checked by vlc_http_file_resp() */
uintmax_t end, total;
case 2:
return total;
}
- vlc_assert_unreachable(); /* checked by vlc_http_file_open() */
+ vlc_assert_unreachable(); /* checked by vlc_http_file_resp() */
}
if (status == 416 /* Range Not Satisfiable */)
/* Content-Range is meaningless here (see RFC7233 B), so check if the size
* of the response entity body is known. */
- return vlc_http_msg_get_size(file->resp);
+ return vlc_http_msg_get_size(res->response);
}
-bool vlc_http_file_can_seek(struct vlc_http_file *file)
+bool vlc_http_file_can_seek(struct vlc_http_resource *res)
{ /* See IETF RFC7233 */
- int status = vlc_http_file_get_status(file);
+ int status = vlc_http_res_get_status(res);
if (status < 0)
return false;
if (status == 206 || status == 416)
return true; /* Partial Content */
- return vlc_http_msg_get_token(file->resp, "Accept-Ranges",
+ return vlc_http_msg_get_token(res->response, "Accept-Ranges",
"bytes") != NULL;
}
-char *vlc_http_file_get_type(struct vlc_http_file *file)
+int vlc_http_file_seek(struct vlc_http_resource *res, uintmax_t offset)
{
- if (vlc_http_file_get_status(file) < 0)
- return NULL;
- return vlc_http_res_get_type(file->resp);
-}
-
-int vlc_http_file_seek(struct vlc_http_file *file, uintmax_t offset)
-{
- struct vlc_http_msg *resp = vlc_http_file_open(file, offset);
+ struct vlc_http_msg *resp = vlc_http_res_open(res, &offset);
if (resp == NULL)
return -1;
+ struct vlc_http_file *file = (struct vlc_http_file *)res;
+
int status = vlc_http_msg_get_status(resp);
- if (file->resp != NULL)
+ if (res->response != NULL)
{ /* Accept the new and ditch the old one if:
* - requested succeeded and range was accepted (206),
* - requested failed due to out-of-range (416),
vlc_http_msg_destroy(resp);
return -1;
}
- vlc_http_msg_destroy(file->resp);
+ vlc_http_msg_destroy(res->response);
}
- file->resp = resp;
+ res->response = resp;
file->offset = offset;
return 0;
}
-block_t *vlc_http_file_read(struct vlc_http_file *file)
+block_t *vlc_http_file_read(struct vlc_http_resource *res)
{
- if (vlc_http_file_get_status(file) < 0)
- return NULL;
-
- block_t *block = vlc_http_res_read(file->resp);
+ struct vlc_http_file *file = (struct vlc_http_file *)res;
+ block_t *block = vlc_http_res_read(res);
if (block == NULL)
{ /* Automatically reconnect if server supports seek */
- if (vlc_http_file_can_seek(file)
- && vlc_http_file_seek(file, file->offset) == 0)
- block = vlc_http_res_read(file->resp);
+ if (vlc_http_file_can_seek(res)
+ && vlc_http_file_seek(res, file->offset) == 0)
+ block = vlc_http_res_read(res);
if (block == NULL)
return NULL;
* @{
*/
-struct vlc_http_file;
struct vlc_http_mgr;
+struct vlc_http_resource;
struct block_t;
/**
* @param url URL of the file to read
* @param ua user agent string (or NULL to ignore)
* @param ref referral URL (or NULL to ignore)
- */
-struct vlc_http_file *vlc_http_file_create(struct vlc_http_mgr *mgr,
- const char *url, const char *ua,
- const char *ref);
-
-/**
- * Destroys an HTTP file.
*
- * Releases all resources allocated or held by the HTTP file object.
+ * @return an HTTP resource object pointer, or NULL on error
*/
-void vlc_http_file_destroy(struct vlc_http_file *);
-
-int vlc_http_file_get_status(struct vlc_http_file *);
-
-/**
- * Gets redirection URL.
- *
- * Checks if the file URL lead to a redirection. If so, return the redirect
- * location.
- *
- * @return Heap-allocated URL or NULL if no redirection.
- */
-char *vlc_http_file_get_redirect(struct vlc_http_file *);
+struct vlc_http_resource *vlc_http_file_create(struct vlc_http_mgr *mgr,
+ const char *url, const char *ua,
+ const char *ref);
/**
* Gets file size.
*
* @return Bytes count or (uintmax_t)-1 if unknown.
*/
-uintmax_t vlc_http_file_get_size(struct vlc_http_file *);
+uintmax_t vlc_http_file_get_size(struct vlc_http_resource *);
/**
* Checks seeking support.
* @retval true if file supports seeking
* @retval false if file does not support seeking
*/
-bool vlc_http_file_can_seek(struct vlc_http_file *);
-
-/**
- * Gets MIME type.
- *
- * @return Heap-allocated MIME type string, or NULL if unknown.
- */
-char *vlc_http_file_get_type(struct vlc_http_file *);
+bool vlc_http_file_can_seek(struct vlc_http_resource *);
/**
* Sets the read offset.
* @retval 0 if seek succeeded
* @retval -1 if seek failed
*/
-int vlc_http_file_seek(struct vlc_http_file *, uintmax_t offset);
+int vlc_http_file_seek(struct vlc_http_resource *, uintmax_t offset);
/**
* Reads data.
+ *
+ * Reads data from a file and update the file offset.
*/
-struct block_t *vlc_http_file_read(struct vlc_http_file *);
+struct block_t *vlc_http_file_read(struct vlc_http_resource *);
+
+#define vlc_http_file_get_status vlc_http_res_get_status
+#define vlc_http_file_get_redirect vlc_http_res_get_redirect
+#define vlc_http_file_get_type vlc_http_res_get_type
+#define vlc_http_file_destroy vlc_http_res_destroy
/** @} */
#include <vlc_common.h>
#include <vlc_http.h>
+#include "resource.h"
#include "file.h"
#include "message.h"
int main(void)
{
- struct vlc_http_file *f;
+ struct vlc_http_resource *f;
char *str;
jar = vlc_http_cookies_new();
assert(!vlc_http_file_can_seek(f));
assert(vlc_http_file_get_type(f) == NULL);
assert(vlc_http_file_read(f) == NULL);
- vlc_http_file_destroy(f);
+ vlc_http_res_destroy(f);
/* Non-seekable stream test */
replies[0] = "HTTP/1.1 200 OK\r\n"
#pragma GCC visibility push(default)
-struct vlc_http_live
-{
- struct vlc_http_resource resource;
- struct vlc_http_msg *resp;
- bool failed;
-};
-
-static int vlc_http_live_req(struct vlc_http_msg *req,
- const struct vlc_http_resource *res, void *opaque)
+static int vlc_http_live_req(const struct vlc_http_resource *res,
+ struct vlc_http_msg *req, void *opaque)
{
vlc_http_msg_add_header(req, "Accept-Encoding", "gzip, deflate");
(void) res;
return 0;
}
-static struct vlc_http_msg *vlc_http_live_open(struct vlc_http_live *live)
+static int vlc_http_live_resp(const struct vlc_http_resource *res,
+ const struct vlc_http_msg *resp, void *opaque)
{
- return vlc_http_res_open(&live->resource, vlc_http_live_req, NULL);
+ (void) res;
+ (void) resp;
+ (void) opaque;
+ return 0;
}
-void vlc_http_live_destroy(struct vlc_http_live *live)
+static const struct vlc_http_resource_cbs vlc_http_live_callbacks =
{
- if (live->resp != NULL)
- vlc_http_msg_destroy(live->resp);
- vlc_http_res_deinit(&live->resource);
- free(live);
-}
+ vlc_http_live_req,
+ vlc_http_live_resp,
+};
-struct vlc_http_live *vlc_http_live_create(struct vlc_http_mgr *mgr,
- const char *uri, const char *ua,
- const char *ref)
+struct vlc_http_resource *vlc_http_live_create(struct vlc_http_mgr *mgr,
+ const char *uri, const char *ua,
+ const char *ref)
{
- struct vlc_http_live *live = malloc(sizeof (*live));
- if (unlikely(live == NULL))
+ struct vlc_http_resource *res = malloc(sizeof (*res));
+ if (unlikely(res == NULL))
return NULL;
- if (vlc_http_res_init(&live->resource, mgr, uri, ua, ref))
+ if (vlc_http_res_init(res, &vlc_http_live_callbacks, mgr, uri, ua, ref))
{
- free(live);
- return NULL;
+ free(res);
+ res = NULL;
}
- live->resp = NULL;
- live->failed = false;
- return live;
+ return res;
}
-int vlc_http_live_get_status(struct vlc_http_live *live)
+block_t *vlc_http_live_read(struct vlc_http_resource *res)
{
- if (live->resp == NULL)
- {
- if (live->failed)
- return -1;
- live->resp = vlc_http_live_open(live);
- if (live->resp == NULL)
- {
- live->failed = true;
- return -1;
- }
- }
- return vlc_http_msg_get_status(live->resp);
-}
-
-char *vlc_http_live_get_redirect(struct vlc_http_live *live)
-{
- if (vlc_http_live_get_status(live) < 0)
- return NULL;
- return vlc_http_res_get_redirect(&live->resource, live->resp);
-}
-
-char *vlc_http_live_get_type(struct vlc_http_live *live)
-{
- if (vlc_http_live_get_status(live) < 0)
- return NULL;
- return vlc_http_res_get_type(live->resp);
-}
-
-block_t *vlc_http_live_read(struct vlc_http_live *live)
-{
- if (vlc_http_live_get_status(live) < 0)
- return NULL;
-
- struct block_t *block = vlc_http_res_read(live->resp);
+ struct block_t *block = vlc_http_res_read(res);
if (block != NULL)
return block;
/* Automatically try to reconnect */
/* TODO: Retry-After parsing, loop and pacing timer */
- vlc_http_msg_destroy(live->resp);
- live->resp = NULL;
- if (vlc_http_live_get_status(live) < 0)
- return NULL;
- return vlc_http_res_read(live->resp);
+ vlc_http_msg_destroy(res->response);
+ res->response = NULL;
+ return vlc_http_res_read(res);
}
* @{
*/
-struct vlc_http_live;
+struct vlc_http_resource;
struct block_t;
-struct vlc_http_live *vlc_http_live_create(struct vlc_http_mgr *mgr,
- const char *uri, const char *ua,
- const char *ref);
-void vlc_http_live_destroy(struct vlc_http_live *live);
+struct vlc_http_resource *vlc_http_live_create(struct vlc_http_mgr *mgr,
+ const char *uri, const char *ua,
+ const char *ref);
+struct block_t *vlc_http_live_read(struct vlc_http_resource *);
-int vlc_http_live_get_status(struct vlc_http_live *live);
-char *vlc_http_live_get_redirect(struct vlc_http_live *live);
-char *vlc_http_live_get_type(struct vlc_http_live *live);
-block_t *vlc_http_live_read(struct vlc_http_live *live);
+#define vlc_http_live_get_status vlc_http_res_get_status
+#define vlc_http_live_get_redirect vlc_http_res_get_redirect
+#define vlc_http_live_get_type vlc_http_res_get_type
+#define vlc_http_live_destroye vlc_http_res_destroy
/** @} */
#include "resource.h"
static struct vlc_http_msg *
-vlc_http_res_req(const struct vlc_http_resource *res)
+vlc_http_res_req(const struct vlc_http_resource *res, void *opaque)
{
struct vlc_http_msg *req;
/* TODO: vlc_http_msg_add_header(req, "TE", "gzip, deflate"); */
+ if (res->cbs->request_format(res, req, opaque))
+ {
+ vlc_http_msg_destroy(req);
+ return NULL;
+ }
+
return req;
}
struct vlc_http_msg *vlc_http_res_open(struct vlc_http_resource *res,
- int (*request_cb)(struct vlc_http_msg *, const struct vlc_http_resource *,
- void *), void *opaque)
+ void *opaque)
{
struct vlc_http_msg *req;
retry:
- req = vlc_http_res_req(res);
+ req = vlc_http_res_req(res, opaque);
if (unlikely(req == NULL))
return NULL;
- if (request_cb(req, res, opaque))
- {
- vlc_http_msg_destroy(req);
- return NULL;
- }
-
struct vlc_http_msg *resp = vlc_http_mgr_request(res->manager, res->secure,
res->host, res->port, req);
vlc_http_msg_destroy(req);
goto retry;
}
+ if (res->cbs->response_validate(res, resp, opaque))
+ goto fail;
+
return resp;
fail:
vlc_http_msg_destroy(resp);
return NULL;
}
-void vlc_http_res_deinit(struct vlc_http_resource *res)
+int vlc_http_res_get_status(struct vlc_http_resource *res)
+{
+ if (res->response == NULL)
+ {
+ if (res->failure)
+ return -1;
+
+ res->response = vlc_http_res_open(res, res + 1);
+ if (res->response == NULL)
+ {
+ res->failure = true;
+ return -1;
+ }
+ }
+ return vlc_http_msg_get_status(res->response);
+}
+
+static void vlc_http_res_deinit(struct vlc_http_resource *res)
{
free(res->referrer);
free(res->agent);
free(res->path);
free(res->authority);
free(res->host);
+
+ if (res->response != NULL)
+ vlc_http_msg_destroy(res->response);
+}
+
+void vlc_http_res_destroy(struct vlc_http_resource *res)
+{
+ vlc_http_res_deinit(res);
+ free(res);
}
static char *vlc_http_authority(const char *host, unsigned port)
}
int vlc_http_res_init(struct vlc_http_resource *restrict res,
- struct vlc_http_mgr *mgr, const char *uri,
- const char *ua, const char *ref)
+ const struct vlc_http_resource_cbs *cbs,
+ struct vlc_http_mgr *mgr,
+ const char *uri, const char *ua, const char *ref)
{
vlc_url_t url;
bool secure;
goto error;
}
+ res->cbs = cbs;
+ res->response = NULL;
res->secure = secure;
res->negotiate = true;
+ res->failure = false;
res->host = strdup(url.psz_host);
res->port = url.i_port;
res->authority = vlc_http_authority(url.psz_host, url.i_port);
return -1;
}
-char *vlc_http_res_get_redirect(const struct vlc_http_resource *restrict res,
- const struct vlc_http_msg *resp)
+char *vlc_http_res_get_redirect(struct vlc_http_resource *restrict res)
{
- int status = vlc_http_msg_get_status(resp);
+ int status = vlc_http_res_get_status(res);
+ if (status < 0)
+ return NULL;
if ((status / 100) == 2 && !res->secure)
{
char *url;
/* HACK: Seems like an MMS server. Redirect to MMSH scheme. */
- if (vlc_http_msg_get_token(resp, "Pragma", "features") != NULL
+ if (vlc_http_msg_get_token(res->response, "Pragma", "features") != NULL
&& asprintf(&url, "mmsh://%s%s", res->authority, res->path) >= 0)
return url;
/* HACK: Seems like an ICY server. Redirect to ICYX scheme. */
- if ((vlc_http_msg_get_header(resp, "Icy-Name") != NULL
- || vlc_http_msg_get_header(resp, "Icy-Genre") != NULL)
+ if ((vlc_http_msg_get_header(res->response, "Icy-Name") != NULL
+ || vlc_http_msg_get_header(res->response, "Icy-Genre") != NULL)
&& asprintf(&url, "icyx://%s%s", res->authority, res->path) >= 0)
return url;
}
|| status == 306 /* Switch Proxy (former) */)
return NULL;
- const char *location = vlc_http_msg_get_header(resp, "Location");
+ const char *location = vlc_http_msg_get_header(res->response, "Location");
if (location == NULL)
return NULL;
return strndup(location, len);
}
-char *vlc_http_res_get_type(const struct vlc_http_msg *resp)
+char *vlc_http_res_get_type(struct vlc_http_resource *res)
{
- int status = vlc_http_msg_get_status(resp);
+ int status = vlc_http_res_get_status(res);
if (status < 200 || status >= 300)
return NULL;
- const char *type = vlc_http_msg_get_header(resp, "Content-Type");
+ const char *type = vlc_http_msg_get_header(res->response, "Content-Type");
return (type != NULL) ? strdup(type) : NULL;
}
-struct block_t *vlc_http_res_read(struct vlc_http_msg *resp)
+struct block_t *vlc_http_res_read(struct vlc_http_resource *res)
{
- int status = vlc_http_msg_get_status(resp);
+ int status = vlc_http_res_get_status(res);
if (status < 200 || status >= 300)
return NULL; /* do not "read" redirect or error message */
- return vlc_http_msg_read(resp);
+ return vlc_http_msg_read(res->response);
}
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+#ifndef VLC_HTTP_RESOURCE_H
+#define VLC_HTTP_RESOURCE_H 1
+
/**
* \defgroup http_res Resources
* Remote HTTP resources identified by a URL
struct vlc_http_msg;
struct vlc_http_mgr;
+struct vlc_http_resource;
+
+struct vlc_http_resource_cbs
+{
+ int (*request_format)(const struct vlc_http_resource *,
+ struct vlc_http_msg *, void *);
+ int (*response_validate)(const struct vlc_http_resource *,
+ const struct vlc_http_msg *, void *);
+};
struct vlc_http_resource
{
+ const struct vlc_http_resource_cbs *cbs;
+ struct vlc_http_msg *response;
struct vlc_http_mgr *manager;
- char *host;
- unsigned port;
bool secure;
bool negotiate;
+ bool failure;
+ char *host;
+ unsigned port;
char *authority;
char *path;
char *agent;
char *referrer;
};
-int vlc_http_res_init(struct vlc_http_resource *, struct vlc_http_mgr *mgr,
- const char *uri,const char *ua, const char *ref);
-void vlc_http_res_deinit(struct vlc_http_resource *);
+int vlc_http_res_init(struct vlc_http_resource *,
+ const struct vlc_http_resource_cbs *cbs,
+ struct vlc_http_mgr *mgr,
+ const char *uri, const char *ua, const char *ref);
+
+/**
+ * Destroys an HTTP resource.
+ *
+ * Releases all underlying resources allocated or held by the HTTP resource
+ * object.
+ */
+void vlc_http_res_destroy(struct vlc_http_resource *);
+
+struct vlc_http_msg *vlc_http_res_open(struct vlc_http_resource *res, void *);
+int vlc_http_res_get_status(struct vlc_http_resource *res);
+
+/**
+ * Gets redirection URL.
+ *
+ * Checks if the resource URL lead to a redirection. If so, return the redirect
+ * location.
+ *
+ * @return Heap-allocated URL or NULL if no redirection.
+ */
+char *vlc_http_res_get_redirect(struct vlc_http_resource *);
+
+/**
+ * Gets MIME type.
+ *
+ * @return Heap-allocated MIME type string, or NULL if unknown.
+ */
+char *vlc_http_res_get_type(struct vlc_http_resource *);
-struct vlc_http_msg *vlc_http_res_open(struct vlc_http_resource *res,
- int (*cb)(struct vlc_http_msg *req, const struct vlc_http_resource *,
- void *), void *);
-char *vlc_http_res_get_redirect(const struct vlc_http_resource *,
- const struct vlc_http_msg *resp);
-char *vlc_http_res_get_type(const struct vlc_http_msg *resp);
-struct block_t *vlc_http_res_read(struct vlc_http_msg *resp);
+/**
+ * Reads data.
+ */
+struct block_t *vlc_http_res_read(struct vlc_http_resource *);
/** @} */
+#endif