{"thread":{"id":"2589","subject":"[PATCH 2/5] Make http-fetch request types more clear","startedAt":"2005-11-18T19:03:04Z","lastAt":"2005-11-18T19:03:04Z","messageCount":1,"participants":["Nick Hengeveld"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"12234","messageId":"20051118190304.GG3968@reactrix.com","threadId":"2589","inReplyTo":null,"subject":"[PATCH 2/5] Make http-fetch request types more clear","fromName":"Nick Hengeveld","fromEmail":"nickh@reactrix.com","sentAt":"2005-11-18T19:03:04Z","receivedAt":"2005-11-18T19:03:04Z","isPatch":true,"sender":{"key":"nickh@reactrix.com","avatar":null},"body":"Rename object request functions and data to make it more clear which type\nof request is being processed - this is a response to the introduction of\nslot callbacks and the definition of different types of requests such as\nalternates_request.\n\nSigned-off-by: Nick Hengeveld <nickh@reactrix.com>\n\n\n---\n\n http-fetch.c |  275 +++++++++++++++++++++++++++++-----------------------------\n 1 files changed, 139 insertions(+), 136 deletions(-)\n\napplies-to: ca1aeba57d4c1ac8d7e6550dba68ead4539696e5\nd3d94b6074099a6aa68280430d38678028268678\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 6a9eaf3..53a7dbf 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -21,14 +21,14 @@ struct alt_base\n \n static struct alt_base *alt = NULL;\n \n-enum transfer_state {\n+enum object_request_state {\n \tWAITING,\n \tABORTED,\n \tACTIVE,\n \tCOMPLETE,\n };\n \n-struct transfer_request\n+struct object_request\n {\n \tunsigned char sha1[20];\n \tstruct alt_base *repo;\n@@ -36,7 +36,7 @@ struct transfer_request\n \tchar filename[PATH_MAX];\n \tchar tmpfile[PATH_MAX];\n \tint local;\n-\tenum transfer_state state;\n+\tenum object_request_state state;\n \tCURLcode curl_result;\n \tchar errorstr[CURL_ERROR_SIZE];\n \tlong http_code;\n@@ -46,10 +46,10 @@ struct transfer_request\n \tint zret;\n \tint rename;\n \tstruct active_request_slot *slot;\n-\tstruct transfer_request *next;\n+\tstruct object_request *next;\n };\n \n-struct alt_request {\n+struct alternates_request {\n \tchar *base;\n \tchar *url;\n \tstruct buffer *buffer;\n@@ -57,7 +57,7 @@ struct alt_request {\n \tint http_specific;\n };\n \n-static struct transfer_request *request_queue_head = NULL;\n+static struct object_request *object_queue_head = NULL;\n \n static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,\n \t\t\t       void *data)\n@@ -65,24 +65,24 @@ static size_t fwrite_sha1_file(void *ptr\n \tunsigned char expn[4096];\n \tsize_t size = eltsize * nmemb;\n \tint posn = 0;\n-\tstruct transfer_request *request = (struct transfer_request *)data;\n+\tstruct object_request *obj_req = (struct object_request *)data;\n \tdo {\n-\t\tssize_t retval = write(request->local,\n+\t\tssize_t retval = write(obj_req->local,\n \t\t\t\t       ptr + posn, size - posn);\n \t\tif (retval < 0)\n \t\t\treturn posn;\n \t\tposn += retval;\n \t} while (posn < size);\n \n-\trequest->stream.avail_in = size;\n-\trequest->stream.next_in = ptr;\n+\tobj_req->stream.avail_in = size;\n+\tobj_req->stream.next_in = ptr;\n \tdo {\n-\t\trequest->stream.next_out = expn;\n-\t\trequest->stream.avail_out = sizeof(expn);\n-\t\trequest->zret = inflate(&request->stream, Z_SYNC_FLUSH);\n-\t\tSHA1_Update(&request->c, expn,\n-\t\t\t    sizeof(expn) - request->stream.avail_out);\n-\t} while (request->stream.avail_in && request->zret == Z_OK);\n+\t\tobj_req->stream.next_out = expn;\n+\t\tobj_req->stream.avail_out = sizeof(expn);\n+\t\tobj_req->zret = inflate(&obj_req->stream, Z_SYNC_FLUSH);\n+\t\tSHA1_Update(&obj_req->c, expn,\n+\t\t\t    sizeof(expn) - obj_req->stream.avail_out);\n+\t} while (obj_req->stream.avail_in && obj_req->zret == Z_OK);\n \tdata_received++;\n \treturn size;\n }\n@@ -91,9 +91,9 @@ static void fetch_alternates(char *base)\n \n static void process_object_response(void *callback_data);\n \n-static void start_request(struct transfer_request *request)\n+static void start_object_request(struct object_request *obj_req)\n {\n-\tchar *hex = sha1_to_hex(request->sha1);\n+\tchar *hex = sha1_to_hex(obj_req->sha1);\n \tchar prevfile[PATH_MAX];\n \tchar *url;\n \tchar *posn;\n@@ -105,53 +105,53 @@ static void start_request(struct transfe\n \tstruct curl_slist *range_header = NULL;\n \tstruct active_request_slot *slot;\n \n-\tsnprintf(prevfile, sizeof(prevfile), \"%s.prev\", request->filename);\n+\tsnprintf(prevfile, sizeof(prevfile), \"%s.prev\", obj_req->filename);\n \tunlink(prevfile);\n-\trename(request->tmpfile, prevfile);\n-\tunlink(request->tmpfile);\n+\trename(obj_req->tmpfile, prevfile);\n+\tunlink(obj_req->tmpfile);\n \n-\tif (request->local != -1)\n-\t\terror(\"fd leakage in start: %d\", request->local);\n-\trequest->local = open(request->tmpfile,\n+\tif (obj_req->local != -1)\n+\t\terror(\"fd leakage in start: %d\", obj_req->local);\n+\tobj_req->local = open(obj_req->tmpfile,\n \t\t\t      O_WRONLY | O_CREAT | O_EXCL, 0666);\n \t/* This could have failed due to the \"lazy directory creation\";\n \t * try to mkdir the last path component.\n \t */\n-\tif (request->local < 0 && errno == ENOENT) {\n-\t\tchar *dir = strrchr(request->tmpfile, '/');\n+\tif (obj_req->local < 0 && errno == ENOENT) {\n+\t\tchar *dir = strrchr(obj_req->tmpfile, '/');\n \t\tif (dir) {\n \t\t\t*dir = 0;\n-\t\t\tmkdir(request->tmpfile, 0777);\n+\t\t\tmkdir(obj_req->tmpfile, 0777);\n \t\t\t*dir = '/';\n \t\t}\n-\t\trequest->local = open(request->tmpfile,\n+\t\tobj_req->local = open(obj_req->tmpfile,\n \t\t\t\t      O_WRONLY | O_CREAT | O_EXCL, 0666);\n \t}\n \n-\tif (request->local < 0) {\n-\t\trequest->state = ABORTED;\n+\tif (obj_req->local < 0) {\n+\t\tobj_req->state = ABORTED;\n \t\terror(\"Couldn't create temporary file %s for %s: %s\\n\",\n-\t\t      request->tmpfile, request->filename, strerror(errno));\n+\t\t      obj_req->tmpfile, obj_req->filename, strerror(errno));\n \t\treturn;\n \t}\n \n-\tmemset(&request->stream, 0, sizeof(request->stream));\n+\tmemset(&obj_req->stream, 0, sizeof(obj_req->stream));\n \n-\tinflateInit(&request->stream);\n+\tinflateInit(&obj_req->stream);\n \n-\tSHA1_Init(&request->c);\n+\tSHA1_Init(&obj_req->c);\n \n-\turl = xmalloc(strlen(request->repo->base) + 50);\n-\trequest->url = xmalloc(strlen(request->repo->base) + 50);\n-\tstrcpy(url, request->repo->base);\n-\tposn = url + strlen(request->repo->base);\n+\turl = xmalloc(strlen(obj_req->repo->base) + 50);\n+\tobj_req->url = xmalloc(strlen(obj_req->repo->base) + 50);\n+\tstrcpy(url, obj_req->repo->base);\n+\tposn = url + strlen(obj_req->repo->base);\n \tstrcpy(posn, \"objects/\");\n \tposn += 8;\n \tmemcpy(posn, hex, 2);\n \tposn += 2;\n \t*(posn++) = '/';\n \tstrcpy(posn, hex + 2);\n-\tstrcpy(request->url, url);\n+\tstrcpy(obj_req->url, url);\n \n \t/* If a previous temp file is present, process what was already\n \t   fetched. */\n@@ -163,7 +163,7 @@ static void start_request(struct transfe\n \t\t\t\tif (fwrite_sha1_file(prev_buf,\n \t\t\t\t\t\t     1,\n \t\t\t\t\t\t     prev_read,\n-\t\t\t\t\t\t     request) == prev_read) {\n+\t\t\t\t\t\t     obj_req) == prev_read) {\n \t\t\t\t\tprev_posn += prev_read;\n \t\t\t\t} else {\n \t\t\t\t\tprev_read = -1;\n@@ -177,24 +177,24 @@ static void start_request(struct transfe\n \t/* Reset inflate/SHA1 if there was an error reading the previous temp\n \t   file; also rewind to the beginning of the local file. */\n \tif (prev_read == -1) {\n-\t\tmemset(&request->stream, 0, sizeof(request->stream));\n-\t\tinflateInit(&request->stream);\n-\t\tSHA1_Init(&request->c);\n+\t\tmemset(&obj_req->stream, 0, sizeof(obj_req->stream));\n+\t\tinflateInit(&obj_req->stream);\n+\t\tSHA1_Init(&obj_req->c);\n \t\tif (prev_posn>0) {\n \t\t\tprev_posn = 0;\n-\t\t\tlseek(request->local, SEEK_SET, 0);\n-\t\t\tftruncate(request->local, 0);\n+\t\t\tlseek(obj_req->local, SEEK_SET, 0);\n+\t\t\tftruncate(obj_req->local, 0);\n \t\t}\n \t}\n \n \tslot = get_active_slot();\n \tslot->callback_func = process_object_response;\n-\tslot->callback_data = request;\n-\trequest->slot = slot;\n+\tslot->callback_data = obj_req;\n+\tobj_req->slot = slot;\n \n-\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, request);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_FILE, obj_req);\n \tcurl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file);\n-\tcurl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);\n+\tcurl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, obj_req->errorstr);\n \tcurl_easy_setopt(slot->curl, CURLOPT_URL, url);\n \tcurl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_pragma_header);\n \n@@ -212,109 +212,111 @@ static void start_request(struct transfe\n \t}\n \n \t/* Try to get the request started, abort the request on error */\n-\trequest->state = ACTIVE;\n+\tobj_req->state = ACTIVE;\n \tif (!start_active_slot(slot)) {\n-\t\trequest->state = ABORTED;\n-\t\trequest->slot = NULL;\n-\t\tclose(request->local); request->local = -1;\n-\t\tfree(request->url);\n+\t\tobj_req->state = ABORTED;\n+\t\tobj_req->slot = NULL;\n+\t\tclose(obj_req->local); obj_req->local = -1;\n+\t\tfree(obj_req->url);\n+\t\treturn;\n \t}\n+\t\n }\n \n-static void finish_request(struct transfer_request *request)\n+static void finish_object_request(struct object_request *obj_req)\n {\n \tstruct stat st;\n \n-\tfchmod(request->local, 0444);\n-\tclose(request->local); request->local = -1;\n+\tfchmod(obj_req->local, 0444);\n+\tclose(obj_req->local); obj_req->local = -1;\n \n-\tif (request->http_code == 416) {\n+\tif (obj_req->http_code == 416) {\n \t\tfprintf(stderr, \"Warning: requested range invalid; we may already have all the data.\\n\");\n-\t} else if (request->curl_result != CURLE_OK) {\n-\t\tif (stat(request->tmpfile, &st) == 0)\n+\t} else if (obj_req->curl_result != CURLE_OK) {\n+\t\tif (stat(obj_req->tmpfile, &st) == 0)\n \t\t\tif (st.st_size == 0)\n-\t\t\t\tunlink(request->tmpfile);\n+\t\t\t\tunlink(obj_req->tmpfile);\n \t\treturn;\n \t}\n \n-\tinflateEnd(&request->stream);\n-\tSHA1_Final(request->real_sha1, &request->c);\n-\tif (request->zret != Z_STREAM_END) {\n-\t\tunlink(request->tmpfile);\n+\tinflateEnd(&obj_req->stream);\n+\tSHA1_Final(obj_req->real_sha1, &obj_req->c);\n+\tif (obj_req->zret != Z_STREAM_END) {\n+\t\tunlink(obj_req->tmpfile);\n \t\treturn;\n \t}\n-\tif (memcmp(request->sha1, request->real_sha1, 20)) {\n-\t\tunlink(request->tmpfile);\n+\tif (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) {\n+\t\tunlink(obj_req->tmpfile);\n \t\treturn;\n \t}\n-\trequest->rename =\n-\t\tmove_temp_to_file(request->tmpfile, request->filename);\n+\tobj_req->rename =\n+\t\tmove_temp_to_file(obj_req->tmpfile, obj_req->filename);\n \n-\tif (request->rename == 0)\n-\t\tpull_say(\"got %s\\n\", sha1_to_hex(request->sha1));\n+\tif (obj_req->rename == 0)\n+\t\tpull_say(\"got %s\\n\", sha1_to_hex(obj_req->sha1));\n }\n \n static void process_object_response(void *callback_data)\n {\n-\tstruct transfer_request *request =\n-\t\t(struct transfer_request *)callback_data;\n+\tstruct object_request *obj_req =\n+\t\t(struct object_request *)callback_data;\n \n-\trequest->curl_result = request->slot->curl_result;\n-\trequest->http_code = request->slot->http_code;\n-\trequest->slot = NULL;\n-\trequest->state = COMPLETE;\n+\tobj_req->curl_result = obj_req->slot->curl_result;\n+\tobj_req->http_code = obj_req->slot->http_code;\n+\tobj_req->slot = NULL;\n+\tobj_req->state = COMPLETE;\n \n \t/* Use alternates if necessary */\n-\tif (request->http_code == 404) {\n+\tif (obj_req->http_code == 404) {\n \t\tfetch_alternates(alt->base);\n-\t\tif (request->repo->next != NULL) {\n-\t\t\trequest->repo =\n-\t\t\t\trequest->repo->next;\n-\t\t\tclose(request->local);\n-\t\t\trequest->local = -1;\n-\t\t\tstart_request(request);\n+\t\tif (obj_req->repo->next != NULL) {\n+\t\t\tobj_req->repo =\n+\t\t\t\tobj_req->repo->next;\n+\t\t\tclose(obj_req->local);\n+\t\t\tobj_req->local = -1;\n+\t\t\tstart_object_request(obj_req);\n \t\t\treturn;\n \t\t}\n \t}\n \n-\tfinish_request(request);\n+\tfinish_object_request(obj_req);\n }\n \n-static void release_request(struct transfer_request *request)\n+static void release_object_request(struct object_request *obj_req)\n {\n-\tstruct transfer_request *entry = request_queue_head;\n+\tstruct object_request *entry = object_queue_head;\n \n-\tif (request->local != -1)\n-\t\terror(\"fd leakage in release: %d\", request->local);\n-\tif (request == request_queue_head) {\n-\t\trequest_queue_head = request->next;\n+\tif (obj_req->local != -1)\n+\t\terror(\"fd leakage in release: %d\", obj_req->local);\n+\tif (obj_req == object_queue_head) {\n+\t\tobject_queue_head = obj_req->next;\n \t} else {\n-\t\twhile (entry->next != NULL && entry->next != request)\n+\t\twhile (entry->next != NULL && entry->next != obj_req)\n \t\t\tentry = entry->next;\n-\t\tif (entry->next == request)\n+\t\tif (entry->next == obj_req)\n \t\t\tentry->next = entry->next->next;\n \t}\n \n-\tfree(request->url);\n-\tfree(request);\n+\tfree(obj_req->url);\n+\tfree(obj_req);\n }\n \n #ifdef USE_CURL_MULTI\n void fill_active_slots(void)\n {\n-\tstruct transfer_request *request = request_queue_head;\n+\tstruct object_request *obj_req = object_queue_head;\n \tstruct active_request_slot *slot = active_queue_head;\n \tint num_transfers;\n \n-\twhile (active_requests < max_requests && request != NULL) {\n-\t\tif (request->state == WAITING) {\n-\t\t\tif (has_sha1_file(request->sha1))\n-\t\t\t\trelease_request(request);\n+\twhile (active_requests < max_requests && obj_req != NULL) {\n+\t\tif (obj_req->state == WAITING) {\n+\t\t\tif (has_sha1_file(obj_req->sha1))\n+\t\t\t\trelease_object_request(obj_req);\n \t\t\telse\n-\t\t\t\tstart_request(request);\n+\t\t\t\tstart_object_request(obj_req);\n \t\t\tcurl_multi_perform(curlm, &num_transfers);\n \t\t}\n-\t\trequest = request->next;\n+\t\tobj_req = obj_req->next;\n \t}\n \n \twhile (slot != NULL) {\n@@ -329,8 +331,8 @@ void fill_active_slots(void)\n \n void prefetch(unsigned char *sha1)\n {\n-\tstruct transfer_request *newreq;\n-\tstruct transfer_request *tail;\n+\tstruct object_request *newreq;\n+\tstruct object_request *tail;\n \tchar *filename = sha1_file_name(sha1);\n \n \tnewreq = xmalloc(sizeof(*newreq));\n@@ -344,10 +346,10 @@ void prefetch(unsigned char *sha1)\n \t\t \"%s.temp\", filename);\n \tnewreq->next = NULL;\n \n-\tif (request_queue_head == NULL) {\n-\t\trequest_queue_head = newreq;\n+\tif (object_queue_head == NULL) {\n+\t\tobject_queue_head = newreq;\n \t} else {\n-\t\ttail = request_queue_head;\n+\t\ttail = object_queue_head;\n \t\twhile (tail->next != NULL) {\n \t\t\ttail = tail->next;\n \t\t}\n@@ -441,9 +443,10 @@ static int setup_index(struct alt_base *\n \treturn 0;\n }\n \n-static void process_alternates(void *callback_data)\n+static void process_alternates_response(void *callback_data)\n {\n-\tstruct alt_request *alt_req = (struct alt_request *)callback_data;\n+\tstruct alternates_request *alt_req =\n+\t\t(struct alternates_request *)callback_data;\n \tstruct active_request_slot *slot = alt_req->slot;\n \tstruct alt_base *tail = alt;\n \tchar *base = alt_req->base;\n@@ -548,7 +551,7 @@ static void fetch_alternates(char *base)\n \tchar *url;\n \tchar *data;\n \tstruct active_request_slot *slot;\n-\tstatic struct alt_request alt_req;\n+\tstatic struct alternates_request alt_req;\n \n \t/* If another request has already started fetching alternates,\n \t   wait for them to arrive and return to processing this request's\n@@ -580,7 +583,7 @@ static void fetch_alternates(char *base)\n \t/* Use a callback to process the result, since another request\n \t   may fail and need to have alternates loaded before continuing */\n \tslot = get_active_slot();\n-\tslot->callback_func = process_alternates;\n+\tslot->callback_func = process_alternates_response;\n \tslot->callback_data = &alt_req;\n \n \tcurl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);\n@@ -760,54 +763,54 @@ static int fetch_object(struct alt_base \n {\n \tchar *hex = sha1_to_hex(sha1);\n \tint ret = 0;\n-\tstruct transfer_request *request = request_queue_head;\n+\tstruct object_request *obj_req = object_queue_head;\n \n-\twhile (request != NULL && memcmp(request->sha1, sha1, 20))\n-\t\trequest = request->next;\n-\tif (request == NULL)\n+\twhile (obj_req != NULL && memcmp(obj_req->sha1, sha1, 20))\n+\t\tobj_req = obj_req->next;\n+\tif (obj_req == NULL)\n \t\treturn error(\"Couldn't find request for %s in the queue\", hex);\n \n-\tif (has_sha1_file(request->sha1)) {\n-\t\trelease_request(request);\n+\tif (has_sha1_file(obj_req->sha1)) {\n+\t\trelease_object_request(obj_req);\n \t\treturn 0;\n \t}\n \n #ifdef USE_CURL_MULTI\n-\twhile (request->state == WAITING) {\n+\twhile (obj_req->state == WAITING) {\n \t\tstep_active_slots();\n \t}\n #else\n-\tstart_request(request);\n+\tstart_object_request(obj_req);\n #endif\n \n-\twhile (request->state == ACTIVE) {\n-\t\trun_active_slot(request->slot);\n+\twhile (obj_req->state == ACTIVE) {\n+\t\trun_active_slot(obj_req->slot);\n \t}\n-\tif (request->local != -1) {\n-\t\tclose(request->local); request->local = -1;\n+\tif (obj_req->local != -1) {\n+\t\tclose(obj_req->local); obj_req->local = -1;\n \t}\n \n-\tif (request->state == ABORTED) {\n+\tif (obj_req->state == ABORTED) {\n \t\tret = error(\"Request for %s aborted\", hex);\n-\t} else if (request->curl_result != CURLE_OK &&\n-\t\t   request->http_code != 416) {\n-\t\tif (request->http_code == 404)\n+\t} else if (obj_req->curl_result != CURLE_OK &&\n+\t\t   obj_req->http_code != 416) {\n+\t\tif (obj_req->http_code == 404)\n \t\t\tret = -1; /* Be silent, it is probably in a pack. */\n \t\telse\n \t\t\tret = error(\"%s (curl_result = %d, http_code = %ld, sha1 = %s)\",\n-\t\t\t\t    request->errorstr, request->curl_result,\n-\t\t\t\t    request->http_code, hex);\n-\t} else if (request->zret != Z_STREAM_END) {\n-\t\tret = error(\"File %s (%s) corrupt\\n\", hex, request->url);\n-\t} else if (memcmp(request->sha1, request->real_sha1, 20)) {\n+\t\t\t\t    obj_req->errorstr, obj_req->curl_result,\n+\t\t\t\t    obj_req->http_code, hex);\n+\t} else if (obj_req->zret != Z_STREAM_END) {\n+\t\tret = error(\"File %s (%s) corrupt\\n\", hex, obj_req->url);\n+\t} else if (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) {\n \t\tret = error(\"File %s has bad hash\\n\", hex);\n-\t} else if (request->rename < 0) {\n+\t} else if (obj_req->rename < 0) {\n \t\tret = error(\"unable to write sha1 filename %s: %s\",\n-\t\t\t    request->filename,\n-\t\t\t    strerror(request->rename));\n+\t\t\t    obj_req->filename,\n+\t\t\t    strerror(obj_req->rename));\n \t}\n \n-\trelease_request(request);\n+\trelease_object_request(obj_req);\n \treturn ret;\n }\n \n---\n0.99.9.GIT\n"}]}