#line 21 "viewers.c-nw" #include "config.h" #include #include "w3a.h" #include #include #include "str.h" #include "url.h" #include "w3alib.h" #include "rcfile.e" #include "globals.e" #include "dynload.e" #include "requests.e" #include "input.e" #include "cache.e" /* check_url -- expand a relative URL, FALSE if it fails */ EXPORT Bool check_url(W3ADocumentInfo *doc, URI *uri) { URI base; URL_clean(doc->url); if (! URL_parse(doc->url, uri)) return FALSE; if (uri->tp == URI_Rel) { if (! doc->referer || ! URL_parse(doc->referer, &base)) return FALSE; URL_expand(uri, base); dispose(doc->url); doc->url = uri2str(*uri); } return uri->tp == URI_URL; } EXPORT long W3AopenView(const W3ADocumentInfo doc, W3AWindow area) { ViewerInfo *info; long id; int v; v = find_viewer(doc.mime_type); /* Find and load a viewer */ if (v == -1) {errno = ETYPE; return -1;} /* No appropriate viewer */ info = get_request_rec(); /* Alloc. admin. data */ info->viewer = v; /* Viewer class */ if (! viewer_open(v, doc, area, (long) info)) { free_request_rec(info); return -1; } return (long) info; } EXPORT int W3AwriteView(long id, const char *buf, size_t nbytes) { ViewerInfo *v = (ViewerInfo *) id; return viewer_write(v->viewer, (long) v, buf, nbytes); } EXPORT Bool W3AcloseView(long id) { return free_request_rec((ViewerInfo *) id); } EXPORT long W3Asubprocess(W3ADocumentInfo *doc, int method, const char *data, size_t nbytes, W3AWindow area) { URI uri; int a = -1; Bool use_cache, ok = TRUE; int fd = -1, n; XtInputId input_id; ViewerInfo *info = NULL; long id = 0; const char *where; char *url; size_t howmuch; /* Check and maybe expand URL */ if (! check_url(doc, &uri)) {errno = EURL; return FALSE;} url = newstring(doc->url); if (method != GET_METHOD) { a = find_agent(strip2str(uri.scheme)); if (a == -1) {errno = ETYPE; goto fail;} if (method == DELETE_METHOD) if (agent_delete(a, url)) goto success; else goto fail; if (method == PUT_METHOD || method == POST_METHOD) { /* * For POST, the connection is made immediately, * without waiting for other connections to close. * The request queue in `input.c' will notice * that fd >= 0 and will use the already opened * connection. */ fd = agent_open(a, doc->url, method, O_NONBLOCK, doc->referer); if (fd == -1) goto fail; while (nbytes > 0) { int n; n = agent_write(a, fd, data, nbytes); if (n == -1 && errno != EAGAIN) goto fail; data += n; nbytes -= n; } } } info = get_request_rec(); info->doc = new_doc(); info->method = method; copy_doc(info->doc, *doc); info->agent = a; info->fd = fd; info->viewer = -1; /* No viewer yet */ info->seqnr = seqnr++; /* Unique request ID */ info->total = 0; /* Count of bytes read */ info->high_prio = FALSE; info->w = area; #if 0 if (! use_cache) { #endif /* Start request in the background */ start_request(uri, info, FALSE); #if 0 } else { /* Copy from the cache */ info->viewer = find_viewer(doc->mime_type); if (! viewer_open(info->viewer, *doc, info->w, (long) info)) goto fail; if (viewer_write(info->viewer, (long) info, where, howmuch) != howmuch || viewer_write(info->viewer, (long) info, NULL, 0) != 0) goto fail; } #endif success: dispose(url); return (long) info; fail: if (info) (void) free_request_rec(info); dispose(url); return -1; }