static STCB urnHandleReply;
static wordlist *urn_parsebuffer(const char *inbuf);
static const char *const crlf = "\r\n";
-static char *urnConstructMenu(clientHttpRequest * http);
+
+typedef struct {
+ StoreEntry *entry;
+ StoreEntry *urlres_e;
+ request_t *request;
+} UrnState;
wordlist *
urnFindMinRtt(wordlist * urls, method_t m, int *rtt_ret)
}
void
-urnStart(clientHttpRequest * http)
+urnStart(request_t *r, StoreEntry *e)
{
LOCAL_ARRAY(char, urlres, 4096);
- StoreEntry *e;
- request_t *r = http->request;
request_t *urlres_r = NULL;
const cache_key *k;
char *t;
+ UrnState *urnState;
+ StoreEntry *urlres_e;
debug(50, 1) ("urnStart\n");
- assert(http != NULL);
- debug(50, 1) ("urnStart: '%s'\n", http->uri);
+ debug(50, 1) ("urnStart: '%s'\n", storeUrl(e));
t = strchr(r->urlpath, ':');
if (t == NULL) {
ErrorState *err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND);
- err->request = requestLink(http->request);
- err->url = http->uri;
- err->src_addr = http->conn->peer.sin_addr;
- errorAppendEntry(http->entry, err);
+ err->request = requestLink(r);
+ err->url = xstrdup(storeUrl(e));
+ errorAppendEntry(e, err);
return;
}
*t = '\0';
+ urnState = xcalloc(1, sizeof(UrnState));
+ urnState->entry = e;
+ urnState->request = requestLink(r);
+ cbdataAdd(urnState);
snprintf(urlres, 4096, "http://%s/uri-res/N2L?%s", r->urlpath, t+1);
k = storeKeyPublic(urlres, METHOD_GET);
urlres_r = urlParse(METHOD_GET, urlres);
urlres_r->headers = xstrdup("Accept: */*\r\n\r\n");
urlres_r->headers_sz = strlen(urlres_r->headers);
- if ((e = storeGet(k)) == NULL) {
- e = storeCreateEntry(urlres, urlres, 0, METHOD_GET);
- storeClientListAdd(e, http);
- protoDispatch(0, e, urlres_r);
+ if ((urlres_e = storeGet(k)) == NULL) {
+ urlres_e = storeCreateEntry(urlres, urlres, 0, METHOD_GET);
+ storeClientListAdd(urlres_e, urnState);
+ protoDispatch(0, urlres_e, urlres_r);
+ } else {
+ storeClientListAdd(urlres_e, urnState);
}
- http->entry = e;
- storeClientCopy(e, 0, 0, 4096, get_free_4k_page(), urnHandleReply, http);
+ urnState->urlres_e = urlres_e;
+ storeLockObject(urlres_e);
+ storeClientCopy(urlres_e,
+ 0,
+ 0,
+ 4096,
+ get_free_4k_page(),
+ urnHandleReply,
+ urnState);
}
static void
urnHandleReply(void *data, char *buf, ssize_t size)
{
- clientHttpRequest *http = data;
- StoreEntry *entry = http->entry;
+ LOCAL_ARRAY(char, line, 4096);
+ UrnState *urnState = data;
+ StoreEntry *e = urnState->entry;
+ StoreEntry *urlres_e = urnState->urlres_e;
char *s = NULL;
- wordlist *urls = NULL;
+ char *hdr;
+ wordlist *w;
+ wordlist *urls;
+ wordlist *min_w;
+ int l;
+ String *S;
+ ErrorState *err;
+
debug(50, 1) ("urnHandleReply: Called with size=%d.\n", size);
- if (entry->store_status == STORE_ABORTED) {
+ if (urlres_e->store_status == STORE_ABORTED) {
put_free_4k_page(buf);
return;
}
put_free_4k_page(buf);
return;
}
- if (entry->store_status == STORE_PENDING) {
- storeClientCopy(entry,
- entry->mem_obj->inmem_hi,
+ if (urlres_e->store_status == STORE_PENDING) {
+ storeClientCopy(urlres_e,
+ size,
0,
SM_PAGE_SIZE,
buf,
urnHandleReply,
- http);
+ urnState);
return;
}
/* we know its STORE_OK */
s = mime_headers_end(buf);
if (s == NULL) {
debug(0, 0) ("urnHandleReply: didn't find end-of-headers for %s\n",
- storeUrl(entry));
+ storeUrl(e));
return;
}
- assert(http->entry->mem_obj);
- assert(http->entry->mem_obj->reply);
- httpParseReplyHeaders(buf, http->entry->mem_obj->reply);
+ assert(urlres_e->mem_obj->reply);
+ httpParseReplyHeaders(buf, urlres_e->mem_obj->reply);
debug(50, 1) ("mem->reply exists, code=%d.\n",
- http->entry->mem_obj->reply->code);
- if (http->entry->mem_obj->reply->code != 200) {
+ urlres_e->mem_obj->reply->code);
+ if (urlres_e->mem_obj->reply->code != 200) {
debug(50, 1) ("urnHandleReply: failed.\n");
- /* XX - return error message */
- urnTranslateDone(http, NULL);
+ err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND);
+ err->request = requestLink(urnState->request);
+ err->url = xstrdup(storeUrl(e));
+ errorAppendEntry(e, err);
return;
}
while (isspace(*s))
s++;
urls = urn_parsebuffer(s);
- urnTranslateDone(http, urls);
+ if (urls == NULL) { /* unkown URN error */
+ debug(50, 1) ("urnTranslateDone: unknown URN (%s).\n", storeUrl(e));
+ err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND);
+ err->request = requestLink(urnState->request);
+ err->url = xstrdup(storeUrl(e));
+ errorAppendEntry(e, err);
+ return;
+ }
+ min_w = urnFindMinRtt(urls, urnState->request->method, NULL);
+ storeBuffer(e);
+ S = stringCreate(1024);
+ l = snprintf(line, 4096,
+ "<TITLE>Select URL for %s</TITLE>\n"
+ "<H2>Select URL for %s</H2>\n"
+ "<UL>\n", storeUrl(e), storeUrl(e));
+ stringAppend(S, line, l);
+ for (w = urls; w; w = w->next) {
+ l = snprintf(line, 4096, "<LI><A HREF=\"%s\">%s</A>\n", w->key, w->key);
+ stringAppend(S, line, l);
+ }
+ l = snprintf(line, 4096,
+ "</UL>"
+ "<HR>\n"
+ "<ADDRESS>\n"
+ "Generated by %s/%s@%s\n"
+ "</ADDRESS>\n",
+ appname, version_string, getMyHostname());
+ stringAppend(S, line, l);
+ hdr = httpReplyHeader(1.0,
+ HTTP_MOVED_TEMPORARILY,
+ "text/html",
+ stringLength(S),
+ 0,
+ squid_curtime);
+ storeAppend(e, hdr, strlen(hdr));
+ if (min_w) {
+ l = snprintf(line, 4096, "Location: %s\r\n", min_w->key);
+ storeAppend(e, line, l);
+ }
+ storeAppend(e, "\r\n", 2);
+ storeAppend(e, S->buf, stringLength(S));
+ storeComplete(e);
put_free_4k_page(buf);
+ stringFree(S);
+ storeUnlockObject(urlres_e);
}
-
static wordlist *
urn_parsebuffer(const char *inbuf)
{
}
return head;
}
-
-void
-urnTranslateDone(void *data, wordlist * urls)
-{
- clientHttpRequest *http = data;
- request_t *new_request = NULL;
- request_t *old_request = http->request;
- ErrorState *err = NULL;
- wordlist *min_w;
- char *buf;
- debug(50, 1) ("urnTranslateDone\n");
- if ((http->urls = urls) == NULL) { /* unkown URN error */
- debug(50, 1) ("urnTranslateDone: unknown URN (%s).\n", http->uri);
- http->entry = clientCreateStoreEntry(http, old_request->method, 0);
- err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND);
- err->request = requestLink(http->request);
- err->url = http->uri;
- err->src_addr = http->conn->peer.sin_addr;
- errorAppendEntry(http->entry, err);
- return;
- }
- min_w = urnFindMinRtt(http->urls, http->request->method, NULL);
- if (min_w != NULL) {
- safe_free(http->uri);
- http->uri = xstrdup(min_w->key);
- new_request = urlParse(old_request->method, http->uri);
- new_request->http_ver = old_request->http_ver;
- new_request->headers = old_request->headers;
- new_request->headers_sz = old_request->headers_sz;
- requestUnlink(http->request);
- http->request = requestLink(new_request);
- clientAccessCheck(http);
- } else {
- buf = urnConstructMenu(http);
- storeAppend(http->entry, buf, strlen(buf));
- storeComplete(http->entry);
- }
-}
-
-static char *
-urnConstructMenu(clientHttpRequest * http)
-{
- LOCAL_ARRAY(char, buf, 8192);
- LOCAL_ARRAY(char, line, 256);
- LOCAL_ARRAY(char, content, 4096);
- char *hdr;
- wordlist *w;
- debug(50, 1) ("urnConstructMenu\n");
- memset(buf, '\0', 8192);
- memset(content, '\0', 4096);
- assert(http->urls);
- for (w = http->urls; w; w = w->next) {
- snprintf(line, 256, "<LI><A HREF=\"%s\">%s</A>\n", w->key, w->key);
- strcat(buf, line);
- }
- snprintf(content, 4096,
- "<TITLE>Select URL for %s</TITLE>\n"
- "<H2>Select URL for %s</H2>\n<UL>\n%s</UL>"
- "<HR>\n"
- "<ADDRESS>\n"
- "Generated by %s/%s@%s\n"
- "</ADDRESS>\n",
- http->uri, http->uri, buf, appname, version_string, getMyHostname());
- memset(buf, '\0', 8192);
- hdr = httpReplyHeader(1.0,
- HTTP_OK,
- "text/html",
- strlen(content),
- 0,
- squid_curtime);
- snprintf(buf, 8192, "%s\r\n%s",
- hdr,
- content);
- return buf;
-}