+++ /dev/null
-list
-break 54
-cont
-print argv
-print argc
-cont
-quit
-break load_targets
-run -c 2000
-finish
-print channel_list
-print *channel_list
-print *channel_list->data
-print *channel_list->next
-next
-break handler
-cont
-next
-print *target
-print *t
-next
-print res
-print errno
-print erddrno
-print (int)errno
-quit
-run -c 2000
-run -c 2001
-run
-run -c 2000
-break handler
-cont
-next
-print res
-next
-cont
-next
-h
-run -c 2001
-next
-cont
-next
-cont
-print channel_list
-print *channel_list
-print *channel_list->next
-print *channel_list->next->next
-run -c 2000
-next
-cont
-next
-cont
-next
-print *a
-print *a->u.initResponse
-next
-step
-next
-cont
-delete 1
-cont
-cont
-run -c 2000
-bt
-frame 4
-list
-print *session
-print *s
-list
-print *i
-run
-run -c 2001
-run -c 2000
-run -c 2001
-run -c 2000
-cont
-quit
-run -c 2000
-break handler
-cont
-cont
-cont
-cont
-cont
-next
-print *p
-next
-print *p
-next
-next
-print *p
-next
-print *p
-next
-cont
-next
-print *t
-next
-print *t
-print *s
-next
-quit
-break do_presentResponse
-run -c 2002
-next
-print *r
-print *r->presentStatus
-print *r->numberOfRecordsReturned
-quit
-break process_record
-run -c 2001
-next
-step
-bt
-finish
-quit
-run -c 2000
-run -c 2001
-run -c 2002
-print put - out
-print pout - out
-print out
-print p
-run -c 2000
-run -c 2001
-quit
-run -c 2001
-bt
-frame 1
-print *channel_list
-print *channel_list->data
-print *((struct target*)channel_list->data)
-print *((struct target*)channel_list->data)->session
-print *((struct target*)channel_list->data)->session->rechear[0]
-print *((struct target*)channel_list->data)->session->recheap[0]
-print *((struct target*)channel_list->data)->session->recheap[1]
-print *((struct target*)channel_list->data)->session->recheap[2]
-print *((struct target*)channel_list->data)->session->recheap[3]
-print *((struct target*)channel_list->data)->session->recheap[4]
-print *((struct target*)channel_list->data)->session->recheap[5]
-cont
-list
-bt
-frame 3
-print *s
-run -c 2000
-bt
-frame 1
-print *channel_list
-print *((struct target*)channel_list->data)
-print *((struct target*)channel_list->data)->target
-print *((struct target*)channel_list->data)->session
-print *((struct target*)channel_list->data)->session->recheap[0]
-quit
-run -c 2000
-run -c 2002
-bt
-frame 2
-list
-print *num
-print *recs[0]
-print *recs[1]
-print *recs[2]
-print *recs[3]
-print *recs[4]
-bt
-frame rewind_recheap
-frame 1
-list
-print *S
-print *s
-bt
-frame 2
-break
-run
-run -c 2000
-bt
-list breakpoints
-delete
-frame 2
-break 865
-list
-run -c 2001
-print *s
-step
-next
-step
-next
-print *s
-next
-step
-print parent
-step
-print *s
-print p
-print *s->recheap[0]
-run -c 2000
-print *s
-print *s->recheap[99]
-step
-print *s
-print *s->recheap[93]
-run -c 2001
-delete
-cont
-quit
-list show
-function show
-help
-list
-quit
-quit
-list show
-list cmd_show
-break 99
-run -c 2000
-print *r
-next
-print r
-print *rt
-print *r
-cont
-print *r
-print r
-print *r->next
-print *r->next_cluster
-print *r->next_cluster->next_cluster
-quit
-quit
-run -c 2000
-run -c 2001
-bt
-frame 1
-print *r
-quit
-run -c 2000
-quit
-run -c 2001
-run -c 2000
-list handler
-break 622
-run -c 2000
-run -c 2001
-cont
-cont
-next
-print len
-cont
-next
-print len
-cont
-run
-run -c 2000
-delete
-cont
-quit
/*
- * $Id: http.c,v 1.4 2006-11-27 14:35:15 quinn Exp $
+ * $Id: http.c,v 1.5 2006-12-08 21:40:58 quinn Exp $
*/
#include <stdio.h>
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>
+#include <assert.h>
#include <yaz/yaz-util.h>
#include <yaz/comstack.h>
#include "http_command.h"
static void proxy_io(IOCHAN i, int event);
+static struct http_channel *http_create(void);
+static void http_destroy(IOCHAN i);
extern IOCHAN channel_list;
static struct sockaddr_in *proxy_addr = 0; // If this is set, we proxy normal HTTP requests
static char proxy_url[256] = "";
static struct http_buf *http_buf_freelist = 0;
+static struct http_channel *http_channel_freelist = 0;
static struct http_buf *http_buf_create()
{
static struct http_buf *http_buf_bywrbuf(WRBUF wrbuf)
{
+ // Heavens to Betsy (buf)!
return http_buf_bybuf(wrbuf_buf(wrbuf), wrbuf_len(wrbuf));
}
wrbuf_printf(c->wrbuf, "HTTP/1.1 %s %s\r\n", r->code, r->msg);
for (h = r->headers; h; h = h->next)
wrbuf_printf(c->wrbuf, "%s: %s\r\n", h->name, h->value);
- wrbuf_printf(c->wrbuf, "Content-length: %d\r\n", r->payload ? strlen(r->payload) : 0);
+ wrbuf_printf(c->wrbuf, "Content-length: %d\r\n", r->payload ? (int) strlen(r->payload) : 0);
wrbuf_printf(c->wrbuf, "Content-type: text/xml\r\n");
wrbuf_puts(c->wrbuf, "\r\n");
}
-// Cleanup
-static void http_destroy(IOCHAN i)
-{
- struct http_channel *s = iochan_getdata(i);
-
- if (s->proxy)
- {
- if (s->proxy->iochan)
- {
- close(iochan_getfd(s->proxy->iochan));
- iochan_destroy(s->proxy->iochan);
- }
- http_buf_destroy_queue(s->proxy->oqueue);
- xfree(s->proxy);
- }
- http_buf_destroy_queue(s->iqueue);
- http_buf_destroy_queue(s->oqueue);
- nmem_destroy(s->nmem);
- wrbuf_free(s->wrbuf, 1);
- xfree(s);
- close(iochan_getfd(i));
- iochan_destroy(i);
-}
-
static int http_weshouldproxy(struct http_request *rq)
{
if (proxy_addr && !strstr(rq->path, "search.pz2"))
return 0;
}
+void http_send_response(struct http_channel *ch)
+{
+ struct http_response *rs = ch->response;
+ assert(rs);
+ struct http_buf *hb = http_serialize_response(ch, rs);
+ if (!hb)
+ {
+ yaz_log(YLOG_WARN, "Failed to serialize HTTP response");
+ http_destroy(ch->iochan);
+ }
+ else
+ {
+ http_buf_enqueue(&ch->oqueue, hb);
+ iochan_setflag(ch->iochan, EVENT_OUTPUT);
+ ch->state = Http_Idle;
+ }
+}
+
static void http_io(IOCHAN i, int event)
{
struct http_channel *hc = iochan_getdata(i);
- struct http_request *request;
- struct http_response *response;
switch (event)
{
http_buf_enqueue(&hc->iqueue, htbuf);
}
+ if (hc->state == Http_Busy)
+ return;
+
if ((reqlen = request_check(hc->iqueue)) <= 2)
return;
nmem_reset(hc->nmem);
- if (!(request = http_parse_request(hc, &hc->iqueue, reqlen)))
+ if (!(hc->request = http_parse_request(hc, &hc->iqueue, reqlen)))
{
yaz_log(YLOG_WARN, "Failed to parse request");
http_destroy(i);
return;
}
- yaz_log(YLOG_LOG, "Request: %s %s v %s", request->method, request->path,
- request->http_version);
- if (http_weshouldproxy(request))
- http_proxy(request);
+ hc->response = 0;
+ yaz_log(YLOG_LOG, "Request: %s %s v %s", hc->request->method,
+ hc->request->path, hc->request->http_version);
+ if (http_weshouldproxy(hc->request))
+ http_proxy(hc->request);
else
{
- struct http_buf *hb;
// Execute our business logic!
- response = http_command(request);
- if (!response)
- {
- http_destroy(i);
- return;
- }
- if (!(hb = http_serialize_response(hc, response)))
- {
- http_destroy(i);
- return;
- }
- http_buf_enqueue(&hc->oqueue, hb);
- iochan_setflags(i, EVENT_OUTPUT); // Turns off input selecting
+ hc->state = Http_Busy;
+ http_command(hc);
}
if (hc->iqueue)
{
return;
}
else
- iochan_setflags(i, EVENT_INPUT); // Turns off output flag
+ {
+ iochan_clearflag(i, EVENT_OUTPUT);
+ if (hc->iqueue)
+ iochan_setevent(hc->iochan, EVENT_INPUT);
+ }
}
}
}
}
+// Cleanup channel
+static void http_destroy(IOCHAN i)
+{
+ struct http_channel *s = iochan_getdata(i);
+
+ if (s->proxy)
+ {
+ if (s->proxy->iochan)
+ {
+ close(iochan_getfd(s->proxy->iochan));
+ iochan_destroy(s->proxy->iochan);
+ }
+ http_buf_destroy_queue(s->proxy->oqueue);
+ xfree(s->proxy);
+ }
+ s->next = http_channel_freelist;
+ http_channel_freelist = s;
+ close(iochan_getfd(i));
+ iochan_destroy(i);
+}
+
+static struct http_channel *http_create(void)
+{
+ struct http_channel *r = http_channel_freelist;
+
+ if (r)
+ {
+ http_channel_freelist = r->next;
+ nmem_reset(r->nmem);
+ wrbuf_rewind(r->wrbuf);
+ }
+ else
+ {
+ r = xmalloc(sizeof(struct http_channel));
+ r->nmem = nmem_create();
+ r->wrbuf = wrbuf_alloc();
+ }
+ r->proxy = 0;
+ r->iochan = 0;
+ r->iqueue = r->oqueue = 0;
+ r->state = Http_Idle;
+ r->request = 0;
+ r->response = 0;
+ return r;
+}
+
+
/* Accept a new command connection */
static void http_accept(IOCHAN i, int event)
{
yaz_log(YLOG_LOG, "New command connection");
c = iochan_create(s, http_io, EVENT_INPUT | EVENT_EXCEPT);
- ch = xmalloc(sizeof(*ch));
- ch->proxy = 0;
- ch->nmem = nmem_create();
- ch->wrbuf = wrbuf_alloc();
+ ch = http_create();
ch->iochan = c;
- ch->iqueue = ch->oqueue = 0;
iochan_setdata(c, ch);
c->next = channel_list;
struct http_buf *oqueue;
char version[10];
struct http_proxy *proxy;
+ enum
+ {
+ Http_Idle,
+ Http_Busy // Don't process new HTTP requests
+ } state;
NMEM nmem;
WRBUF wrbuf;
+ struct http_request *request;
+ struct http_response *response;
+ struct http_channel *next; // for freelist
};
struct http_proxy // attached to iochan for proxy connection
char *http_argbyname(struct http_request *r, char *name);
char *http_headerbyname(struct http_request *r, char *name);
struct http_response *http_create_response(struct http_channel *c);
+void http_send_response(struct http_channel *c);
/*
* Local variables:
-/*
- * $Id: http_command.c,v 1.6 2006-12-04 02:27:02 quinn Exp $
+/*_response(c, rs);
+ * $Id: http_command.c,v 1.7 2006-12-08 21:40:58 quinn Exp $
*/
#include <stdio.h>
strcpy(rs->code, code);
sprintf(tmp, "<error code=\"general\">%s</error>", txt);
rs->payload = nmem_strdup(c->nmem, tmp);
+ http_send_response(c);
}
int make_sessionid()
return 0;
}
-static void cmd_exit(struct http_request *rq, struct http_response *rs)
+static void cmd_exit(struct http_channel *c)
{
yaz_log(YLOG_WARN, "exit");
exit(0);
}
-static void cmd_init(struct http_request *rq, struct http_response *rs)
+static void cmd_init(struct http_channel *c)
{
int sesid;
char buf[1024];
struct http_session *s = http_session_create();
+ struct http_response *rs = c->response;
// FIXME create a pazpar2 session
yaz_log(YLOG_DEBUG, "HTTP Session init");
sesid = make_sessionid();
s->session_id = sesid;
sprintf(buf, "<init><status>OK</status><session>%d</session></init>", sesid);
- rs->payload = nmem_strdup(rq->channel->nmem, buf);
+ rs->payload = nmem_strdup(c->nmem, buf);
+ http_send_response(c);
}
-static void cmd_termlist(struct http_request *rq, struct http_response *rs)
+static void cmd_termlist(struct http_channel *c)
{
+ struct http_response *rs = c->response;
+ struct http_request *rq = c->request;
struct http_session *s = locate_session(rq, rs);
- struct http_channel *c = rq->channel;
struct termlist_score **p;
int len;
int i;
}
wrbuf_puts(c->wrbuf, "</termlist>");
rs->payload = nmem_strdup(rq->channel->nmem, wrbuf_buf(c->wrbuf));
+ http_send_response(c);
}
-static void cmd_bytarget(struct http_request *rq, struct http_response *rs)
+static void cmd_bytarget(struct http_channel *c)
{
+ struct http_response *rs = c->response;
+ struct http_request *rq = c->request;
struct http_session *s = locate_session(rq, rs);
- struct http_channel *c = rq->channel;
struct hitsbytarget *ht;
int count, i;
wrbuf_puts(c->wrbuf, "</bytarget>");
rs->payload = nmem_strdup(c->nmem, wrbuf_buf(c->wrbuf));
+ http_send_response(c);
}
-static void cmd_show(struct http_request *rq, struct http_response *rs)
+static void cmd_show(struct http_channel *c)
{
+ struct http_request *rq = c->request;
+ struct http_response *rs = c->response;
struct http_session *s = locate_session(rq, rs);
- struct http_channel *c = rq->channel;
struct record **rl;
char *start = http_argbyname(rq, "start");
char *num = http_argbyname(rq, "num");
wrbuf_puts(c->wrbuf, "</show>\n");
rs->payload = nmem_strdup(c->nmem, wrbuf_buf(c->wrbuf));
+ http_send_response(c);
}
-static void cmd_search(struct http_request *rq, struct http_response *rs)
+static void cmd_search(struct http_channel *c)
{
+ struct http_request *rq = c->request;
+ struct http_response *rs = c->response;
struct http_session *s = locate_session(rq, rs);
char *query = http_argbyname(rq, "query");
char *res;
return;
}
rs->payload = "<search><status>OK</status></search>";
+ http_send_response(c);
}
-static void cmd_stat(struct http_request *rq, struct http_response *rs)
+static void cmd_stat(struct http_channel *c)
{
+ struct http_request *rq = c->request;
+ struct http_response *rs = c->response;
struct http_session *s = locate_session(rq, rs);
- struct http_channel *c = rq->channel;
struct statistics stat;
if (!s)
wrbuf_printf(c->wrbuf, "<error>%d</error>\n", stat.num_error);
wrbuf_puts(c->wrbuf, "</stat>");
rs->payload = nmem_strdup(c->nmem, wrbuf_buf(c->wrbuf));
+ http_send_response(c);
}
-#ifdef GAGA
-static void cmd_load(struct http_request *rq, struct http_response *rs)
-{
- struct http_session *s = locate_session(rq, rs);
- char *fn = http_argbyname(rq, "name");
-
- if (!s)
- return;
- if (!fn)
- {
- error(rs, "417", "Must suppply name", 0);
- return;
- }
- if (load_targets(s->psession, fn) < 0)
- error(rs, "417", "Failed to find targets", "Possibly wrong filename");
- else
- rs->payload = "<load><status>OK</status></load>";
-}
-#endif
struct {
char *name;
- void (*fun)(struct http_request *rq, struct http_response *rs);
+ void (*fun)(struct http_channel *c);
} commands[] = {
{ "init", cmd_init },
{ "stat", cmd_stat },
{0,0}
};
-struct http_response *http_command(struct http_request *rq)
+void http_command(struct http_channel *c)
{
- char *command = http_argbyname(rq, "command");
- struct http_channel *c = rq->channel;
+ char *command = http_argbyname(c->request, "command");
struct http_response *rs = http_create_response(c);
int i;
+ c->response = rs;
if (!command)
{
error(rs, "417", "Must supply command", 0);
- return rs;
+ return;
}
for (i = 0; commands[i].name; i++)
if (!strcmp(commands[i].name, command))
{
- (*commands[i].fun)(rq, rs);
+ (*commands[i].fun)(c);
break;
}
if (!commands[i].name)
error(rs, "417", "Unknown command", 0);
- return rs;
+ return;
}
/*
#include "http.h"
-struct http_response *http_command(struct http_request *r);
+void http_command(struct http_channel *c);
#endif
-/* $Id: pazpar2.c,v 1.10 2006-12-04 03:31:24 quinn Exp $ */;
+/* $Id: pazpar2.c,v 1.11 2006-12-08 21:40:58 quinn Exp $ */;
#include <stdlib.h>
#include <stdio.h>
}
}
wrbuf_putc(s->wrbuf, '\0');
- obuf = nmem_strdup(s->nmem, wrbuf_buf(s->wrbuf));
+ obuf = (unsigned char*) nmem_strdup(s->nmem, wrbuf_buf(s->wrbuf));
for (p = obuf; *p; p++)
if (*p == '&' || *p == '<' || *p > 122 || *p < ' ')
*p = ' ';
- return obuf;
+ return (char*) obuf;
}
// Extract 245 $a $b 100 $a
/*
- * $Id: reclists.c,v 1.3 2006-11-27 14:35:15 quinn Exp $
+ * $Id: reclists.c,v 1.4 2006-12-08 21:40:58 quinn Exp $
*/
#include <assert.h>
struct reclist_bucket **p;
struct record *head;
- bucket = hash(record->merge_key) & l->hashmask;
+ bucket = hash((unsigned char*) record->merge_key) & l->hashmask;
for (p = &l->hashtable[bucket]; *p; p = &(*p)->next)
{
// We found a matching record. Merge them
/*
- * $Id: termlists.c,v 1.2 2006-11-27 14:35:15 quinn Exp $
+ * $Id: termlists.c,v 1.3 2006-12-08 21:40:58 quinn Exp $
*/
#include <stdlib.h>
unsigned int bucket;
struct termlist_bucket **p;
- bucket = hash(term) & tl->hashmask;
+ bucket = hash((unsigned char *)term) & tl->hashmask;
for (p = &tl->hashtable[bucket]; *p; p = &(*p)->next)
{
if (!strcmp(term, (*p)->term.term))