X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=server.cpp;h=6b92fc6af5eb6eec6fa9983a587681dfc2e14623;hp=60836a74ca52774855f80c2a3ce623545dbc534f;hb=fbfb955ee7233030357ec32c0d613f9279700d70;hpb=e8740ea38fa1b54672a83744549fcd1463403d98 diff --git a/server.cpp b/server.cpp index 60836a7..6b92fc6 100644 --- a/server.cpp +++ b/server.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -197,11 +196,11 @@ void Server::do_work() for (map::iterator stream_it = streams.begin(); stream_it != streams.end(); ++stream_it) { - Stream *stream = stream_it->second; - for (size_t i = 0; i < stream->to_process.size(); ++i) { - process_client(stream->to_process[i]); + vector to_process; + swap(stream_it->second->to_process, to_process); + for (size_t i = 0; i < to_process.size(); ++i) { + process_client(to_process[i]); } - stream->to_process.clear(); } } } @@ -362,34 +361,27 @@ read_request_again: return; } - // Guard against overlong requests gobbling up all of our space. - if (client->request.size() + ret > MAX_CLIENT_REQUEST) { + RequestParseStatus status = wait_for_double_newline(&client->request, buf, ret); + + switch (status) { + case RP_OUT_OF_SPACE: fprintf(stderr, "WARNING: fd %d sent overlong request!\n", client->sock); close_client(client); return; - } - - // See if we have \r\n\r\n anywhere in the request. We start three bytes - // before what we just appended, in case we just got the final character. - size_t existing_req_bytes = client->request.size(); - client->request.append(string(buf, buf + ret)); - - size_t start_at = (existing_req_bytes >= 3 ? existing_req_bytes - 3 : 0); - const char *ptr = reinterpret_cast( - memmem(client->request.data() + start_at, client->request.size() - start_at, - "\r\n\r\n", 4)); - if (ptr == NULL) { + case RP_NOT_FINISHED_YET: // OK, we don't have the entire header yet. Fine; we'll get it later. // See if there's more data for us. goto read_request_again; - } - - if (ptr != client->request.data() + client->request.size() - 4) { + case RP_EXTRA_DATA: fprintf(stderr, "WARNING: fd %d had junk data after request!\n", client->sock); close_client(client); return; + case RP_FINISHED: + break; } + assert(status == RP_FINISHED); + int error_code = parse_request(client); if (error_code == 200) { construct_header(client); @@ -583,6 +575,13 @@ void Server::construct_error(Client *client, int error_code) exit(1); } } + +template +void delete_from(vector *v, T elem) +{ + typename vector::iterator new_end = remove(v->begin(), v->end(), elem); + v->erase(new_end, v->end()); +} void Server::close_client(Client *client) { @@ -593,12 +592,8 @@ void Server::close_client(Client *client) // This client could be sleeping, so we'll need to fix that. (Argh, O(n).) if (client->stream != NULL) { - vector::iterator new_end = - remove(client->stream->sleeping_clients.begin(), - client->stream->sleeping_clients.end(), - client); - client->stream->sleeping_clients.erase( - new_end, client->stream->sleeping_clients.end()); + delete_from(&client->stream->sleeping_clients, client); + delete_from(&client->stream->to_process, client); } // Bye-bye!