Пример #1
0
int format_ogg_get_plugin (format_plugin_t *plugin, client_t *client)
{
    ogg_state_t *state = calloc (1, sizeof (ogg_state_t));

    plugin->get_buffer = ogg_get_buffer;
    plugin->write_buf_to_client = write_buf_to_client;
    plugin->write_buf_to_file = write_ogg_to_file;
    plugin->create_client_data = create_ogg_client_data;
    plugin->free_plugin = format_ogg_free_plugin;
    plugin->get_image = get_image;
    plugin->set_tag = NULL;
    plugin->apply_settings = apply_ogg_settings;
    if (plugin->parser)
    {
        const char *s = httpp_getvar (plugin->parser, "content-type");;
        if (s==NULL || strcmp (s, "application/x-ogg") == 0)
            httpp_setvar (plugin->parser, "content-type", "application/ogg");
        plugin->contenttype = strdup (httpp_getvar (plugin->parser, "content-type"));
    }
    else
        plugin->contenttype = strdup ("application/ogg");

    ogg_sync_init (&state->oy);

    plugin->_state = state;
    state->mount = plugin->mount;
    state->bos_end = &state->header_pages;

    return 0;
}
Пример #2
0
int format_ogg_get_plugin (source_t *source)
{
    format_plugin_t *plugin;
    ogg_state_t *state = calloc (1, sizeof (ogg_state_t));

    plugin = (format_plugin_t *)calloc(1, sizeof(format_plugin_t));

    plugin->type = FORMAT_TYPE_OGG;
    plugin->get_buffer = ogg_get_buffer;
    plugin->write_buf_to_client = write_buf_to_client;
    plugin->write_buf_to_file = write_ogg_to_file;
    plugin->create_client_data = create_ogg_client_data;
    plugin->free_plugin = format_ogg_free_plugin;
    plugin->set_tag = NULL;
    if (strcmp (httpp_getvar (source->parser, "content-type"), "application/x-ogg") == 0)
        httpp_setvar (source->parser, "content-type", "application/ogg");
    plugin->contenttype = httpp_getvar (source->parser, "content-type");

    ogg_sync_init (&state->oy);

    plugin->_state = state;
    source->format = plugin;
    state->mount = source->mount;
    state->bos_end = &state->header_pages;

    return 0;
}
Пример #3
0
static void ogg_apply_client (format_plugin_t *plugin, client_t *client)
{
    ogg_state_t *state = plugin->_state;

    state->mount = NULL;
    ogg_sync_clear (&state->oy);

    if (client == NULL)
        return;
    plugin->parser = client->parser;
    if (plugin->parser)
    {
        const char *s = httpp_getvar (plugin->parser, "content-type");
        if (s==NULL || strcmp (s, "application/x-ogg") == 0)
            httpp_setvar (plugin->parser, "content-type", "application/ogg");
        s = httpp_getvar (plugin->parser, "content-type");
        if (s)
            plugin->contenttype = strdup (s);
    }

    ogg_sync_init (&state->oy);

    state->mount = plugin->mount;
    state->bos_end = &state->header_pages;
}
Пример #4
0
static int format_mp3_create_client_data(source_t *source, client_t *client)
{
    mp3_client_data *client_mp3 = calloc(1,sizeof(mp3_client_data));
    mp3_state *source_mp3 = source->format->_state;
    const char *metadata;
    /* the +-2 is for overwriting the last set of \r\n */
    unsigned remaining = 4096 - client->refbuf->len + 2;
    char *ptr = client->refbuf->data + client->refbuf->len - 2;
    int bytes;
    const char *useragent;

    if (client_mp3 == NULL)
        return -1;

    /* hack for flash player, it wants a length.  It has also been reported that the useragent
     * appears as MSIE if run in internet explorer */
    useragent = httpp_getvar (client->parser, "user-agent");
    if (httpp_getvar(client->parser, "x-flash-version") ||
            (useragent && strstr(useragent, "MSIE")))
    {
        bytes = snprintf (ptr, remaining, "Content-Length: 221183499\r\n");
        remaining -= bytes;
        ptr += bytes;
    }

    client->format_data = client_mp3;
    client->free_client_data = free_mp3_client_data;
    metadata = httpp_getvar(client->parser, "icy-metadata");
    if (metadata && atoi(metadata))
    {
        if (source_mp3->interval >= 0)
            client_mp3->interval = source_mp3->interval;
        else
            client_mp3->interval = ICY_METADATA_INTERVAL;
        if (client_mp3->interval)
        {
            bytes = snprintf (ptr, remaining, "icy-metaint:%u\r\n",
                    client_mp3->interval);
            if (bytes > 0)
            {
                remaining -= bytes;
                ptr += bytes;
            }
        }
    }
    bytes = snprintf (ptr, remaining, "\r\n");
    remaining -= bytes;
    ptr += bytes;

    client->refbuf->len = 4096 - remaining;

    return 0;
}
Пример #5
0
int format_mp3_get_plugin (source_t *source)
{
    const char *metadata;
    format_plugin_t *plugin;
    mp3_state *state = calloc(1, sizeof(mp3_state));
    refbuf_t *meta;

    plugin = (format_plugin_t *)calloc(1, sizeof(format_plugin_t));

    plugin->type = FORMAT_TYPE_GENERIC;
    plugin->get_buffer = mp3_get_no_meta;
    plugin->write_buf_to_client = format_mp3_write_buf_to_client;
    plugin->write_buf_to_file = write_mp3_to_file;
    plugin->create_client_data = format_mp3_create_client_data;
    plugin->free_plugin = format_mp3_free_plugin;
    plugin->set_tag = mp3_set_tag;
    plugin->apply_settings = format_mp3_apply_settings;

    plugin->contenttype = httpp_getvar (source->parser, "content-type");
    if (plugin->contenttype == NULL) {
        /* We default to MP3 audio for old clients without content types */
        plugin->contenttype = "audio/mpeg";
    }

    plugin->_state = state;

    /* initial metadata needs to be blank for sending to clients and for
       comparing with new metadata */
    meta = refbuf_new (17);
    memcpy (meta->data, "\001StreamTitle='';", 17);
    state->metadata = meta;
    state->interval = -1;

    metadata = httpp_getvar (source->parser, "icy-metaint");
    if (metadata)
    {
        state->inline_metadata_interval = atoi (metadata);
        if (state->inline_metadata_interval > 0)
        {
            state->offset = 0;
            plugin->get_buffer = mp3_get_filter_meta;
            state->interval = state->inline_metadata_interval;
        }
    }
    source->format = plugin;
    thread_mutex_create (&state->url_lock);

    return 0;
}
Пример #6
0
int command_list_mounts(client_t *client, int response)
{
    DEBUG0("List mounts request");

    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    if (response == TEXT)
    {
        redirector_update (client);

        snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
                "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
        client->refbuf->len = strlen (client->refbuf->data);
        client->respcode = 200;

        if (strcmp (httpp_getvar (client->parser, HTTPP_VAR_URI), "/admin/streams") == 0)
            client->refbuf->next = stats_get_streams (1);
        else
            client->refbuf->next = stats_get_streams (0);
        return fserve_setup_client (client);
    }
    else
    {
        xmlDocPtr doc;
        avl_tree_rlock (global.source_tree);
        doc = admin_build_sourcelist(NULL);
        avl_tree_unlock (global.source_tree);

        return admin_send_response (doc, client, response, "listmounts.xsl");
    }
}
Пример #7
0
static void file_release (client_t *client)
{
    fh_node *fh = client->shared_data;
    int ret = -1;

    if (fh->finfo.flags & FS_FALLBACK)
        stats_event_dec (NULL, "listeners");
    remove_from_fh (fh, client);

    client_set_queue (client, NULL);

    if (client->flags & CLIENT_AUTHENTICATED && client->parser->req_type == httpp_req_get)
    {
        const char *mount = httpp_getvar (client->parser, HTTPP_VAR_URI);
        ice_config_t *config = config_get_config ();
        mount_proxy *mountinfo = config_find_mount (config, mount);
        if (mountinfo && mountinfo->access_log.name)
            logging_access_id (&mountinfo->access_log, client);
        ret = auth_release_listener (client, mount, mountinfo);
        config_release_config();
    }
    if (ret < 0)
    {
        client->flags &= ~CLIENT_AUTHENTICATED;
        client_destroy (client);
    }
    global_reduce_bitrate_sampling (global.out_bitrate);
}
Пример #8
0
static void format_mp3_apply_settings (client_t *client, format_plugin_t *format, mount_proxy *mount)
{
    mp3_state *source_mp3 = format->_state;

    source_mp3->interval = -1;
    free (format->charset);
    format->charset = NULL;

    if (mount)
    {
        if (mount->mp3_meta_interval >= 0)
            source_mp3->interval = mount->mp3_meta_interval;
        if (mount->charset)
            format->charset = strdup (mount->charset);
    }
    if (source_mp3->interval < 0)
    {
        const char *metadata = httpp_getvar (client->parser, "icy-metaint");
        source_mp3->interval = ICY_METADATA_INTERVAL;
        if (metadata)
        {
            int interval = atoi (metadata);
            if (interval > 0)
                source_mp3->interval = interval;
        }
    }

    if (format->charset == NULL)
        format->charset = strdup ("ISO8859-1");

    ICECAST_LOG_DEBUG("sending metadata interval %d", source_mp3->interval);
    ICECAST_LOG_DEBUG("charset %s", format->charset);
}
Пример #9
0
void source_client_callback (client_t *client, void *arg)
{
    const char *agent;
    source_t *source = arg;
    refbuf_t *old_data = client->refbuf;

    if (client->con->error)
    {
        global_lock();
        global.sources--;
        global_unlock();
        source_clear_source (source);
        source_free_source (source);
        return;
    }
    client->refbuf = old_data->associated;
    old_data->associated = NULL;
    refbuf_release (old_data);
    stats_event (source->mount, "source_ip", source->client->con->ip);
    agent = httpp_getvar (source->client->parser, "user-agent");
    if (agent)
        stats_event (source->mount, "user_agent", agent);

    thread_create ("Source Thread", source_client_thread,
            source, THREAD_DETACHED);
}
Пример #10
0
static void command_list_mounts(client_t *client, int response)
{
    DEBUG0("List mounts request");

    if (response == PLAINTEXT)
    {
        snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
                "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
        client->refbuf->len = strlen (client->refbuf->data);
        client->respcode = 200;

        const char *url = httpp_getvar(client->parser, "x-origin");
        stats_event_args(NULL, "relay_url", "%s", url);

        client->refbuf->next = stats_get_streams ();
        fserve_add_client (client, NULL);
    }
    else
    {
        xmlDocPtr doc;
        avl_tree_rlock (global.source_tree);
        doc = admin_build_sourcelist(NULL);
        avl_tree_unlock (global.source_tree);

        admin_send_response(doc, client, response, 
            LISTMOUNTS_TRANSFORMED_REQUEST);
        xmlFreeDoc(doc);
    }
}
Пример #11
0
/* return 0 for failed, 1 for ok
 */
