void _dacp_client_web_connection_response_received_callback(web_client_connection_p connection, web_request_p request, web_response_p response, void* ctx) { struct dacp_client_t* dc = (struct dacp_client_t*)ctx; if (web_response_get_status(response) == 200 && dc->callbacks.playback_state_changed != NULL) { web_headers_p headers = web_response_get_headers(response); size_t content_length; const char* s_content_type = web_headers_value(headers, "Content-Type"); if (s_content_type != NULL && strcmp(s_content_type, "application/x-dmap-tagged") == 0 && (content_length = web_response_get_content(response, NULL, 0)) > 0) { char data[content_length]; web_response_get_content(response, data, content_length); dmap_p dmap = dmap_create(); dmap_parse(dmap, data, content_length); dmap_p container = dmap_container_for_atom_identifer(dmap, "com.airfloat.nowplayingcontainer"); if (container != NULL) { char now_playing = dmap_char_for_atom_identifer(container, "com.airfloat.nowplayingstatus"); dc->playback_state = now_playing; dc->callbacks.playback_state_changed(dc, dc->playback_state, dc->callbacks.ctx.playback_state_changed); } object_release(dmap); } } }
ssize_t web_request_parse(struct web_request_t* wr, const void* data, size_t data_size) { size_t ret = 0; char* buffer = malloc(data_size); memcpy(buffer, data, data_size); const char* content_start = web_tools_get_content_start(buffer, data_size);; if (content_start != NULL) { size_t header_length = content_start - buffer; char header[header_length]; memcpy(header, buffer, content_start - buffer); log_data(LOG_INFO, data, content_start - buffer); char* header_start = header; header_length = web_tools_convert_new_lines(header_start, header_length); char* cmd = header_start; char* path = NULL; char* protocol = NULL; while (header_start[0] != '\n') { if (header_start[0] == ' ') { if (path == NULL) path = (char*)&header_start[1]; else if (protocol == NULL) protocol = (char*)&header_start[1]; header_start[0] = '\0'; } header_start++; header_length--; } header_start[0] = '\0'; if (path == NULL || protocol == NULL) { free(buffer); return -1; } header_start++; header_length--; web_headers_p headers = web_headers_create(); web_headers_parse(headers, header_start, header_length); size_t content_length = 0; const char* s_content_length = web_headers_value(headers, "Content-Length"); if (s_content_length != NULL) content_length = atoi(s_content_length); size_t actual_content_length = data_size - (content_start - buffer); if (content_length <= actual_content_length) { wr->command = (char*)malloc(strlen(cmd) + 1); strcpy(wr->command, cmd); wr->path = (char*)malloc(strlen(path) + 1); strcpy(wr->path, path); wr->protocol = (char*)malloc(strlen(protocol) + 1); strcpy(wr->protocol, protocol); web_headers_destroy(wr->headers); wr->headers = headers; log_message(LOG_INFO, "(Complete) - %d bytes", content_length); web_request_set_content(wr, (void*)content_start, content_length); ret = content_start + content_length - buffer; } else { log_message(LOG_INFO, "(Incomplete)"); web_headers_destroy(headers); } } free(buffer); return ret; }