int handle_incoming_message(int skt, struct sockaddr_in *sin, struct s_client2server_msg_record *rec) /* Purpose:Process message which has just arrived from client. A 'message' could be a login/logout request or a ping. Params: skt - client's port to respond to sin - client's IP address, in sockaddr_in structure rec - data received from client Return: result (0=success, nonzero=failure) */ { char clientIP[MAX_STR_LEN+1]; unsigned char *ptr; int res=0; // echo_ipaddr_to_screen(&sin->sin_addr); ptr = (unsigned char*)(&sin->sin_addr); sprintf(clientIP, "%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]); log_it(debug, "clientIP = %s", clientIP); log_it(debug, "%s message from %s [%s] (port %d)", tmsg_to_string(rec->msg_type), clientIP, rec->body, rec->port); switch(rec->msg_type) { case login: res=handle_login_request(skt, rec, clientIP); break; case ping: res=handle_ping_request(skt, rec, clientIP); break; case progress_rpt: res=handle_progress_rpt(skt, rec, clientIP); break; case logout: res=handle_logout_request(skt, rec, clientIP); break; case user_req: res=handle_user_request(skt, rec, clientIP); break; default: log_it(error, "...How do I handle it?"); } return(res); }
// Request dispatcher static void handle_request(struct evhttp_request *request, void *userdata) { evhttp_connection_set_timeout(request->evcon, 1); evhttp_add_header(evhttp_request_get_output_headers(request), "Server", "[email protected]/spotify-api-server"); // Check request method int http_method = evhttp_request_get_command(request); switch (http_method) { case EVHTTP_REQ_GET: case EVHTTP_REQ_PUT: case EVHTTP_REQ_POST: break; default: evhttp_send_error(request, HTTP_NOTIMPL, "Not Implemented"); return; } struct state *state = userdata; sp_session *session = state->session; char *uri = evhttp_decode_uri(evhttp_request_get_uri(request)); char *entity = strtok(uri, "/"); if (entity == NULL) { evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request"); free(uri); return; } // Handle requests to /user/<user_name>/inbox if (strncmp(entity, "user", 4) == 0) { char *username = strtok(NULL, "/"); if (username == NULL) { evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request"); free(uri); return; } char *action = strtok(NULL, "/"); handle_user_request(request, action, username, session); free(uri); return; } // Handle requests to /playlist/<playlist_uri>/<action> if (strncmp(entity, "playlist", 8) != 0) { evhttp_send_error(request, HTTP_BADREQUEST, "Bad Request"); free(uri); return; } char *playlist_uri = strtok(NULL, "/"); if (playlist_uri == NULL) { switch (http_method) { case EVHTTP_REQ_PUT: case EVHTTP_REQ_POST: put_playlist(NULL, request, session); break; default: send_error(request, HTTP_BADREQUEST, "Bad Request"); break; } free(uri); return; } sp_link *playlist_link = sp_link_create_from_string(playlist_uri); if (playlist_link == NULL) { send_error(request, HTTP_NOTFOUND, "Playlist link not found"); free(uri); return; } if (sp_link_type(playlist_link) != SP_LINKTYPE_PLAYLIST) { sp_link_release(playlist_link); send_error(request, HTTP_BADREQUEST, "Not a playlist link"); free(uri); return; } sp_playlist *playlist = sp_playlist_create(session, playlist_link); sp_link_release(playlist_link); if (playlist == NULL) { send_error(request, HTTP_NOTFOUND, "Playlist not found"); free(uri); return; } sp_playlist_add_ref(playlist); // Dispatch request char *action = strtok(NULL, "/"); // Default request handler handle_playlist_fn request_callback = ¬_implemented; void *callback_userdata = session; switch (http_method) { case EVHTTP_REQ_GET: { if (action == NULL) { // Send entire playlist request_callback = &get_playlist; } else if (strncmp(action, "collaborative", 13) == 0) { request_callback = &get_playlist_collaborative; } else if (strncmp(action, "subscribers", 11) == 0) { request_callback = &get_playlist_subscribers; } } break; case EVHTTP_REQ_PUT: case EVHTTP_REQ_POST: { if (strncmp(action, "add", 3) == 0) { request_callback = &put_playlist_add_tracks; } else if (strncmp(action, "remove", 6) == 0) { request_callback = &put_playlist_remove_tracks; } else if (strncmp(action, "patch", 5) == 0) { callback_userdata = state; request_callback = &put_playlist_patch; } } break; } if (sp_playlist_is_loaded(playlist)) { request_callback(playlist, request, callback_userdata); } else { // Wait for playlist to load register_playlist_callbacks(playlist, request, request_callback, &playlist_state_changed_callbacks, callback_userdata); } free(uri); }