int connection_check_pass (http_parser_t *parser, const char *user, const char *pass)
{
    int ret;
    const char *protocol;

    if(!pass) {
        WARN0("No source password set, rejecting source");
        return -1;
    }

    protocol = httpp_getvar(parser, HTTPP_VAR_PROTOCOL);
    if(protocol != NULL && !strcmp(protocol, "ICY")) {
        ret = _check_pass_icy(parser, pass);
    }
    else {
        ret = _check_pass_http(parser, user, pass);
        if (!ret)
        {
            ice_config_t *config = config_get_config_unlocked();
            if (config->ice_login)
            {
                ret = _check_pass_ice(parser, pass);
                if(ret)
                    WARN0("Source is using deprecated icecast login");
            }
        }
    }
    return ret;
}
Пример #12
0
static int format_mp3_create_client_data(source_t *source, client_t *client)
{
    mp3_client_data *client_mp3 = calloc(1,sizeof(mp3_client_data));
    mp3_state *source_mp3 = source->format->_state;
    const char *metadata; 
    /* the +-2 is for overwriting the last set of \r\n */
    unsigned remaining = 4096 - client->refbuf->len + 2;
    char *ptr = client->refbuf->data + client->refbuf->len - 2;
    int bytes;

    if (client_mp3 == NULL)
        return -1;

    /* hack for flash player, it wants a length */
    if (httpp_getvar(client->parser, "x-flash-version"))
    {
        bytes = snprintf (ptr, remaining, "Content-Length: 347122319\r\n");
        remaining -= bytes;
        ptr += bytes;
    }

    client->format_data = client_mp3;
    client->free_client_data = free_mp3_client_data;
    metadata = httpp_getvar(client->parser, "icy-metadata");
    if (metadata && atoi(metadata))
    {
        if (source_mp3->interval > 0)
            client_mp3->interval = source_mp3->interval;
        else
            client_mp3->interval = ICY_METADATA_INTERVAL;
        bytes = snprintf (ptr, remaining, "icy-metaint:%u\r\n",
                client_mp3->interval);
        if (bytes > 0)
        {
            remaining -= bytes;
            ptr += bytes;
        }
    }
    bytes = snprintf (ptr, remaining, "\r\n");
    remaining -= bytes;
    ptr += bytes;

    client->refbuf->len = 4096 - remaining;

    return 0;
}
Пример #13
0
static void url_stream_auth (auth_client *auth_user)
{
    ice_config_t *config;
    int port;
    client_t *client = auth_user->client;
    auth_url *url = client->auth->state;
    char *mount, *host, *user, *pass, *ipaddr, *admin="";
    char post [4096];

    if (strchr (url->stream_auth, '@') == NULL)
    {
        if (url->userpwd)
            curl_easy_setopt (url->handle, CURLOPT_USERPWD, url->userpwd);
        else
            curl_easy_setopt (url->handle, CURLOPT_USERPWD, "");
    }
    else
        curl_easy_setopt (url->handle, CURLOPT_USERPWD, "");
    curl_easy_setopt (url->handle, CURLOPT_URL, url->stream_auth);
    curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post);
    curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user);
    if (strcmp (auth_user->mount, httpp_getvar (client->parser, HTTPP_VAR_URI)) != 0)
        admin = "&admin=1";
    mount = util_url_escape (auth_user->mount);
    config = config_get_config ();
    host = util_url_escape (config->hostname);
    port = config->port;
    config_release_config ();
    ipaddr = util_url_escape (client->con->ip);

    if (client->username) {
        user = util_url_escape(client->username);
    } else {
        user = strdup("");
    }

    if (client->password) {
        pass = util_url_escape(client->password);
    } else {
        pass = strdup("");
    }

    snprintf (post, sizeof (post),
              "action=stream_auth&mount=%s&ip=%s&server=%s&port=%d&user=%s&pass=%s%s",
              mount, ipaddr, host, port, user, pass, admin);
    free (ipaddr);
    free (user);
    free (pass);
    free (mount);
    free (host);

    client->authenticated = 0;
    if (curl_easy_perform (url->handle))
        ICECAST_LOG_WARN("auth to server %s failed with %s", url->stream_auth, url->errormsg);
}
Пример #14
0
static int _handle_client (client_t *client)
{
    const char *rawuri;
    http_parser_t *parser = client->parser;
    char *uri;

    rawuri = httpp_getvar(parser, HTTPP_VAR_URI);

    if (strcmp("ICE",  httpp_getvar(parser, HTTPP_VAR_PROTOCOL)) &&
        strcmp("HTTP", httpp_getvar(parser, HTTPP_VAR_PROTOCOL))) {
        client_send_400 (client, "Bad HTTP protocol");
        return -EINPROGRESS;
    }

    uri = util_normalise_uri(rawuri);

    if (uri == NULL) {
        client_send_400 (client, "Couldn't normalize uri");
        return -EINPROGRESS;
    }

    if (parser->req_type == httpp_req_source) {
        _handle_source_request (client, uri);
    }
    else if (parser->req_type == httpp_req_post) {
        _handle_post_request (client, uri);
    }
    else if (parser->req_type == httpp_req_stats) {
        _handle_stats_request (client, uri);
    }
    else if (parser->req_type == httpp_req_get) {
        _handle_get_request (client, uri);
    }
    else {
        client_send_400 (client, "Wrong request type from client");
        return -EINPROGRESS;
    }

    free(uri);
    return 1;
}
Пример #15
0
static void command_show_listeners(client_t *client, source_t *source,
    int response)
{
    xmlDocPtr doc;
    xmlNodePtr node, srcnode, listenernode;
    avl_node *client_node;
    client_t *current;
    char buf[22];
    char *userAgent = NULL;
    time_t now = time(NULL);

    doc = xmlNewDoc("1.0");
    node = xmlNewDocNode(doc, NULL, "icestats", NULL);
    srcnode = xmlNewChild(node, NULL, "source", NULL);
    xmlSetProp(srcnode, "mount", source->mount);
    xmlDocSetRootElement(doc, node);

    memset(buf, '\000', sizeof(buf));
    snprintf(buf, sizeof(buf)-1, "%ld", source->listeners);
    xmlNewChild(srcnode, NULL, "Listeners", buf);

    avl_tree_rlock(source->client_tree);

    client_node = avl_get_first(source->client_tree);
    while(client_node) {
        current = (client_t *)client_node->key;
        listenernode = xmlNewChild(srcnode, NULL, "listener", NULL);
        xmlNewChild(listenernode, NULL, "IP", current->con->ip);
        userAgent = httpp_getvar(current->parser, "user-agent");
        if (userAgent) {
            xmlNewChild(listenernode, NULL, "UserAgent", userAgent);
        }
        else {
            xmlNewChild(listenernode, NULL, "UserAgent", "Unknown");
        }
        memset(buf, '\000', sizeof(buf));
        snprintf(buf, sizeof(buf)-1, "%ld", now - current->con->con_time);
        xmlNewChild(listenernode, NULL, "Connected", buf);
        memset(buf, '\000', sizeof(buf));
        snprintf(buf, sizeof(buf)-1, "%lu", current->con->id);
        xmlNewChild(listenernode, NULL, "ID", buf);
        if (current->username) {
            xmlNewChild(listenernode, NULL, "username", current->username);
        }
        client_node = avl_get_next(client_node);
    }

    avl_tree_unlock(source->client_tree);
    admin_send_response(doc, client, response, 
        LISTCLIENTS_TRANSFORMED_REQUEST);
    xmlFreeDoc(doc);
    client_destroy(client);
}
Пример #16
0
void client_destroy(client_t *client)
{
    if (client == NULL)
        return;

    if (client->worker)
    {
        WARN0 ("client still on worker thread");
        return;
    }
    /* release the buffer now, as the buffer could be on the source queue
     * and may of disappeared after auth completes */
    if (client->refbuf)
    {
        refbuf_release (client->refbuf);
        client->refbuf = NULL;
    }

    if (client->flags & CLIENT_AUTHENTICATED)
        DEBUG1 ("client still in auth \"%s\"", httpp_getvar (client->parser, HTTPP_VAR_URI));

    /* write log entry if ip is set (some things don't set it, like outgoing 
     * slave requests
     */
    if (client->respcode > 0 && client->parser)
        logging_access(client);

    if (client->flags & CLIENT_IP_BAN_LIFT)
    {
        INFO1 ("lifting IP ban on client at %s", client->connection.ip);
        connection_release_banned_ip (client->connection.ip);
        client->flags &= ~CLIENT_IP_BAN_LIFT;
    }

    connection_close (&client->connection);
    if (client->parser)
        httpp_destroy (client->parser);

    global_lock ();
    global.clients--;
    stats_event_args (NULL, "clients", "%d", global.clients);
    config_clear_listener (client->server_conn);
    global_unlock ();

    /* we need to free client specific format data (if any) */
    if (client->free_client_data)
        client->free_client_data (client);

    free(client->username);
    free(client->password);

    free(client);
}
Пример #17
0
static int _check_pass_ice(http_parser_t *parser, const char *correctpass)
{
    const char *password;

    password = httpp_getvar(parser, "ice-password");
    if(!password)
        password = "";

    if (strcmp(password, correctpass))
        return 0;
    else
        return 1;
}
Пример #18
0
static int _check_pass_icy(http_parser_t *parser, const char *correctpass)
{
    const char *password;

    password = httpp_getvar(parser, HTTPP_VAR_ICYPASSWORD);
    if(!password)
        return 0;

    if (strcmp(password, correctpass))
        return 0;
    else
        return 1;
}
Пример #19
0
auth_result auth_check_client(source_t *source, client_t *client)
{
    auth_t *authenticator = source->authenticator;
    auth_result result;

    if(authenticator) {
        /* This will look something like "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" */
        char *header = httpp_getvar(client->parser, "authorization");
        char *userpass, *tmp;
        char *username, *password;
    
        if(header == NULL)
            return AUTH_FAILED;
    
        if(strncmp(header, "Basic ", 6)) {
            INFO0("Authorization not using Basic");
            return 0;
        }
        
        userpass = util_base64_decode(header+6);
        if(userpass == NULL) {
            WARN1("Base64 decode of Authorization header \"%s\" failed",
                    header+6);
            return AUTH_FAILED;
        }
        
        tmp = strchr(userpass, ':');
        if(!tmp) { 
            free(userpass);
            return AUTH_FAILED;
        }

        *tmp = 0;
        username = userpass;
        password = tmp+1;

        result = authenticator->authenticate(
                authenticator, source, username, password);

        if(result == AUTH_OK)
            client->username = strdup(username);

        free(userpass);

        return result;
    }
    else
        return AUTH_FAILED;
}
Пример #20
0
int connection_check_source_pass(http_parser_t *parser, char *mount)
{
    ice_config_t *config = config_get_config();
    char *pass = config->source_password;
    char *user = "******";
    int ret;
    int ice_login = config->ice_login;
    char *protocol;

    mount_proxy *mountinfo = config->mounts;
    thread_mutex_lock(&(config_locks()->mounts_lock));

    while(mountinfo) {
        if(!strcmp(mountinfo->mountname, mount)) {
            if(mountinfo->password)
                pass = mountinfo->password;
            if(mountinfo->username)
                user = mountinfo->username;
            break;
        }
        mountinfo = mountinfo->next;
    }

    thread_mutex_unlock(&(config_locks()->mounts_lock));

    if(!pass) {
        WARN0("No source password set, rejecting source");
        config_release_config();
        return 0;
    }

    protocol = httpp_getvar(parser, HTTPP_VAR_PROTOCOL);
    if(protocol != NULL && !strcmp(protocol, "ICY")) {
        ret = _check_pass_icy(parser, pass);
    }
    else {
        ret = _check_pass_http(parser, user, pass);
        if(!ret && ice_login)
        {
            ret = _check_pass_ice(parser, pass);
            if(ret)
                WARN0("Source is using deprecated icecast login");
        }
    }
    config_release_config();
    return ret;
}
Пример #21
0
static auth_client *auth_client_setup (const char *mount, client_t *client)
{
    /* This will look something like "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" */
    const char *header = httpp_getvar(client->parser, "authorization");
    char *userpass, *tmp;
    char *username, *password;
    auth_client *auth_user;

    do
    {
        if (header == NULL)
            break;

        if (strncmp(header, "Basic ", 6) == 0)
        {
            userpass = util_base64_decode (header+6);
            if (userpass == NULL)
            {
                ICECAST_LOG_WARN("Base64 decode of Authorization header \"%s\" failed",
                        header+6);
                break;
            }

            tmp = strchr(userpass, ':');
            if (tmp == NULL)
            { 
                free (userpass);
                break;
            }

            *tmp = 0;
            username = userpass;
            password = tmp+1;
            client->username = strdup (username);
            client->password = strdup (password);
            free (userpass);
            break;
        }
        ICECAST_LOG_INFO("unhandled authorization header: %s", header);

    } while (0);

    auth_user = calloc (1, sizeof(auth_client));
    auth_user->mount = strdup (mount);
    auth_user->client = client;
    return auth_user;
}
Пример #22
0
/* 
** ADDR IDENT USER DATE REQUEST CODE BYTES REFERER AGENT [TIME]
**
** ADDR = client->con->ip
** IDENT = always - , we don't support it because it's useless
** USER = client->username
** DATE = _make_date(client->con->con_time)
** REQUEST = build from client->parser
** CODE = client->respcode
** BYTES = client->con->sent_bytes
** REFERER = get from client->parser
** AGENT = get from client->parser
** TIME = timing_get_time() - client->con->con_time
*/
void logging_access(client_t *client)
{
    char datebuf[128];
    char reqbuf[1024];
    struct tm thetime;
    time_t now;
    time_t stayed;
    const char *referrer, *user_agent, *username;

    now = time(NULL);

    localtime_r (&now, &thetime);
    /* build the data */
#ifdef _WIN32
    memset(datebuf, '\000', sizeof(datebuf));
    get_clf_time(datebuf, sizeof(datebuf)-1, &thetime);
#else
    strftime (datebuf, sizeof(datebuf), LOGGING_FORMAT_CLF, &thetime);
#endif
    /* build the request */
    snprintf (reqbuf, sizeof(reqbuf), "%s %s %s/%s",
            httpp_getvar (client->parser, HTTPP_VAR_REQ_TYPE),
            httpp_getvar (client->parser, HTTPP_VAR_URI),
            httpp_getvar (client->parser, HTTPP_VAR_PROTOCOL),
            httpp_getvar (client->parser, HTTPP_VAR_VERSION));

    stayed = now - client->con->con_time;

    if (client->username == NULL)
        username = "******"; 
    else
        username = client->username;

    referrer = httpp_getvar (client->parser, "referer");
    if (referrer == NULL)
        referrer = "-";

    user_agent = httpp_getvar (client->parser, "user-agent");
    if (user_agent == NULL)
        user_agent = "-";

    log_write_direct (accesslog,
            "%s - %s [%s] \"%s\" %d %" PRIu64 " \"%s\" \"%s\" %lu",
            client->con->ip,
            username,
            datebuf,
            reqbuf,
            client->respcode,
            client->con->sent_bytes,
            referrer,
            user_agent,
            (unsigned long)stayed);
}
Пример #23
0
static void ebml_apply_client (format_plugin_t *plugin, client_t *client)
{
    ebml_source_state_t *ebml_source_state = plugin->_state;
    const char *s;

    refbuf_release (ebml_source_state->header);
    ebml_source_state->header = NULL;
    ebml_destroy (ebml_source_state->ebml);
    ebml_source_state->ebml = NULL;
    free (plugin->contenttype);

    if (client == NULL)
        return;

    s = plugin->parser ? httpp_getvar (plugin->parser, "content-type") : NULL;
    plugin->contenttype = strdup (s ? s : "video/x-matroska");
    ebml_source_state->ebml = ebml_create();
}
Пример #24
0
/* Decide whether we need to start a source or just process a source
 * admin request.
 */
