/** * Abort a fetch. */ static void fetch_curl_abort(void *vf) { struct curl_fetch_info *f = (struct curl_fetch_info *)vf; assert(f); LOG("fetch %p, url '%s'", f, nsurl_access(f->url)); if (f->curl_handle) { f->abort = true; } else { fetch_remove_from_queues(f->fetch_handle); fetch_free(f->fetch_handle); } }
/** * Clean up the provided fetch object and free it. * * Will prod the queue afterwards to allow pending requests to be initiated. */ static void fetch_curl_stop(struct curl_fetch_info *f) { CURLMcode codem; assert(f); LOG("fetch %p, url '%s'", f, nsurl_access(f->url)); if (f->curl_handle) { /* remove from curl multi handle */ codem = curl_multi_remove_handle(fetch_curl_multi, f->curl_handle); assert(codem == CURLM_OK); /* Put this curl handle into the cache if wanted. */ fetch_curl_cache_handle(f->curl_handle, f->host); f->curl_handle = 0; } fetch_remove_from_queues(f->fetch_handle); }
/** callback to poll for additional resource fetch contents */ static void fetch_javascript_poll(lwc_string *scheme) { struct fetch_javascript_context *c, *next; if (ring == NULL) return; /* Iterate over ring, processing each pending fetch */ c = ring; do { /* Ignore fetches that have been flagged as locked. * This allows safe re-entrant calls to this function. * Re-entrancy can occur if, as a result of a callback, * the interested party causes fetch_poll() to be called * again. */ if (c->locked == true) { next = c->r_next; continue; } /* Only process non-aborted fetches */ if (c->aborted == false) { /* resource fetches can be processed in one go */ fetch_javascript_handler(c); } /* Compute next fetch item at the last possible moment * as processing this item may have added to the ring */ next = c->r_next; fetch_remove_from_queues(c->fetchh); fetch_free(c->fetchh); /* Advance to next ring entry, exiting if we've reached * the start of the ring or the ring has become empty */ } while ( (c = next) != ring && ring != NULL); }
static void fetch_rsrc_poll(lwc_string *scheme) { fetch_msg msg; struct fetch_rsrc_context *c, *next; if (ring == NULL) return; /* Iterate over ring, processing each pending fetch */ c = ring; do { /* Take a copy of the next pointer as we may destroy * the ring item we're currently processing */ next = c->r_next; /* Ignore fetches that have been flagged as locked. * This allows safe re-entrant calls to this function. * Re-entrancy can occur if, as a result of a callback, * the interested party causes fetch_poll() to be called * again. */ if (c->locked == true) { continue; } /* Only process non-aborted fetches */ if (!c->aborted && fetch_rsrc_process(c) == true) { char header[64]; fetch_set_http_code(c->parent_fetch, 200); LOG(("setting rsrc: MIME type to %s, length to %zd", c->mimetype, c->datalen)); /* Any callback can result in the fetch being aborted. * Therefore, we _must_ check for this after _every_ * call to fetch_rsrc_send_callback(). */ snprintf(header, sizeof header, "Content-Type: %s", c->mimetype); msg.type = FETCH_HEADER; msg.data.header_or_data.buf = (const uint8_t *) header; msg.data.header_or_data.len = strlen(header); fetch_rsrc_send_callback(&msg, c); snprintf(header, sizeof header, "Content-Length: %zd", c->datalen); msg.type = FETCH_HEADER; msg.data.header_or_data.buf = (const uint8_t *) header; msg.data.header_or_data.len = strlen(header); fetch_rsrc_send_callback(&msg, c); if (!c->aborted) { msg.type = FETCH_DATA; msg.data.header_or_data.buf = (const uint8_t *) c->data; msg.data.header_or_data.len = c->datalen; fetch_rsrc_send_callback(&msg, c); } if (!c->aborted) { msg.type = FETCH_FINISHED; fetch_rsrc_send_callback(&msg, c); } } else { LOG(("Processing of %s failed!", c->url)); /* Ensure that we're unlocked here. If we aren't, * then fetch_rsrc_process() is broken. */ assert(c->locked == false); } fetch_remove_from_queues(c->parent_fetch); fetch_free(c->parent_fetch); /* Advance to next ring entry, exiting if we've reached * the start of the ring or the ring has become empty */ } while ( (c = next) != ring && ring != NULL); }
void ami_fetch_file_poll(const char *scheme_ignored) { struct nsObject *node; struct nsObject *nnode; struct ami_file_fetch_info *fetch; fetch_error_code errorcode; if(IsMinListEmpty(ami_file_fetcher_list)) return; node = (struct nsObject *)GetHead((struct List *)ami_file_fetcher_list); do { errorcode = FETCH_ERROR_NO_ERROR; nnode=(struct nsObject *)GetSucc((struct Node *)node); fetch = (struct ami_file_fetch_info *)node->objstruct; if(fetch->locked) continue; if(!fetch->aborted) { if(fetch->fh) { ULONG len; len = FRead(fetch->fh,ami_file_fetcher_buffer,1,1024); if (len == (ULONG)-1) errorcode = FETCH_ERROR_MISC; else if (len > 0) ami_fetch_file_send_callback( FETCH_DATA, fetch, ami_file_fetcher_buffer, len, errorcode); if((len<1024) && (!fetch->aborted)) { ami_fetch_file_send_callback(FETCH_FINISHED, fetch, NULL, 0, errorcode); fetch->aborted = true; } } else { fetch->fh = FOpen(fetch->path,MODE_OLDFILE,0); if(fetch->fh) { char header[64]; struct ExamineData *fib; if(fib = ExamineObjectTags(EX_FileHandleInput,fetch->fh,TAG_DONE)) { fetch->len = fib->FileSize; FreeDosObject(DOS_EXAMINEDATA,fib); } fetch_set_http_code(fetch->fetch_handle,200); fetch->mimetype = fetch_mimetype(fetch->path); LOG(("mimetype %s len %ld",fetch->mimetype,fetch->len)); snprintf(header, sizeof header, "Content-Type: %s", fetch->mimetype); ami_fetch_file_send_callback(FETCH_HEADER, fetch, header, strlen(header), errorcode); snprintf(header, sizeof header, "Content-Length: %ld", fetch->len); ami_fetch_file_send_callback(FETCH_HEADER, fetch, header, strlen(header), errorcode); } else { STRPTR errorstring; errorstring = ASPrintf("%s %s",messages_get("FileError"),fetch->path); fetch_set_http_code(fetch->fetch_handle,404); errorcode = FETCH_ERROR_HTTP_NOT2; ami_fetch_file_send_callback(FETCH_ERROR, fetch, errorstring, 0, errorcode); fetch->aborted = true; FreeVec(errorstring); } } } if(fetch && fetch->aborted) { fetch_remove_from_queues(fetch->fetch_handle); fetch_free(fetch->fetch_handle); return; } }while(node=nnode); }