Exemplo n.º 1
0
Arquivo: owl.c Projeto: eliasson/owl
static void logged_out_callback(sp_session *session) {
    TRACE("logged_out_callback\n");

    struct owl_state* state = sp_session_userdata(session);

    state->state = OWL_STATE_INITIALIZED;
    INFO("Logged out from Spotify\n");

    respond_success(state->http_request);
}
Exemplo n.º 2
0
Arquivo: owl.c Projeto: eliasson/owl
//
// -- Spotify callbacks ---------------------------------------------------------------------------
//
static void logged_in_callback(sp_session *session, sp_error error) {
    TRACE("logged_in_callback\n");
    struct owl_state* state = sp_session_userdata(session);

    if(error == SP_ERROR_OK) {
        state->state = OWL_STATE_IDLE;
        INFO("Logged in to Spotify!\n");
        respond_success(state->http_request);
    }
    else {
        state->state = OWL_STATE_INITIALIZED;
        ERROR("Failed to login to Spotify: %s\n", sp_error_message(error));

        respond_error(state->http_request, OWL_HTTP_ERROR_LOGIN, sp_error_message(error));
    }
}
Exemplo n.º 3
0
void handle_client(int fd, const char * userTest, const char * passTest) {
    FILE * fp = fdopen(fd, "w+");
    char * user, * pass, * path;
    long long initial;
    if (read_client_request(fp, &user, &pass, &path, &initial) < 0) {
        return;
    }
    if (strcmp(user, userTest) != 0 || strcmp(pass, passTest) != 0) {
        respond_error(fp, PROTOCOL_ERROR_AUTH, "Login incorrect.");
        goto handleError;
    }
#ifdef __linux__
    struct stat64 info;
    if (stat64(path, &info) < 0) {
#else
    struct stat info
    if (stat(path, &info) < 0) {
#endif
        respond_error(fp, PROTOCOL_ERROR_NO_FILE, "Could not stat file.");
        goto handleError;
    }
    if (S_ISDIR(info.st_mode)) {
        respond_error(fp, PROTOCOL_ERROR_NOT_FILE, "Could not send directory.");
        goto handleError;
    }
    if (initial > info.st_size) {
        respond_error(fp, PROTOCOL_ERROR_INVALID_INITIAL, "Invalid initial offset.");
        goto handleError;
    }
#ifdef __linux__
    FILE * readFile = fopen64(path, "r");
#else
    FILE * readfile = fopen(path, "r");
#endif
    if (!readFile) {
        perror("fopen");
        respond_error(fp, PROTOCOL_ERROR_INTERNAL, "fopen() failed");
        goto handleError;
    }
    
    if (respond_success(fp, info.st_size - initial) < 0) {
        fclose(readFile);
        goto handleError;
    }
    
    // read file from start offset
    fseek(readFile, initial, SEEK_SET);
    char buff[512];
    while (!feof(readFile)) {
        int got = fread(buff, 1, 512, readFile);
        if (got == 0) break;
        if (fwrite(buff, 1, got, fp) != got) {
            break;
        }
    }
    fclose(readFile);
    
handleError:
    fclose(fp);
    free(user);
    free(pass);
    free(path);
    return;
}

void sigchild_handler(int signal) {
    int status;
    wait(&status);
}
Exemplo n.º 4
0
Arquivo: owl.c Projeto: eliasson/owl
//
// Function called when a new HTTP request have been recieved.
//
static void http_handler(struct evhttp_request *request, void *userdata) {
    struct owl_state* state = userdata;

    // Setup general response headers
    struct evkeyvalq *headers = evhttp_request_get_output_headers(request);
    evhttp_add_header(headers, "Server", USER_AGENT);

    // Get the requested URI
    const char* uri = evhttp_request_get_uri(request);
    const int http_method = evhttp_request_get_command(request);

    if( http_method != EVHTTP_REQ_GET &&
            http_method != EVHTTP_REQ_PUT &&
            http_method != EVHTTP_REQ_POST) {
        evhttp_send_error(request, 501, "Not Implemented");
        return;
    }

    TRACE("Received HTTP request: %s (method %d)\n", uri, http_method);

    // Keep the request for async usage
    state->http_request = request;

    //
    // Retrieve application state (sync)
    if(string_starts_with(uri, "/api/state") && http_method == EVHTTP_REQ_GET) {
        state_action(state);
    }

    //
    // Shutdown owl application (async)
    else if(string_starts_with(uri, "/api/shutdown") && http_method == EVHTTP_REQ_GET) {
        shutdown_action(state);
    }

    //
    // Try to login to Spotify (async)
    else if(string_starts_with(uri, "/api/login") && http_method == EVHTTP_REQ_GET) {
        char* username = extract_uri_section(2, uri);
        char* password = extract_uri_section(3, uri);

        if(username != NULL && password != NULL) {
            login_to_spotify_action(state, username, password);
        }
        else {
            WARN("Could not extract username and password in order to login to Spotify!\n");
            respond_error(request, OWL_HTTO_ERROR_NO_LOGIN_DETAILS, "No username or password given");
        }
    }

    else if(string_starts_with(uri, "/api/login") && http_method == EVHTTP_REQ_POST) {
        TRACE("POST LOGIN\n");
        get_post_argument(request, "username");
        evhttp_send_error(request, 501, "Not Implemented");
    }

    //
    // Logout from spotify (async)
    else if(string_starts_with(uri, "/api/logout") && http_method == EVHTTP_REQ_GET) {
        if(state->state > OWL_STATE_LOGGING_IN && state->state < OWL_STATE_LOGGING_OUT)
            logout_from_spotify_action(state);
        else
            respond_success(request);
    }

    //
    // Clear the entire queue
    else if(string_starts_with(uri, "/api/queue/clear") && http_method == EVHTTP_REQ_GET) {
        if(state->state < OWL_STATE_IDLE || state->state > OWL_STATE_PLAYING) {
            respond_error(request, OWL_HTTP_ERROR_NOT_LOGGED_IN, "Operation not allowed when not logged in");
        }
        else {
            const int size = queue_size(state->spotify_state->queue);
            for(int i = 0; i < size; i++) {
                owl_track *track = pop_from_queue(state->spotify_state->queue);
                free_track(track);
            }
            respond_success(request);
        }
    }

    //
    // Get the current playback queue (sync)
    else if(string_starts_with(uri, "/api/queue") && http_method == EVHTTP_REQ_GET) {
        if(state->state < OWL_STATE_IDLE || state->state > OWL_STATE_PLAYING) {
            WARN("Operation not allowed at this state (%d)\n", state->state);
            respond_error(request, OWL_HTTP_ERROR_NOT_LOGGED_IN, "Operation not allowed when not logged in");
        }
        else {
            respond_with_queue(state->http_request, state->spotify_state->queue);
        }
    }

    //
    // Serve static file immediately
    else {
        // Create the buffer to retrn as content
        struct evbuffer *content_buffer = evbuffer_new();

        // If not a handler this is a static request
        char *static_file = (char *) malloc(strlen(doc_root) + strlen(uri) + 1);
        stpcpy(stpcpy(static_file, doc_root), uri);

        TRACE("Looking for static file: %s\n", static_file);

        bool file_exists = 1;
        struct stat st;
        if(stat(static_file, &st) == -1 || S_ISDIR(st.st_mode)) {
            file_exists = 0;
            evhttp_send_error(request, HTTP_NOTFOUND, "Not Found");
        }

        if(file_exists) {
            const int file_size = st.st_size;
            FILE *fp = fopen(static_file, "r");
            const char* content_type = resolve_content_type(static_file);

            evbuffer_add_file(content_buffer, fileno(fp), 0, file_size); // will close

            TRACE("Resolving content type for filename: %s to: %s\n", static_file, content_type);
            evhttp_add_header(headers, "Content-Type", content_type);
            evhttp_send_reply(request, HTTP_OK, "OK", content_buffer);
        }
        free(static_file);

        // Send the data
        evhttp_send_reply(request, HTTP_OK, USER_AGENT, content_buffer);

        // Free memrory
        evbuffer_free(content_buffer);
    }
    return;
}