void auth_postprocess_source (auth_client *auth_user)
{
    client_t *client = auth_user->client;
    const char *mount = auth_user->mount;
    const char *req = httpp_getvar (client->parser, HTTPP_VAR_URI);

    auth_user->client = NULL;
    if (strcmp (req, "/admin.cgi") == 0 || strncmp ("/admin/metadata", req, 15) == 0)
    {
        DEBUG2 ("metadata request (%s, %s)", req, mount);
        admin_mount_request (client, "metadata");
    }
    else
    {
        DEBUG1 ("on mountpoint %s", mount);
        source_startup (client, mount);
    }
}
Пример #25
0
void httpp_setvar(http_parser_t *parser, const char *name, const char *value)
{
    http_var_t *var;

    if (name == NULL || value == NULL)
        return;

    var = (http_var_t *)amalloc(sizeof(http_var_t));

    var->name = strdup(name);
    var->value = strdup(value);

    if (httpp_getvar(parser, name) == NULL) {
        avl_insert(parser->vars, (void *)var);
    } else {
        avl_delete(parser->vars, (void *)var, _free_vars);
        avl_insert(parser->vars, (void *)var);
    }
}
Пример #26
0
static void format_mp3_apply_settings (client_t *client, format_plugin_t *format, mount_proxy *mount)
{
    mp3_state *source_mp3 = format->_state;

    if (mount == NULL || mount->mp3_meta_interval <= 0)
    {
        char *metadata = httpp_getvar (client->parser, "icy-metaint");
        source_mp3->interval = -1;
        if (metadata)
        {
            int interval = atoi (metadata);
            if (interval > 0)
                source_mp3->interval = interval;
        }
    }
    else
        source_mp3->interval = mount->mp3_meta_interval;
    DEBUG1 ("mp3 interval %d", source_mp3->interval);
}
Пример #27
0
void stats_listener_to_xml (client_t *listener, xmlNodePtr parent)
{
    const char *useragent;
    char buf[30];

    xmlNodePtr node = xmlNewChild (parent, NULL, XMLSTR("listener"), NULL);

    snprintf (buf, sizeof (buf), "%lu", listener->connection.id);
    xmlSetProp (node, XMLSTR("id"), XMLSTR(buf));

    xmlNewChild (node, NULL, XMLSTR("IP"), XMLSTR(listener->connection.ip));

    useragent = httpp_getvar (listener->parser, "user-agent");
    if (useragent && xmlCheckUTF8((unsigned char *)useragent))
    {
        xmlChar *str = xmlEncodeEntitiesReentrant (parent->doc, XMLSTR(useragent));
        xmlNewChild (node, NULL, XMLSTR("UserAgent"), str);
        xmlFree (str);
    }

    if ((listener->flags & (CLIENT_ACTIVE|CLIENT_IN_FSERVE)) == CLIENT_ACTIVE)
    {
        source_t *source = listener->shared_data;
        snprintf (buf, sizeof (buf), "%"PRIu64, source->client->queue_pos - listener->queue_pos);
    }
    else
        snprintf (buf, sizeof (buf), "0");
    xmlNewChild (node, NULL, XMLSTR("lag"), XMLSTR(buf));

    if (listener->worker)
    {
        snprintf (buf, sizeof (buf), "%lu",
                (unsigned long)(listener->worker->current_time.tv_sec - listener->connection.con_time));
        xmlNewChild (node, NULL, XMLSTR("Connected"), XMLSTR(buf));
    }
    if (listener->username)
    {
        xmlChar *str = xmlEncodeEntitiesReentrant (parent->doc, XMLSTR(listener->username));
        xmlNewChild (node, NULL, XMLSTR("username"), str);
        xmlFree (str);
    }
}
Пример #28
0
static void url_stream_auth (auth_client *auth_user)
{
    client_t *client = auth_user->client;
    auth_url *url = auth_user->auth->state;
    auth_thread_data *atd = auth_user->thread_data;
    char *mount, *host, *user, *pass, *ipaddr, *admin="";
    char post [4096];

    if (strchr (url->stream_auth, '@') == NULL)
    {
        if (url->userpwd)
            curl_easy_setopt (atd->curl, CURLOPT_USERPWD, url->userpwd);
        else
            curl_easy_setopt (atd->curl, CURLOPT_USERPWD, "");
    }
    else
        curl_easy_setopt (atd->curl, CURLOPT_USERPWD, "");
    curl_easy_setopt (atd->curl, CURLOPT_URL, url->stream_auth);
    curl_easy_setopt (atd->curl, CURLOPT_POSTFIELDS, post);
    curl_easy_setopt (atd->curl, CURLOPT_WRITEHEADER, auth_user);
    curl_easy_setopt (atd->curl, CURLOPT_WRITEDATA, auth_user);
    if (strcmp (auth_user->mount, httpp_getvar (client->parser, HTTPP_VAR_URI)) != 0)
        admin = "&admin=1";
    mount = util_url_escape (auth_user->mount);
    host = util_url_escape (auth_user->hostname);
    user = util_url_escape (client->username);
    pass = util_url_escape (client->password);
    ipaddr = util_url_escape (client->connection.ip);

    snprintf (post, sizeof (post),
            "action=stream_auth&mount=%s&ip=%s&server=%s&port=%d&user=%s&pass=%s%s",
            mount, ipaddr, host, auth_user->port, user, pass, admin);
    free (ipaddr);
    free (user);
    free (pass);
    free (mount);
    free (host);

    client->flags &= ~CLIENT_AUTHENTICATED;
    if (curl_easy_perform (atd->curl))
        WARN3 ("auth to server %s (%s) failed with %s", url->stream_auth, auth_user->mount, atd->errormsg);
}
Пример #29
0
/* Called when the stream ends so that the authentication engine can do
 * any authentication cleanup
 */
