Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/pazpar2
authorDennis Schafroth <dennis@indexdata.com>
Mon, 7 Nov 2011 09:23:54 +0000 (10:23 +0100)
committerDennis Schafroth <dennis@indexdata.com>
Mon, 7 Nov 2011 09:23:54 +0000 (10:23 +0100)
1  2 
src/http_command.c
src/session.h

diff --combined src/http_command.c
@@@ -126,7 -126,7 +126,7 @@@ void http_sessions_destroy(http_session
          {
              struct http_session *s_next = s->next;
              iochan_destroy(s->timeout_iochan);
-             destroy_session(s->psession);
+             session_destroy(s->psession);
              nmem_destroy(s->nmem);
              s = s_next;
          }
@@@ -199,7 -199,7 +199,7 @@@ void http_session_destroy(struct http_s
      {   /* destroying for real */
          yaz_log(http_sessions->log_level, "%p HTTP Session %u destroyed", s, s->session_id);
          iochan_destroy(s->timeout_iochan);
-         destroy_session(s->psession);
+         session_destroy(s->psession);
          http_session_use(-1);
          nmem_destroy(s->nmem);
      }
@@@ -229,7 -229,6 +229,7 @@@ static const char *get_msg(enum pazpar2
          { PAZPAR2_RECORD_FAIL, "Record command failed"},
          { PAZPAR2_NOT_IMPLEMENTED, "Not implemented"},
          { PAZPAR2_NO_SERVICE, "No service"},
 +        { PAZPAR2_ALREADY_BLOCKED, "Already blocked in session on: "},
          { PAZPAR2_LAST_ERROR, "Last error"},
          { 0, 0 }
      };
@@@ -321,8 -320,8 +321,8 @@@ unsigned int make_sessionid(void
  
  static struct http_session *locate_session(struct http_channel *c)
  {
 -    struct http_response *rs = c->response;
      struct http_request *rq = c->request;
 +    struct http_response *rs = c->response;
      struct http_session *p;
      const char *session = http_argbyname(rq, "session");
      http_sessions_t http_sessions = c->http_sessions;
@@@ -509,7 -508,7 +509,7 @@@ static void cmd_settings(struct http_ch
      release_session(c, s);
  }
  
 -static void cmd_termlist(struct http_channel *c)
 +static void termlist_response(struct http_channel *c)
  {
      struct http_request *rq = c->request;
      struct http_session *s = locate_session(c);
      int num = 15;
      int status;
  
      if (nums)
          num = atoi(nums);
  
 +    status = session_active_clients(s->psession);
 +
      response_open_no_status(c, "termlist");
      wrbuf_printf(c->wrbuf, "<activeclients>%d</activeclients>\n", status);
  
      release_session(c, s);
  }
  
 +static void termlist_result_ready(void *data)
 +{
 +    struct http_channel *c = (struct http_channel *) data;
 +    yaz_log(c->http_sessions->log_level, "termlist watch released");
 +    termlist_response(c);
 +}
 +
 +static void cmd_termlist(struct http_channel *c)
 +{
 +    struct http_request *rq = c->request;
 +    struct http_response *rs = c->response;
 +    struct http_session *s = locate_session(c);
 +    const char *block = http_argbyname(rq, "block");
 +    int active_clients;
 +    if (!s)
 +        return;
 +
 +    active_clients = session_active_clients(s->psession);
 +
 +    if (block && !strcmp("1", block) && active_clients)
 +    {
 +        // if there is already a watch/block. we do not block this one
 +        if (session_set_watch(s->psession, SESSION_WATCH_TERMLIST,
 +                              termlist_result_ready, c, c) != 0)
 +        {
 +            yaz_log(YLOG_WARN, "Attempt to block multiple times on termlist block. Not supported!");
 +            error(rs, PAZPAR2_ALREADY_BLOCKED, "termlist");
 +        }
 +        else
 +        {
 +            yaz_log(c->http_sessions->log_level, "%p Session %u: Blocking on command termlist", s, s->session_id);
 +        }
 +        release_session(c, s);
 +        return;
 +    }
 +
 +    termlist_response(c);
 +    release_session(c, s);
 +}
 +
  size_t session_get_memory_status(struct session *session);
  
  static void session_status(struct http_channel *c, struct http_session *s)
@@@ -638,17 -600,20 +638,17 @@@ static void cmd_server_status(struct ht
      xmalloc_trav(0);
  }
  
 -
 -static void cmd_bytarget(struct http_channel *c)
 -{
 -    struct http_request *rq = c->request;
 -    struct http_session *s = locate_session(c);
 +static void bytarget_response(struct http_channel *c) {
 +    int count, i;
      struct hitsbytarget *ht;
 +    struct http_request *rq = c->request;
      const char *settings = http_argbyname(rq, "settings");
 -    int count, i;
 +    struct http_session *s = locate_session(c);
  
 -    if (!s)
 -        return;
      ht = get_hitsbytarget(s->psession, &count, c->nmem);
      response_open(c, "bytarget");
 -
 +    if (count == 0)
 +        yaz_log(YLOG_WARN, "Empty bytarget Response. No targets found!");
      for (i = 0; i < count; i++)
      {
          wrbuf_puts(c->wrbuf, "\n<target>");
      release_session(c, s);
  }
  
 +static void bytarget_result_ready(void *data)
 +{
 +    struct http_channel *c = (struct http_channel *) data;
 +    yaz_log(c->http_sessions->log_level, "bytarget watch released");
 +    bytarget_response(c);
 +}
 +
 +
 +static void cmd_bytarget(struct http_channel *c)
 +{
 +    struct http_request *rq = c->request;
 +    struct http_response *rs = c->response;
 +    struct http_session *s = locate_session(c);
 +    const char *block = http_argbyname(rq, "block");
 +    int no_active;
 +
 +    if (!s)
 +        return;
 +
 +    no_active = session_active_clients(s->psession);
 +
 +    if (block && !strcmp("1",block) && no_active)
 +    {
 +        // if there is already a watch/block. we do not block this one
 +        if (session_set_watch(s->psession, SESSION_WATCH_BYTARGET,
 +                              bytarget_result_ready, c, c) != 0)
 +        {
 +            yaz_log(YLOG_WARN, "Attempt to block multiple times on bytarget block. Not supported!");
 +            error(rs, PAZPAR2_ALREADY_BLOCKED, "bytarget"); 
 +        }
 +        else
 +        {
 +            yaz_log(c->http_sessions->log_level, "%p Session %u: Blocking on command bytarget", s, s->session_id);
 +        }
 +        release_session(c, s);
 +        return;
 +    }
 +    bytarget_response(c);
 +    release_session(c, s);
 +}
 +
  static void write_metadata(WRBUF w, struct conf_service *service,
          struct record_metadata **ml, int full)
  {
@@@ -941,7 -865,7 +941,7 @@@ static void cmd_record(struct http_chan
  static void cmd_record_ready(void *data)
  {
      struct http_channel *c = (struct http_channel *) data;
 -
 +    yaz_log(c->http_sessions->log_level, "record watch released");
      cmd_record(c);
  }
  
@@@ -1023,14 -947,13 +1023,14 @@@ static void show_records(struct http_ch
  static void show_records_ready(void *data)
  {
      struct http_channel *c = (struct http_channel *) data;
 -
 +    yaz_log(c->http_sessions->log_level, "show watch released");
      show_records(c, -1);
  }
  
  static void cmd_show(struct http_channel *c)
  {
 -    struct http_request *rq = c->request;
 +    struct http_request  *rq = c->request;
 +    struct http_response *rs = c->response;
      struct http_session *s = locate_session(c);
      const char *block = http_argbyname(rq, "block");
      const char *sort = http_argbyname(rq, "sort");
          {
              // if there is already a watch/block. we do not block this one
              if (session_set_watch(s->psession, SESSION_WATCH_SHOW_PREF,
 -                                  show_records_ready, c, c) != 0)
 +                                  show_records_ready, c, c) == 0)
              {
                  yaz_log(c->http_sessions->log_level,
 -                        "%p Session %u: Blocking on cmd_show. Waiting for preferred targets", s, s->session_id);
 +                        "%p Session %u: Blocking on command show (preferred targets)", s, s->session_id);
 +            }
 +            else
 +            {
 +                yaz_log(YLOG_WARN, "Attempt to block multiple times on show (preferred targets) block. Not supported!");
 +                error(rs, PAZPAR2_ALREADY_BLOCKED, "show (preferred targets)"); 
              }
              release_session(c, s);
              return;
              if (session_set_watch(s->psession, SESSION_WATCH_SHOW,
                                    show_records_ready, c, c) != 0)
              {
 -                yaz_log(c->http_sessions->log_level, "%p Session %u: Blocking on cmd_show", s, s->session_id);
 +                yaz_log(YLOG_WARN, "Attempt to block multiple times on show block. Not supported!");
 +                error(rs, PAZPAR2_ALREADY_BLOCKED, "show"); 
 +            }
 +            else
 +            {
 +                yaz_log(c->http_sessions->log_level, "%p Session %u: Blocking on command show", s, s->session_id);
              }
              release_session(c, s);
              return;
diff --combined src/session.h
@@@ -48,7 -48,6 +48,7 @@@ enum pazpar2_error_code 
      PAZPAR2_RECORD_FAIL,
      PAZPAR2_NOT_IMPLEMENTED,
      PAZPAR2_NO_SERVICE,
 +    PAZPAR2_ALREADY_BLOCKED,
  
      PAZPAR2_LAST_ERROR
  };
@@@ -76,9 -75,7 +76,9 @@@ struct session_databas
  #define SESSION_WATCH_SHOW      0
  #define SESSION_WATCH_RECORD    1
  #define SESSION_WATCH_SHOW_PREF 2
 -#define SESSION_WATCH_MAX       2
 +#define SESSION_WATCH_TERMLIST  3
 +#define SESSION_WATCH_BYTARGET  4
 +#define SESSION_WATCH_MAX       4
  
  #define SESSION_MAX_TERMLISTS 10
  
@@@ -147,7 -144,7 +147,7 @@@ struct hitsbytarget 
  struct hitsbytarget *get_hitsbytarget(struct session *s, int *count, NMEM nmem);
  struct session *new_session(NMEM nmem, struct conf_service *service,
                              unsigned session_id);
- void destroy_session(struct session *s);
+ void session_destroy(struct session *s);
  void session_init_databases(struct session *s);
  void statistics(struct session *s, struct statistics *stat);