コード例 #1
0
ファイル: file.c プロジェクト: Akilklk/vlc
static struct vlc_http_msg *vlc_http_file_open(struct vlc_http_file *file,
                                               uintmax_t offset)
{
    struct vlc_http_msg *resp;

    resp = vlc_http_res_open(&file->resource, vlc_http_file_req, &offset);
    if (resp == NULL)
        return NULL;

    int status = vlc_http_msg_get_status(resp);
    if (status == 206)
    {
        const char *str = vlc_http_msg_get_header(resp, "Content-Range");
        if (str == NULL)
            /* A multipart/byteranges response. This is not what we asked for
             * and we do not support it. */
            goto fail;

        uintmax_t start, end;
        if (sscanf(str, "bytes %ju-%ju", &start, &end) != 2
         || start != offset || start > end)
            /* A single range response is what we asked for, but not at that
             * start offset. */
            goto fail;
    }

    return resp;
fail:
    vlc_http_msg_destroy(resp);
    errno = EIO;
    return NULL;
}
コード例 #2
0
ファイル: file.c プロジェクト: Akilklk/vlc
static int vlc_http_file_req(struct vlc_http_msg *req,
                             const struct vlc_http_resource *res, void *opaque)
{
    struct vlc_http_file *file = (struct vlc_http_file *)res;
    const uintmax_t *offset = opaque;

    if (file->resp != NULL)
    {
        const char *str = vlc_http_msg_get_header(file->resp, "ETag");
        if (str != NULL)
        {
            if (!memcmp(str, "W/", 2))
                str += 2; /* skip weak mark */
            vlc_http_msg_add_header(req, "If-Match", "%s", str);
        }
        else
        {
            time_t mtime = vlc_http_msg_get_mtime(file->resp);
            if (mtime != -1)
                vlc_http_msg_add_time(req, "If-Unmodified-Since", &mtime);
        }
    }

    if (vlc_http_msg_add_header(req, "Range", "bytes=%ju-", *offset)
     && *offset != 0)
        return -1;
    return 0;
}
コード例 #3
0
struct vlc_http_msg *vlc_https_request(struct vlc_http_mgr *mgr,
                                       const char *host, unsigned port,
                                       const struct vlc_http_msg *req)
{
    const char *str;
    char *end;

    assert(mgr == NULL);
    assert(!strcmp(host, "www.example.com"));
    assert(port == 8443);

    str = vlc_http_msg_get_method(req);
    assert(!strcmp(str, "GET"));
    str = vlc_http_msg_get_scheme(req);
    assert(!strcmp(str, "https"));
    str = vlc_http_msg_get_authority(req);
    assert(!strcmp(str, "www.example.com:8443"));
    str = vlc_http_msg_get_path(req);
    assert(!strcmp(str, "/dir/file.ext?a=b"));
    str = vlc_http_msg_get_agent(req);
    assert(!strcmp(str, ua));
    str = vlc_http_msg_get_header(req, "Referer");
    assert(str == NULL);
    str = vlc_http_msg_get_header(req, "Accept");
    assert(str == NULL || strstr(str, "*/*") != NULL);
    str = vlc_http_msg_get_header(req, "Accept-Language");
    assert(str == NULL || strstr(str, "*") != NULL);

    str = vlc_http_msg_get_header(req, "Range");
    assert(str != NULL && !strncmp(str, "bytes=", 6)
        && strtoul(str + 6, &end, 10) == offset && *end == '-');

    str = vlc_http_msg_get_header(req, "If-Match");
    if (offset != 0)
        assert(str != NULL && !strcmp(str, "\"foobar42\""));
    else
        assert(str == NULL || strcmp(str, "*") || strcmp(str, "\"foobar42\""));

    return vlc_http_stream_read_headers(&stream);
}
コード例 #4
0
ファイル: file.c プロジェクト: Akilklk/vlc
uintmax_t vlc_http_file_get_size(struct vlc_http_file *file)
{
    int status = vlc_http_file_get_status(file);
    if (status < 0)
        return -1;

    const char *range = vlc_http_msg_get_header(file->resp, "Content-Range");

    if (status == 206 /* Partial Content */)
    {   /* IETF RFC7233 §4.1 */
        assert(range != NULL); /* checked by vlc_http_file_open() */

        uintmax_t end, total;

        switch (sscanf(range, "bytes %*u-%ju/%ju", &end, &total))
        {
            case 1:
                if (unlikely(end == UINTMAX_MAX))
                    return -1; /* avoid wrapping to zero */
                return end + 1;
            case 2:
                return total;
        }
        vlc_assert_unreachable(); /* checked by vlc_http_file_open() */
    }

    if (status == 416 /* Range Not Satisfiable */)
    {   /* IETF RFC7233 §4.4 */
        uintmax_t total;

        if (range == NULL)
            return -1; /* valid but helpless response */

        if (sscanf(range, "bytes */%ju", &total) == 1)
            return total; /* this occurs when seeking beyond EOF */
    }

    if (status >= 300 || status == 201)
        return -1; /* Error or redirection, size is unknown/irrelevant. */

    /* 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);
}