void auth_stream_end (mount_proxy *mountinfo, source_t *source)
{
    if (mountinfo && mountinfo->auth && mountinfo->auth->stream_end)
    {
        client_t *client = source->client;
        const char *agent = httpp_getvar (client->parser, "user-agent"),
                           *mount = source->mount;
        auth_client *auth_user = auth_client_setup (mount, NULL);

        // use a blank client copy to avoid a race
        auth_user->client = calloc (1, sizeof (client_t));
        auth_user->client->connection.ip = strdup (client->connection.ip);
        if (agent)
            auth_user->client->shared_data = strdup (agent);
        auth_user->process = stream_end_callback;
        INFO1 ("request stream end for \"%s\"", mount);

        queue_auth_client (auth_user, mountinfo);
    }
}
Пример #30
0
static int command_buildm3u (client_t *client, const char *mount)
{
    const char *username = NULL;
    const char *password = NULL;
    ice_config_t *config;
    const char *host = httpp_getvar (client->parser, "host");

    if (COMMAND_REQUIRE(client, "username", username) < 0 ||
            COMMAND_REQUIRE(client, "password", password) < 0)
        return client_send_400 (client, "missing arg, username/password");

    client->respcode = 200;
    config = config_get_config();
    if (host)
    {
        char port[10] = "";
        if (strchr (host, ':') == NULL)
            snprintf (port, sizeof (port), ":%u",  config->port);
        snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
                "HTTP/1.0 200 OK\r\n"
                "Content-Type: audio/x-mpegurl\r\n"
                "Content-Disposition = attachment; filename=listen.m3u\r\n\r\n" 
                "http://%s:%s@%s%s%s\r\n",
                username, password,
                host, port, mount);
    }
    else
    {
        snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
                "HTTP/1.0 200 OK\r\n"
                "Content-Type: audio/x-mpegurl\r\n"
                "Content-Disposition = attachment; filename=listen.m3u\r\n\r\n" 
                "http://%s:%s@%s:%d%s\r\n",
                username, password,
                config->hostname, config->port, mount);
    }
    config_release_config();

    client->refbuf->len = strlen (client->refbuf->data);
    return fserve_setup_client (client);
}