/* ** Proxy and Gateway BEFORE filter ** ------------------------------- ** Checks for registerd proxy servers or gateways and sees whether this ** request should be redirected to a proxy or a gateway. Proxies have ** higher priority than gateways so we look for them first! ** For HTTP/1.0 and HTTP/1.1 we may only send a full URL (including the ** host portion) to proxy servers. Therefore, we tell the Library whether ** to use the full URL or the traditional HTTP one without the host part. */ PUBLIC int HTProxyFilter (HTRequest * request, void * param, int mode) { HTParentAnchor * anchor = HTRequest_anchor(request); char * addr = HTAnchor_physical(anchor); char * physical = NULL; if ((physical = HTProxy_find(addr))) { HTRequest_setFullURI(request, YES); /* For now */ HTRequest_setProxy(request, physical); HT_FREE(physical); #if 0 /* Don't paste the URLs together anymore */ StrAllocCat(physical, addr); HTAnchor_setPhysical(anchor, physical); #endif } else if ((physical = HTGateway_find(addr))) { /* ** A gateway URL is crated by chopping off any leading "/" to make the ** host into part of path */ char * path = HTParse(addr, "", PARSE_HOST + PARSE_PATH + PARSE_PUNCTUATION); char * gatewayed = HTParse((*path=='/') ? path+1 : path, physical, PARSE_ALL); HTAnchor_setPhysical(anchor, gatewayed); HT_FREE(path); HT_FREE(gatewayed); HTRequest_setFullURI(request, NO); HTRequest_deleteProxy(request); } else { HTRequest_setFullURI(request, NO); /* For now */ HTRequest_deleteProxy(request); } return HT_OK; }
/* "Load a document" -- establishes a session ** ------------------------------------------ ** ** On entry, ** addr must point to the fully qualified hypertext reference. ** ** On exit, ** returns <0 Error has occured. ** >=0 Value of file descriptor or socket to be used ** to read data. ** *pFormat Set to the format of the file, if known. ** (See WWW.h) ** */ PRIVATE int HTLoadTelnet ARGS4 ( CONST char *, addr, HTParentAnchor *, anchor GCC_UNUSED, HTFormat, format_out GCC_UNUSED, HTStream *, sink /* Ignored */ ) { char * acc_method; char * host; int status; if (sink) { CTRACE(tfp, "HTTelnet: Can't output a live session -- must be interactive!\n"); return HT_NO_DATA; } acc_method = HTParse(addr, "file:", PARSE_ACCESS); host = HTParse(addr, "", PARSE_HOST); if (!host || *host == '\0') { status = HT_NO_DATA; CTRACE(tfp, "HTTelnet: No host specified!\n"); } else { status = remote_session(acc_method, host); } FREE(host); FREE(acc_method); return status; }
/* "Load a document" -- establishes a session ** ------------------------------------------ ** ** On entry, ** addr must point to the fully qualified hypertext reference. ** ** On exit, ** returns <0 Error has occured. ** >=0 Value of file descriptor or socket to be used ** to read data. ** *pFormat Set to the format of the file, if known. ** (See WWW.h) ** */ PRIVATE int HTLoadTelnet ARGS4 ( WWW_CONST char *, addr, HTParentAnchor *, anchor, HTFormat, format_out, HTStream *, sink /* Ignored */ ) { char * access; char * host; int status; if (sink) { HTAlert("Can't output a live session -- it has to be interactive"); return HT_NO_ACCESS; } access = HTParse(addr, "file:", PARSE_ACCESS); host = HTParse(addr, "", PARSE_HOST); status = remote_session(access, host); free(host); free(access); return status; }
HTAnchor * HTAnchor_findAddress ARGS1 (CONST char *,address) { char *tag = HTParse (address, "", PARSE_ANCHOR); /* Anchor tag specified ? */ /* If the address represents a sub-anchor, we recursively load its parent, then we create a child anchor within that document. */ if (tag && *tag) { char *docAddress = HTParse(address, "", PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION); HTParentAnchor * foundParent = (HTParentAnchor *) HTAnchor_findAddress (docAddress); HTChildAnchor * foundAnchor = HTAnchor_findChild (foundParent, tag); free (docAddress); free (tag); return (HTAnchor *) foundAnchor; } else { /* If the address has no anchor tag, check whether we have this node */ int hash; CONST char *p; HTList * adults; HTList *grownups; HTParentAnchor * foundAnchor; if (tag && *tag) free (tag); /* Select list from hash table */ for(p=address, hash=0; *p; p++) hash = (hash * 3 + *p) % HASH_SIZE; if (!adult_table) adult_table = (HTList**) calloc(HASH_SIZE, sizeof(HTList*)); if (!adult_table[hash]) adult_table[hash] = HTList_new(); adults = adult_table[hash]; /* Search list for anchor */ grownups = adults; while (foundAnchor = HTList_nextObject (grownups)) { if (equivalent(foundAnchor->address, address)) { if (TRACE) fprintf(stderr, "Anchor %p with address `%s' already exists.\n", foundAnchor, address); return (HTAnchor *) foundAnchor; } } /* Node not found : create new anchor */ foundAnchor = HTParentAnchor_new (); if (TRACE) fprintf(stderr, "New anchor %p has hash %d and address `%s'\n", foundAnchor, hash, address); StrAllocCopy(foundAnchor->address, address); HTList_addObject (adults, foundAnchor); return (HTAnchor *) foundAnchor; } }
/* Create new or find old named anchor ** ----------------------------------- ** ** Me one is for a reference which is found in a document, and might ** not be already loaded. ** Note: You are not guaranteed a new anchor -- you might get an old one, ** like with fonts. */ PUBLIC HTAnchor * HTAnchor_findAddress (const char * address) { char *tag = HTParse (address, "", PARSE_VIEW); /* Any tags? */ /* If the address represents a sub-anchor, we recursively load its parent, then we create a child anchor within that document. */ if (*tag) { char *addr = HTParse(address, "", PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION); HTParentAnchor * parent = (HTParentAnchor*) HTAnchor_findAddress(addr); HTChildAnchor * child = HTAnchor_findChild(parent, tag); HT_FREE(addr); HT_FREE(tag); return (HTAnchor *) child; } else { /* Else check whether we have this node */ int hash; const char *p; HTList * adults; HTList *grownups; HTParentAnchor * foundAnchor; char *newaddr = NULL; StrAllocCopy(newaddr, address); /* Get our own copy */ HT_FREE(tag); newaddr = HTSimplify(&newaddr); /* Select list from hash table */ for(p=newaddr, hash=0; *p; p++) hash = (int) ((hash * 3 + (*(unsigned char*)p)) % PARENT_HASH_SIZE); if (!adult_table) { if ((adult_table = (HTList* *) HT_CALLOC(PARENT_HASH_SIZE, sizeof(HTList*))) == NULL) HT_OUTOFMEM("HTAnchor_findAddress"); } if (!adult_table[hash]) adult_table[hash] = HTList_new(); adults = adult_table[hash]; /* Search list for anchor */ grownups = adults; while ((foundAnchor = (HTParentAnchor *) HTList_nextObject(grownups))){ if (!strcmp(foundAnchor->address, newaddr)) { HTTRACE(ANCH_TRACE, "Find Parent. %p with address `%s' already exists.\n" _ (void*) foundAnchor _ newaddr); HT_FREE(newaddr); /* We already have it */ return (HTAnchor *) foundAnchor; } } /* Node not found : create new anchor. */ foundAnchor = HTParentAnchor_new(); foundAnchor->address = newaddr; /* Remember our copy */ HTList_addObject (adults, foundAnchor); HTTRACE(ANCH_TRACE, "Find Parent. %p with hash %d and address `%s' created\n" _ (void*)foundAnchor _ hash _ newaddr); return (HTAnchor *) foundAnchor; } }
/* Add a AA context to the URL tree ** -------------------------------- ** Each node in the AA URL tree is a list of the modules we must call ** for this particular node. */ PUBLIC void * HTAA_updateNode (BOOL proxy_access, char const * scheme, const char * realm, const char * url, void * context) { HTUTree * tree = NULL; HTAAModule * module = NULL; if (!scheme || !url) { HTTRACE(AUTH_TRACE, "Auth Engine. Bad argument\n"); return NULL; } HTTRACE(AUTH_TRACE, "Auth Engine. Adding info for `%s'\n" _ url); /* Find the AA module with this name */ if ((module = HTAA_findModule(scheme)) == NULL) { HTTRACE(AUTH_TRACE, "Auth Engine. Module `%s\' not registered\n" _ scheme ? scheme : "<null>"); return NULL; } /* Find an existing URL Tree or create a new one */ { char * host = HTParse(url, "", PARSE_HOST); char * colon = strchr(host, ':'); int port = DEFAULT_PORT; if (colon ) { *(colon++) = '\0'; /* Chop off port number */ port = atoi(colon); } tree = HTUTree_new(proxy_access ? AA_PROXY_TREE : AA_TREE, host, port, HTAA_deleteElement); HT_FREE(host); if (!tree) { HTTRACE(AUTH_TRACE, "Auth Engine. Can't create tree\n"); return NULL; } } /* Find a matching AA element or create a new one */ { char * path = HTParse(url, "", PARSE_PATH | PARSE_PUNCTUATION); HTAAElement * element = NULL; BOOL status; if ((element = (HTAAElement *) HTUTree_findNode(tree, realm, path)) && element->scheme && !strcasecomp (element->scheme, scheme)) status = HTAA_updateElement(element, scheme, context); else { /* create the new element */ element = HTAA_newElement(scheme, context); status = HTUTree_addNode(tree, realm, path, element); } HT_FREE(path); return status==YES ? element->context : NULL; } }
/**************************************************************************** * name: mo_url_canonicalize_keep_anchor * purpose: Turn a URL into its canonical form, based on the previous * URL in this context (if appropriate). * INTERNAL ANCHORS ARE *NOT* STRIPPED OFF. * inputs: * - char *url: URL to canonicalize. * - char *oldurl: The previous URL in this context. * returns: * The canonical representation of the URL. * remarks: * All we do is call HTParse. ****************************************************************************/ char *mo_url_canonicalize_keep_anchor (char *url, char *oldurl) { char *rv; /* We KEEP anchor information already present in url, but NOT in oldurl. */ oldurl = HTParse (oldurl, "", PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION); rv = HTParse (url, oldurl, PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION | PARSE_ANCHOR); /* We made a new copy of oldurl, so free the new copy. */ free (oldurl); return rv; }
/* ** Look for cached information for this news server ** We store the information in a URL Tree so that we can have multiple ** servers stored simultanously */ PRIVATE HTNewsCache * HTNewsCache_find (HTRequest * request, const char * url) { HTUTree * tree = NULL; if (request && url) { char * newshost = NULL; HTNewsCache * element = NULL; if (!strncasecomp(url, "news:", 5)) { HTUserProfile * up = HTRequest_userProfile(request); StrAllocCopy(newshost, HTUserProfile_news(up)); } else if (!strncasecomp(url, "nntp:", 5)) { newshost = HTParse(url, "", PARSE_HOST); } /* If we have a news server then continue to find a URL tree */ if (newshost) { char * colon = strchr(newshost, ':'); int port = NEWS_PORT; if (colon ) { *(colon++) = '\0'; /* Chop off port number */ port = atoi(colon); } tree = HTUTree_find(NEWS_TREE, newshost, port); HT_FREE(newshost); if (!tree) { HTTRACE(PROT_TRACE, "News Cache.. No information for `%s\'\n" _ url); return NULL; } /* Find a cache element (if any) */ element = (HTNewsCache *) HTUTree_findNode(tree, "", "/"); return element; } } return NULL; }
/* ** This function tries really hard to find a non-existent filename relative ** to the path given. Returns a string that must be freed by the caller or ** NULL on error. */ PRIVATE char * get_filename (char * base, const char * uri, const char * suffix, BOOL use_last_segment) { char * path = NULL; if (use_last_segment) { char * uri_path = NULL; if (uri && (uri_path = HTParse(uri, "", PARSE_PATH|PARSE_PUNCTUATION))) { char * last_segment = strrchr(uri_path, '/'); BOOL slash = (base && *(base+strlen(base)-1)==DIR_SEPARATOR_CHAR); if (last_segment && *(last_segment+1)) { StrAllocMCopy(&path, base ? base : "", slash ? "" : DIR_SEPARATOR_STR, ++last_segment, NULL); } else { StrAllocMCopy(&path, base ? base : "", slash ? "" : DIR_SEPARATOR_STR, DEFAULT_LAST_SEGMENT, suffix ? suffix : "", NULL); } } } else { path = HTGetTmpFileName(base); if (path && suffix) StrAllocCat(path, suffix); } HTTRACE(STREAM_TRACE, "Save file... Temporaray file `%s\'\n" _ path ? path : "<null>"); return path; }
// Operations BOOL CLinks::AddLinkRelationships (HTAnchor * source) { ASSERT(source != NULL); if (!m_hWnd) return FALSE; HTParentAnchor * src = HTAnchor_parent(source); // Update the list control with three columns CListCtrl &ListCtrl = m_pLinkList->GetListCtrl(); int iItem = ListCtrl.GetItemCount(); int cnt; for (cnt=0; cnt<iItem; cnt++) { CString l_type = ListCtrl.GetItemText(cnt, 0); CString l_dir = ListCtrl.GetItemText(cnt, 1); CString l_dest = ListCtrl.GetItemText(cnt, 2); if (!l_type.IsEmpty() && !l_dir.IsEmpty() && !l_dest.IsEmpty()) { char * link_addr = HTParse(l_dest, "", PARSE_ALL); HTParentAnchor * dest = HTAnchor_parent(HTAnchor_findAddress(link_addr)); /* Now add the new relation */ if (l_dir == "forward") { HTLink_add((HTAnchor *) src, (HTAnchor *) dest, (HTLinkType) HTAtom_caseFor(l_type), METHOD_INVALID); } else if (l_dir == "reverse") { HTLink_add((HTAnchor *) dest, (HTAnchor *) src, (HTLinkType) HTAtom_caseFor(l_type), METHOD_INVALID); } else ASSERT(1); } } return TRUE; }
int HTParse_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { if (argc > 2 && argc < 5) { char *aName = argv[1]; char *relatedName = argv[2]; if (aName && relatedName) { char *result; int bitflag = -1; /* Don't know how to check otherwise, so dummy statement at end */ if ((argc == 4) && (Tcl_GetInt(interp, argv[3], &bitflag) == TCL_OK)) { } result = HTParse(aName, relatedName, bitflag); Tcl_AppendResult(interp, result, NULL); return TCL_OK; } Tcl_AppendResult(interp, bad_vars, NULL); return TCL_ERROR; } else { Tcl_AppendResult(interp, err_string, argv[0], " a_address absolute_address bit-flags", NULL); return TCL_ERROR; } }
/* Create new or find old parent anchor ** ------------------------------------ ** ** Me one is for a reference which is found in a document, and might ** not be already loaded. ** Note: You are not guaranteed a new anchor -- you might get an old one, ** like with fonts. */ PUBLIC HTParentAnchor * HTAnchor_findAddress ARGS1( CONST DocAddress *, newdoc) { /* Anchor tag specified ? */ CONST char *tag = HTParseAnchor(newdoc->address); CTRACE((tfp,"Entered HTAnchor_findAddress\n")); /* ** If the address represents a sub-anchor, we load its parent, ** then we create a named child anchor within that parent. */ if (*tag) { DocAddress parsed_doc; HTParentAnchor0 * foundParent; HTChildAnchor * foundAnchor; parsed_doc.address = HTParse(newdoc->address, "", PARSE_ALL_WITHOUT_ANCHOR); parsed_doc.post_data = newdoc->post_data; parsed_doc.post_content_type = newdoc->post_content_type; parsed_doc.bookmark = newdoc->bookmark; parsed_doc.isHEAD = newdoc->isHEAD; parsed_doc.safe = newdoc->safe; foundParent = HTAnchor_findAddress_in_adult_table(&parsed_doc); foundAnchor = HTAnchor_findNamedChild (foundParent, tag); FREE(parsed_doc.address); return HTAnchor_parent((HTAnchor *)foundParent); } return HTAnchor_parent((HTAnchor *)HTAnchor_findAddress_in_adult_table(newdoc)); }
PUBLIC BOOL HTBind_getResponseBindings (HTResponse * response, const char * url) { BOOL status = NO; double quality = 1.0; if (response) { char * path = HTParse(url, "", PARSE_PATH + PARSE_PUNCTUATION); char * file; char * end; if ((end = strchr(path, ';')) || (end = strchr(path, '?')) || (end = strchr(path, '#'))) *end = '\0'; if ((file = strrchr(path, '/'))) { HTFormat format = NULL; HTEncoding encoding = NULL; HTEncoding transfer = NULL; HTLanguage language = NULL; HTTRACE(BIND_TRACE, "Response.... Get Bindings for `%s\'\n" _ path); status = HTBind_getFormat(file, &format, &encoding, &transfer, &language, &quality); if (status) { HTResponse_setFormat(response, format); HTResponse_setContentTransferEncoding(response, transfer); HTResponse_addEncoding(response, encoding); #if 0 HTResponse_addLanguage(response, language); #endif } } HT_FREE(path); } return status; }
/**************************************************************************** * name: mo_url_canonicalize * purpose: Turn a URL into its canonical form, based on the previous * URL in this context (if appropriate). * INTERNAL ANCHORS ARE STRIPPED OFF. * inputs: * - char *url: URL to canonicalize. * - char *oldurl: The previous URL in this context. * returns: * The canonical representation of the URL. * remarks: * All we do is call HTParse. ****************************************************************************/ char *mo_url_canonicalize (char *url, char *oldurl) { /* We LOSE anchor information. */ return HTParse (url, oldurl, PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION); }
int main (int argc, char ** argv) { char * uri = NULL; /* Create a new premptive client */ HTProfile_newHTMLNoCacheClient ("ShowLinks", "1.0"); /* Need our own trace and print functions */ HTPrint_setCallback(printer); HTTrace_setCallback(tracer); /* Set trace messages and alert messages */ #if 0 HTSetTraceMessageMask("sop"); #endif /* Add our own termination filter */ HTNet_addAfter(terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); /* ** Register our HTML link handler. We don't actually create a HText ** object as this is not needed. We only register the specific link ** callback. */ HText_registerLinkCallback(foundLink); /* Setup a timeout on the request for 15 secs */ HTHost_setEventTimeout(15000); /* Handle command line args */ if (argc >= 2) uri = HTParse(argv[1], NULL, PARSE_ALL); if (uri) { HTRequest * request = NULL; HTAnchor * anchor = NULL; BOOL status = NO; /* Create a request */ request = HTRequest_new(); /* Get an anchor object for the URI */ anchor = HTAnchor_findAddress(uri); /* Issue the GET and store the result in a chunk */ status = HTLoadAnchor(anchor, request); /* Go into the event loop... */ if (status == YES) HTEventList_loop(request); } else { HTPrint("Type the URI to print out a list of embedded links\n"); HTPrint("\t%s <uri>\n", argv[0]); HTPrint("For example:\n"); HTPrint("\t%s http://www.w3.org\n", argv[0]); } return 0; }
/* Make the cache file name for a W3 document ** ------------------------------------------ ** Make up a suitable name for saving the node in ** ** E.g. /tmp/WWW_Cache_news/[email protected] ** /tmp/WWW_Cache_http/crnvmc/FIND/xx.xxx.xx ** ** On exit, ** returns a malloc'ed string which must be freed by the caller. */ PUBLIC char * HTCacheFileName ARGS1(WWW_CONST char *,name) { char * access = HTParse(name, "", PARSE_ACCESS); char * host = HTParse(name, "", PARSE_HOST); char * path = HTParse(name, "", PARSE_PATH+PARSE_PUNCTUATION); char * result; result = (char *)malloc( strlen(HTCacheRoot)+strlen(access) +strlen(host)+strlen(path)+6+1); if (result == NULL) outofmem(__FILE__, "HTCacheFileName"); sprintf(result, "%s/WWW/%s/%s%s", HTCacheRoot, access, host, path); free(path); free(access); free(host); return result; }
void CLinks::OnLinkAdd() { UpdateData(); // Get the edit text if (!m_linkType.IsEmpty() && m_linkDestination.GetWindowTextLength()) { CString LinkCaption; m_linkDestination.GetWindowText(LinkCaption); // Get the base address (if any) CString base; m_linkDestination.GetLBText(0, base); char * link = HTParse(LinkCaption, base.IsEmpty() ? "" : base, PARSE_ALL); link = HTSimplify(&link); LinkCaption = link; m_linkDestination.SetWindowText(LinkCaption); HT_FREE(link); // Update the combo box if (m_linkDestination.FindStringExact(-1, LinkCaption) == CB_ERR) { m_linkDestination.InsertString(0, LinkCaption); int length = m_linkDestination.GetCount(); if (length >= MAX_LIST_LENGTH) { int cnt; for (cnt=MAX_LIST_LENGTH; cnt < length; cnt++) m_linkDestination.DeleteString(cnt); } } // Write into INI file CWinComApp * pApp = (CWinComApp *) AfxGetApp(); ASSERT(pApp != NULL); pApp->AddLinkToIniFile(LinkCaption); // Update the list control with three columns CListCtrl &ListCtrl = m_pLinkList->GetListCtrl(); // Insert item LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvi.iItem = 0; lvi.iSubItem = 0; lvi.pszText = (char *) LPCTSTR(m_linkType); lvi.iImage = 0; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = INDEXTOSTATEIMAGEMASK(1); int iItem = ListCtrl.InsertItem(&lvi); ASSERT(iItem != -1); // Set item text for additional columns ListCtrl.SetItemText(iItem,1, m_direction==0 ? _T("forward") : _T("reverse")); ListCtrl.SetItemText(iItem,2, (char *) LPCTSTR(LinkCaption)); // Update changes m_pLinkList->UpdateWindow(); } }
/* Output parent directory entry ** ** This gives the TITLE and H1 header, and also a link ** to the parent directory if appropriate. */ PUBLIC void HTDirTitles ARGS2(HTStructured *, target, HTAnchor * , anchor) { char * logical = HTAnchor_address(anchor); char * path = HTParse(logical, "", PARSE_PATH + PARSE_PUNCTUATION); char * current; current = strrchr(path, '/'); /* last part or "" */ free(logical); { char * printable = NULL; StrAllocCopy(printable, (current + 1)); HTUnEscape(printable); START(HTML_TITLE); PUTS(*printable ? printable : "Welcome "); PUTS(" directory"); END(HTML_TITLE); START(HTML_H1); PUTS(*printable ? printable : "Welcome"); END(HTML_H1); free(printable); } /* Make link back to parent directory */ if (current && current[1]) { /* was a slash AND something else too */ char * parent; char * relative; *current++ = 0; parent = strrchr(path, '/'); /* penultimate slash */ relative = (char*) malloc(strlen(current) + 4); if (relative == NULL) outofmem(__FILE__, "DirRead"); sprintf(relative, "%s/..", current); PUTS ("<A HREF=\""); PUTS (relative); PUTS ("\">"); free(relative); PUTS("Up to "); if (parent) { char * printable = NULL; StrAllocCopy(printable, parent + 1); HTUnEscape(printable); PUTS(printable); free(printable); } else { PUTS("/"); } PUTS("</A>"); } free(path); }
/* ** Existing entries are replaced with new ones */ PRIVATE BOOL add_object (HTList * list, const char * access, const char * url, BOOL regex, int regex_flags) { HTProxy *me; if (!list || !access || !url || !*url) return NO; if ((me = (HTProxy *) HT_CALLOC(1, sizeof(HTProxy))) == NULL) HT_OUTOFMEM("add_object"); StrAllocCopy(me->access, access); /* Access method */ #ifdef HT_POSIX_REGEX /* ** If we support regular expressions then compile one up for ** this regular expression. Otherwise use is as a normal ** access scheme. */ if (regex) { me->regex = get_regex_t(access, regex_flags < 0 ? W3C_DEFAULT_REGEX_FLAGS : regex_flags); } else #endif { char *ptr = me->access; while ((*ptr = TOLOWER(*ptr))) ptr++; } me->url = HTParse(url, "", PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION); if (*(me->url+strlen(me->url)-1) != '/') StrAllocCat(me->url, "/"); me->url = HTSimplify(&me->url); /* See if we already have this one */ { HTList *cur = list; HTProxy *pres; while ((pres = (HTProxy *) HTList_nextObject(cur)) != NULL) { if (!strcmp(pres->access, me->access)) break; /* We already have it */ } if (pres) { HTTRACE(PROT_TRACE, "HTProxy..... replacing for `%s\' access %s\n" _ me->url _ me->access); HT_FREE(pres->access); HT_FREE(pres->url); #ifdef HT_POSIX_REGEX if (pres->regex) regfree(pres->regex); #endif HTList_removeObject(list, (void *) pres); HT_FREE(pres); } HTTRACE(PROT_TRACE, "HTProxy..... adding for `%s\' access %s\n" _ me->url _ me->access); HTList_addObject(list, (void *) me); } return YES; }
/* Delete a AA context from the URL tree ** ------------------------------------- ** Each node in the AA URL tree is a list of the modules we must call ** for this particular node. */ PUBLIC BOOL HTAA_deleteNode (BOOL proxy_access, char const * scheme, const char * realm, const char * url) { HTUTree * tree = NULL; HTAAModule * module = NULL; if (!scheme || !url) { HTTRACE(AUTH_TRACE, "Auth Engine. Bad argument\n"); return NO; } HTTRACE(AUTH_TRACE, "Auth Engine. Deleting info for `%s'\n" _ url); /* Find the AA module with this name */ if ((module = HTAA_findModule(scheme)) == NULL) { HTTRACE(AUTH_TRACE, "Auth Engine. Module `%s\' not registered\n" _ scheme ? scheme : "<null>"); return NO; } /* Find an existing URL Tree or create a new one */ { char * host = HTParse(url, "", PARSE_HOST); char * colon = strchr(host, ':'); int port = DEFAULT_PORT; if (colon ) { *(colon++) = '\0'; /* Chop off port number */ port = atoi(colon); } tree = HTUTree_new(proxy_access ? AA_PROXY_TREE : AA_TREE, host, port, HTAA_deleteElement); HT_FREE(host); if (!tree) { HTTRACE(AUTH_TRACE, "Auth Engine. Can't create tree\n"); return NO; } } /* Delete any existing node */ { char * path = HTParse(url, "", PARSE_PATH | PARSE_PUNCTUATION); BOOL status = HTUTree_deleteNode(tree, realm, path); HT_FREE(path); return status; } }
/* NewsPost_start ** -------------- ** NNTP needs two extra headers: "From" and "Newsgroups". ** Take the newsgroups from the Postweb model as destinations for this ** anchor. ** Return YES if OK else NO */ PRIVATE BOOL NewsPost_start (HTStream * me, HTRequest * request) { char linebuf[128]; /* @@@ */ HTChunk *header = me->buffer; HTUserProfile * up = HTRequest_userProfile(request); const char * mailaddress = HTUserProfile_email(up); if (mailaddress) { sprintf(linebuf, "From: %s%c%c", mailaddress, CR, LF); HTChunk_puts(header, linebuf); } /* ** Find all the newsgroups we are posting to by looking at all the ** destinations from the source of this request. ** First the main link and then the sub links */ HTChunk_puts(header, "Newsgroups :"); if (HTRequest_isDestination(request)) { HTRequest *src_req = HTRequest_source(request); HTParentAnchor *src_anchor = HTRequest_anchor(src_req); HTLink *link = HTAnchor_mainLink((HTAnchor *) src_anchor); HTAnchor *dest = HTLink_destination(link); HTMethod method = HTLink_method(link); if (link && method == METHOD_POST && HTLink_result(link) == HT_LINK_NONE) { char *desturl = HTAnchor_physical((HTParentAnchor *) dest); char *access = HTParse(desturl, "", PARSE_ACCESS); if (!strcasecomp(access, "news") || !strcasecomp(access, "nntp")) { char *newsgroup = HTParse(desturl, "", PARSE_PATH); HTUnEscape(newsgroup); HTCleanTelnetString(newsgroup); HTChunk_puts(header, newsgroup); HT_FREE(newsgroup); } HT_FREE(access); } /* DO FOR ALL SUB ANCHOR DESTINATION S AS WELL */ } HTTRACE(PROT_TRACE, "News Tx..... %s" _ HTChunk_data(header)); return YES; }
/* ** Expand the location relative to the base URL if any, otherwise the ** anchor address it self */ PUBLIC BOOL HTAnchor_setLocation (HTParentAnchor * me, char * location) { if (me && location) { char * base = HTAnchor_base(me); if (!base) base = me->address; me->content_location = HTParse(location, base, PARSE_ALL); return YES; } return NO; }
int main (int argc, char ** argv) { char * uri = NULL; /* Create a new premptive client */ HTProfile_newHTMLNoCacheClient ("ShowXML", "1.0"); /* Need our own trace and print functions */ HTPrint_setCallback(printer); HTTrace_setCallback(tracer); /* Set trace messages */ #if 0 HTSetTraceMessageMask("sop"); #endif /* Add our own termination filter */ HTNet_addAfter(terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); /* Register our new XML Instance handler */ HTXMLCallback_registerNew (HTXML_newInstance, NULL); /* Setup a timeout on the request for 15 secs */ HTHost_setEventTimeout(15000); /* Handle command line args */ if (argc >= 2) uri = HTParse(argv[1], NULL, PARSE_ALL); if (uri) { HTRequest * request = NULL; HTAnchor * anchor = NULL; BOOL status = NO; /* Create a request */ request = HTRequest_new(); /* Get an anchor object for the URI */ anchor = HTAnchor_findAddress(uri); /* Issue the GET and store the result in a chunk */ status = HTLoadAnchor(anchor, request); /* Go into the event loop... */ if (status == YES) HTEventList_loop(request); } else { HTPrint("Type the URI to parse\n"); HTPrint("\t%s <uri>\n", argv[0]); HTPrint("For example:\n"); HTPrint("\t%s http://www.yoursite.com/your.xml\n", argv[0]); } return 0; }
int HTLoadTelnet( char *addr, HTParentAnchor *anchor, HTFormat format_out, HTStream *sink ) { char *acc_method; char *host; int status; if ( sink ) { if ( WWW_TraceFlag ) { fprintf( TraceFP( ), "HTTelnet: Can't output a live session -- must be interactive!\n" ); } return -204; } else { acc_method = HTParse( addr, "file:", 16 ); host = HTParse( addr, "", 8 ); if ( host == 0 || host[0] == 0 ) { status = -204; if ( WWW_TraceFlag ) { fprintf( TraceFP( ), "HTTelnet: No host specified!\n" ); } } else { status = remote_session( acc_method, host ); } if ( host ) { free( host ); host = 0; } if ( acc_method ) { free( acc_method ); acc_method = 0; } return status; } }
void CLocation::OnBrowse() { CWinComApp * pApp = (CWinComApp *) AfxGetApp(); ASSERT(pApp != NULL); CFileDialog fd(TRUE); fd.m_ofn.lpstrInitialDir = pApp->GetIniCWD(); UpdateData(); if (fd.DoModal() == IDOK) { // Make the source an absolute URI CString path = fd.GetPathName(); char * fileaddr = HTLocalToWWW(path, NULL); if (fileaddr) { m_source = fileaddr; m_sourceList.SetWindowText(fileaddr); // Set the initial dir for next time int idx = path.ReverseFind('\\'); if (idx != -1) path.GetBufferSetLength(idx+1); pApp->SetIniCWD(path); HT_FREE(fileaddr); } /* Update the destination */ CString file = fd.GetFileName(); if (!file.IsEmpty()) { CString base = ""; char * escaped = HTEscape(file, URL_XALPHAS); char * destination = escaped; int length = m_destinationList.GetCount(); if (length > 0) { m_destinationList.GetLBText(0, base); if (!base.IsEmpty()) { destination = HTParse(escaped, base, PARSE_ALL); HT_FREE(escaped); } } destination = HTSimplify(&destination); m_destination = destination; m_destinationList.SetWindowText(m_destination); HT_FREE(destination); } // If change in source then update the entity and link info ASSERT(GetParentFrame()->GetActiveView()->IsKindOf(RUNTIME_CLASS(CTabsView))); CTabsView * view = (CTabsView *) GetParentFrame()->GetActiveView(); view->GetDocument()->m_EntityInfo.Clear(); view->GetDocument()->m_Links.Clear(); UpdateData(); } }
/* ** Check the response to see if we got a cookie or more. ** If so then figure out what to do with it (prompt user, store, etc.) */ PRIVATE int HTCookie_afterFilter (HTRequest * request, HTResponse * response, void * param, int status) { if ((CookieMode & HT_COOKIE_ACCEPT) && SetCookie) { HTCookieHolder * holder = HTCookieHolder_find(request); if (holder) { HTList * cookies = holder->cookies; HTCookie * pres; while ((pres = (HTCookie *) HTAssocList_nextObject(cookies))) { /* Should we check to see if hosts match? */ if (CookieMode & (HT_COOKIE_SAME_HOST|HT_COOKIE_SAME_DOMAIN)) { char * cookie_host = HTCookie_domain(pres); if (cookie_host) { int res; char * addr = HTAnchor_address((HTAnchor *) HTRequest_anchor(request)); char * host = HTParse(addr, "", PARSE_HOST); if (CookieMode & HT_COOKIE_SAME_DOMAIN) res = tailcasecomp(cookie_host, host); else res = strcasecomp(cookie_host, host); if (res != 0) { HTTRACE(APP_TRACE, "Cookie...... Host `%s\' doesn't match what is sent in cookie `%s\'\n" _ host _ cookie_host); HT_FREE(addr); continue; } HT_FREE(addr); } } /* Should we prompt the user? */ if (CookieMode & HT_COOKIE_PROMPT) { HTAlertCallback * prompt = HTAlert_find(HT_A_CONFIRM); if (prompt) { if ((*prompt)(request, HT_A_CONFIRM, HT_MSG_ACCEPT_COOKIE, NULL, NULL, NULL) != YES) continue; } else continue; } /* Call the application with our new cookie */ (*SetCookie)(request, pres, SetCookieContext); } /* Delete cookie holder */ HTCookieHolder_delete(holder); } } return HT_OK; }
int main (int argc, char ** argv) { char * uri = NULL; char * cwd = HTGetCurrentDirectoryURL(); /* Create a new premptive client */ HTProfile_newHTMLNoCacheClient ("ParseRDF", "1.0"); /* Need our own trace and print functions */ HTPrint_setCallback(printer); HTTrace_setCallback(tracer); /* Set trace messages */ #if 0 HTSetTraceMessageMask("sopx"); #endif /* Add our own termination filter */ HTNet_addAfter(terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); /* Setup a timeout on the request for 15 secs */ HTHost_setEventTimeout(15000); /* Handle command line args */ if (argc >= 2) uri = HTParse(argv[1], cwd, PARSE_ALL); HT_FREE(cwd); /* Set up our RDF To Triple conveter stream */ HTFormat_addConversion("text/rdf", "*/*", HTRDFParser_new, 1.0, 0.0, 0.0); /* Set our new RDF parser instance callback */ HTRDF_registerNewParserCallback (new_parser_handler, NULL); if (uri) { HTRequest * request = HTRequest_new(); HTAnchor * anchor = HTAnchor_findAddress(uri); BOOL status = NO; /* Start the GET request */ status = HTLoadAnchor(anchor, request); /* Go into the event loop... */ if (status == YES) HTEventList_loop(request); } else { HTPrint("Type the URI to parse\n"); HTPrint("\t%s <uri>\n", argv[0]); HTPrint("For example:\n"); HTPrint("\t%s http://www.yoursite.com/your.rdf\n", argv[0]); } return 0; }
/* Convert filenames between local and WWW formats ** ----------------------------------------------- ** On exit, ** returns a malloc'ed string which must be freed by the caller. */ PUBLIC char * HTLocalName ARGS1(WWW_CONST char *,name) { char * access = HTParse(name, "", PARSE_ACCESS); char * host = HTParse(name, "", PARSE_HOST); char * path = HTParse(name, "", PARSE_PATH+PARSE_PUNCTUATION); HTUnEscape(path); /* Interpret % signs */ if (0==strcmp(access, "file")) { free(access); if (!host || !*host || (0==my_strcasecmp(host, HTHostName())) || (0==my_strcasecmp(host, "localhost"))) { if (host) free(host); #ifndef DISABLE_TRACE if (www2Trace) fprintf(stderr, "Node `%s' means path `%s'\n", name, path); #endif return(path); } else { free (host); if (path) free (path); return NULL; } } /* not file */ if (host) free (host); free (access); if (path) free (path); return NULL; }
/* Make Relative Name ** ------------------ ** ** This function creates and returns a string which gives an expression of ** one address as related to another. Where there is no relation, an absolute ** address is retured. ** ** On entry, ** Both names must be absolute, fully qualified names of nodes ** (no fragment bits) ** ** On exit, ** The return result points to a newly allocated name which, if ** parsed by HTParse relative to relatedName, will yield aName. ** The caller is responsible for freeing the resulting name later. ** */ PUBLIC char * HTRelative (const char * aName, const char * relatedName) { char * result = 0; const char *p = aName; const char *q = relatedName; const char * after_access = NULL; const char * path = 0; const char * last_slash = 0; int slashes = 0; for(;*p; p++, q++) { /* Find extent of match */ if (*p!=*q) break; if (*p==':') if (!after_access) after_access = p+1; if (*p=='/') { last_slash = p; slashes++; if (slashes==3) path=p; } } /* q, p point to the first non-matching character or zero */ if (!after_access) { /* Different access */ StrAllocCopy(result, aName); } else if (slashes<3){ /* Different nodes */ StrAllocCopy(result, after_access); } else { /* Some path in common */ int levels= 0; for(; *q && *q!='#' && *q!=';' && *q!='?'; q++) if (*q=='/') levels++; if ((result = (char *) HT_MALLOC(3*levels + strlen(last_slash) + 4)) == NULL) HT_OUTOFMEM("HTRelative"); *result = '\0'; if (!levels) strcat(result, "./"); for(;levels; levels--)strcat(result, "../"); strcat(result, last_slash+1); if (!*result) strcat(result, "./"); } HTTRACE(URI_TRACE, "HTRelative.. `%s' expressed relative to `%s' is `%s'\n" _ aName _ relatedName _ result); #if 0 { char * absstr = HTParse(result, relatedName, PARSE_ALL); HTSimplify(&absstr); HTTRACE(URI_TRACE, "HTRelative.. `%s' made absolute based on `%s' is `%s'\n" _ result _ relatedName _ absstr); if (strcmp(absstr, aName) != 0) HTTRACE(URI_TRACE, "THEY DIFFER!!!\n"); HT_FREE(absstr); } #endif return result; }
/* Helper function added by MP. */ PRIVATE char* GetNewsGroupTitle (HTRequest* request) { char * url = HTAnchor_physical(HTRequest_anchor(request)); char * title = NULL; if (strrchr(url, '*')) StrAllocCopy(title, "Newsgroups: "); else StrAllocCopy(title, "Newsgroup: "); if (!strncasecomp(url, "news:", 5)) StrAllocCat(title, url+5); else StrAllocCat(title, HTParse(url, "", PARSE_PATH)); return title; }