OSDN Git Service

replace http request implement for bbsmenuretriever.
authorornse01 <ornse01@users.sourceforge.jp>
Sat, 23 Jun 2012 07:24:51 +0000 (07:24 +0000)
committerornse01 <ornse01@users.sourceforge.jp>
Sat, 23 Jun 2012 07:24:51 +0000 (07:24 +0000)
git-svn-id: http://svn.sourceforge.jp/svnroot/bchan/bchanl/trunk@505 20a0b8eb-f62a-4a12-8fe1-b598822500fb

src/bbsmenuretriever.c
src/bbsmenuretriever.h
src/main.c

index 1c6089a..ee5f8ab 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bbsmenuretriever.c
  *
- * Copyright (c) 2009-2010 project bchan
+ * Copyright (c) 2009-2012 project bchan
  *
  * This software is provided 'as-is', without any express or implied
  * warranty. In no event will the authors be held liable for any damages
@@ -34,8 +34,9 @@
 
 #include    "bbsmenuretriever.h"
 
-#include    "retriever.h"
 #include    "bbsmenucache.h"
+#include       <http/http_typedef.h>
+#include       <http/http_connector.h>
 
 #ifdef BCHANL_CONFIG_DEBUG
 # define DP(arg) printf arg
 #endif
 
 struct bbsmnretriever_t_ {
-       retriever_t *retr;
+       http_connector_t *connector;
+       ID endpoint;
+       HTTP_STATUSCODE status;
 };
 
-EXPORT bbsmnretriever_t* bbsmnretriever_new()
+EXPORT bbsmnretriever_t* bbsmnretriever_new(http_connector_t *connector)
 {
        bbsmnretriever_t *retriever;
 
@@ -57,45 +60,21 @@ EXPORT bbsmnretriever_t* bbsmnretriever_new()
        if (retriever == NULL) {
                return NULL;
        }
-       retriever->retr = retriever_new();
-       if (retriever->retr == NULL) {
-               free(retriever);
-               return NULL;
-       }
+       retriever->connector = connector;
+       retriever->endpoint = -1;
+       retriever->status = 0;
 
        return retriever;
 }
 
 EXPORT VOID bbsmnretriever_delete(bbsmnretriever_t *retriever)
 {
-       retriever_delete(retriever->retr);
+       if (retriever->endpoint > 0) {
+               http_connector_deleteendpoint(retriever->connector, retriever->endpoint);
+       }
        free(retriever);
 }
 
-#define SO_ERR_SEND_LEN(sockID, str, len) \
-   err = so_send(sockID, (str), (len), 0); \
-   if(err < 0){ \
-     return err; \
-   }
-
-#define SO_ERR_SEND(sockID, str) SO_ERR_SEND_LEN(sockID, (str), strlen((str)))
-
-LOCAL W bbsmnretriever_sendheader(W sock)
-{
-       W err;
-
-       SO_ERR_SEND(sock, "GET /bbsmenu.html HTTP/1.1\r\n");
-       SO_ERR_SEND(sock, "Accept-Encoding: gzip\r\n");
-       SO_ERR_SEND(sock, "Host: menu.2ch.net\r\n");
-       SO_ERR_SEND(sock, "Accept: */*\r\n");
-       SO_ERR_SEND(sock, "Referer: http://menu.2ch.net/\r\n");
-       SO_ERR_SEND(sock, "Accept-Language: ja\r\n");
-       SO_ERR_SEND(sock, "User-Agent: Monazilla/1.00 (bchanl/0.101)\r\n");
-       SO_ERR_SEND(sock, "Connection: close\r\n");
-       SO_ERR_SEND(sock, "\r\n");
-
-       return 0;
-}
 /* from http://www.monazilla.org/index.php?e=196 */
 #if 0
 "
@@ -112,62 +91,80 @@ Connection: close
 
 EXPORT W bbsmnretriever_sendrequest(bbsmnretriever_t *retriever, bbsmncache_t *cache)
 {
-       W sock, err, ret = -1, len, status;
-       UB *bin, *host = "menu.2ch.net";
+       UB host[] = "menu.2ch.net";
 
-       retriever_clearbuffer(retriever->retr);
-
-       err = retriever_gethost(retriever->retr, host);
-       if (err < 0) {
-               return err;
-       }
-       sock = retriver_connectsocket(retriever->retr);
-       if (sock < 0) {
-               return sock;
+       if (retriever->endpoint > 0) {
+               DP(("bbsmnretriever_sendrequest: requesting\n"));
+               return -1;
        }
 
-       err = bbsmnretriever_sendheader(sock);
-       if (err < 0) {
-               so_close(sock);
-               return err;
+       retriever->endpoint = http_connector_createendpoint(retriever->connector, host, strlen(host), 80, HTTP_METHOD_GET);
+       if (retriever->endpoint < 0) {
+               DP_ER("http_connector_createendpoint error", retriever->endpoint);
+               return -1;
        }
 
-       err = retriever_recieve(retriever->retr, sock);
-       if (err < 0) {
-               so_close(sock);
-               return err;
-       }
-
-       err = retriever_parsehttpresponse(retriever->retr);
-       if (err < 0) {
-               so_close(sock);
-               return err;
-       }
-       retriever_dumpheader(retriever->retr);
+       return 0;
+}
 
-       err = retriever_decompress(retriever->retr);
-       if (err < 0) {
-               so_close(sock);
-               return err;
+EXPORT Bool bbsmnretriever_iswaitingendpoint(bbsmnretriever_t *retriever, ID endpoint)
+{
+       if (retriever->endpoint == endpoint) {
+               return True;
        }
+       return False;
+}
 
-       status = retriever_parse_response_status(retriever->retr);
-       if (status == 200) {
-               bin = retriever_getbody(retriever->retr);
-               len = retriever_getbodylength(retriever->retr);
-               bbsmncache_cleardata(cache);
-               bbsmncache_appenddata(cache, bin, len);
+LOCAL UB path[] = "/bbsmenu.html";
+LOCAL UB header[] =
+"Accept: */*\r\n"
+"Referer: http://menu.2ch.net/\r\n"
+"Accept-Language: ja\r\n"
+"User-Agent: Monazilla/1.00\r\n";
 
-               bin = retriever_getheader(retriever->retr);
-               len = retriever_getheaderlength(retriever->retr);
-               bbsmncache_updatelatestheader(cache, bin, len);
+EXPORT W bbsmnretriever_recievehttpevent(bbsmnretriever_t *retriever, bbsmncache_t *cache, http_connector_event *hevent)
+{
+       http_connector_t *connector = retriever->connector;
 
-               ret = BBSMNRETRIEVER_REQUEST_ALLRELOAD;
+       if (retriever->endpoint <= 0) {
+               return -1;
        }
 
-       so_close(sock);
-
-       retriever_clearbuffer(retriever->retr);
+       if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_SEND) {
+               http_connector_sendrequestline(connector, hevent->endpoint, path, strlen(path));
+               http_connector_sendheader(connector, hevent->endpoint, header, strlen(header));
+               http_connector_sendheaderend(connector, hevent->endpoint);
+               http_connector_sendmessagebody(connector, hevent->endpoint, NULL, 0);
+               http_connector_sendmessagebodyend(connector, hevent->endpoint);
+       } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_STATUSLINE) {
+               DP(("HTTP_CONNECTOR_EVENTTYPE_RECEIVE_STATUSLINE\n"));
+               DP(("    status = %d\n", hevent->data.receive_statusline.statuscode));
+               retriever->status = hevent->data.receive_statusline.statuscode;
+       } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_HEADER) {
+#ifdef BCHANL_CONFIG_DEBUG
+               {
+                       W i = 0;
+                       for (i = 0; i < hevent->data.receive_header.len; i++) {
+                               printf("%c", hevent->data.receive_header.bin[i]);
+                       }
+               }
+#endif
+       } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_HEADER_END) {
+       } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_MESSAGEBODY) {
+               if (retriever->status == HTTP_STATUSCODE_200_OK) {
+                       bbsmncache_appenddata(cache, hevent->data.receive_messagebody.bin, hevent->data.receive_messagebody.len);
+               }
+       } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_MESSAGEBODY_END) {
+               http_connector_deleteendpoint(connector, hevent->endpoint);
+               retriever->endpoint = -1;
+               return BBSMNRETRIEVER_REQUEST_ALLRELOAD;
+       } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_ERROR) {
+               http_connector_deleteendpoint(connector, hevent->endpoint);
+               retriever->endpoint = -1;
+       } else {
+               /* error */
+               return -1;
+       }
 
-       return ret;
+       return BBSMNRETRIEVER_REQUEST_WAITNEXT;
 }
index 4725151..c44d0c4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bbsmenuretriever.h
  *
- * Copyright (c) 2009 project bchan
+ * Copyright (c) 2009-2012 project bchan
  *
  * This software is provided 'as-is', without any express or implied
  * warranty. In no event will the authors be held liable for any damages
 
 #include       <basic.h>
 #include       "bbsmenucache.h"
+#include       <http/http_connector.h>
 
 #ifndef __BBSMENURETREIEVER_H__
 #define __BBSMENURETREIEVER_H__
 
 typedef struct bbsmnretriever_t_ bbsmnretriever_t;
 
-IMPORT bbsmnretriever_t* bbsmnretriever_new();
+IMPORT bbsmnretriever_t* bbsmnretriever_new(http_connector_t *connector);
 IMPORT VOID bbsmnretriever_delete(bbsmnretriever_t *retriever);
 IMPORT W bbsmnretriever_sendrequest(bbsmnretriever_t *retriever, bbsmncache_t *cache);
+IMPORT Bool bbsmnretriever_iswaitingendpoint(bbsmnretriever_t *retriever, ID endpoint);
+IMPORT W bbsmnretriever_recievehttpevent(bbsmnretriever_t *retriever, bbsmncache_t *cache, http_connector_event *hevent);
 
 #define BBSMNRETRIEVER_REQUEST_NOT_MODIFIED 0
 #define BBSMNRETRIEVER_REQUEST_ALLRELOAD    1
+#define BBSMNRETRIEVER_REQUEST_WAITNEXT     2
 
 #endif
index 279a8a4..a2e5ac6 100644 (file)
@@ -58,6 +58,8 @@
 #include    "bchanl_menus.h"
 #include    "bchanl_panels.h"
 
+#include       <http/http_connector.h>
+
 #ifdef BCHANL_CONFIG_DEBUG
 # define DP(arg) printf arg
 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
@@ -144,9 +146,11 @@ struct bchanl_bbsmenu_t_ {
        TC *category_extbbs;
 };
 
+#define BCHANL_NETWORK_FLAG_WAITHTTPEVENT 0x00000001
+
 struct bchanl_t_ {
        W taskid;
-       W mbfid;
+       W flgid; /* for reduce TMOUT message sending. */
 
        bchanl_mainmenu_t mainmenu;
        VID vid;
@@ -154,6 +158,8 @@ struct bchanl_t_ {
 
        bchanl_hmistate_t hmistate;
 
+       http_connector_t *connector;
+
        sbjtretriever_t *retriever;
 
        bchanl_subjecthash_t *subjecthash;
@@ -659,7 +665,7 @@ LOCAL VOID bchanl_bbsmenuwindow_butdn(bchanl_t *bchanl, W dck, PNT evpos)
        }
 }
 
-LOCAL W bchanl_bbsmenu_initialize(bchanl_bbsmenu_t *bchanl, GID gid, bchanl_subjecthash_t *subjecthash, LINK *storage)
+LOCAL W bchanl_bbsmenu_initialize(bchanl_bbsmenu_t *bchanl, GID gid, bchanl_subjecthash_t *subjecthash, LINK *storage, http_connector_t *connector)
 {
        bbsmnretriever_t *retriever;
        bbsmncache_t *cache;
@@ -675,7 +681,7 @@ LOCAL W bchanl_bbsmenu_initialize(bchanl_bbsmenu_t *bchanl, GID gid, bchanl_subj
        if (cache == NULL) {
                goto error_cache;
        }
-       retriever = bbsmnretriever_new();
+       retriever = bbsmnretriever_new(connector);
        if (retriever == NULL) {
                goto error_retriever;
        }
@@ -1007,71 +1013,109 @@ LOCAL VOID bchanl_externalbbswindow_scroll(bchanl_t *bchanl, W dh, W dv)
 
 #define BCHANL_MESSAGE_RETRIEVER_RELAYOUT 1
 #define BCHANL_MESSAGE_RETRIEVER_ERROR -1
+#define BCHANL_MESSAGE_HTTP_EVENT 2
 
-LOCAL VOID bchanl_retriever_task(W arg)
+LOCAL Bool bchanl_bbsmenu_httpevent(bchanl_bbsmenu_t *bchanl, http_connector_event *hevent)
+{
+       Bool ok;
+       W err;
+
+       ok = bbsmnretriever_iswaitingendpoint(bchanl->retriever, hevent->endpoint);
+       if (ok == False) {
+               return False;
+       }
+       err = bbsmnretriever_recievehttpevent(bchanl->retriever, bchanl->cache, hevent);
+
+       switch (err) {
+       case BBSMNRETRIEVER_REQUEST_ALLRELOAD:
+               req_tmg(0, BCHANL_MESSAGE_RETRIEVER_RELAYOUT);
+               break;
+       case BBSMNRETRIEVER_REQUEST_WAITNEXT:
+               break;
+       default:
+               req_tmg(0, BCHANL_MESSAGE_RETRIEVER_ERROR);
+               DP_ER("bbsmnretriever_recievehttpevent", err);
+               break;
+       }
+
+       return True;
+}
+
+LOCAL VOID bchanl_http_task(W arg)
 {
        bchanl_t *bchanl;
+       http_connector_t *connector;
        bbsmnretriever_t *retr;
        bbsmncache_t *cache;
-       W msg,err;
+       W err;
 
        bchanl = (bchanl_t*)arg;
+       connector = bchanl->connector;
        retr = bchanl->bbsmenu.retriever;
        cache = bchanl->bbsmenu.cache;
 
        for (;;) {
-               DP(("before rcv_mbf %d\n", bchanl->mbfid));
-               err = rcv_mbf(bchanl->mbfid, (VP)&msg, T_FOREVER);
-               DP_ER("rcv_mbf error:",err);
-               if (err != 4) {
-                       continue;
-               }
-
-               err = bbsmnretriever_sendrequest(retr, cache);
-
-               switch (err) {
-               case BBSMNRETRIEVER_REQUEST_ALLRELOAD:
-                       req_tmg(0, BCHANL_MESSAGE_RETRIEVER_RELAYOUT);
-                       break;
-               default:
+               err = http_connector_waitconnection(connector, T_FOREVER);
+               if (err < 0) {
+                       DP_ER("http_connector_waitconnection", err);
                        req_tmg(0, BCHANL_MESSAGE_RETRIEVER_ERROR);
-                       DP_ER("bbsmnretreiver_request error",err);
                        break;
                }
+
+               err = wai_flg(bchanl->flgid, BCHANL_NETWORK_FLAG_WAITHTTPEVENT, WF_AND, T_FOREVER);
+               if (err < 0) {
+                       DP_ER("wai_flg", err);
+               }
+               req_tmg(0, BCHANL_MESSAGE_HTTP_EVENT);
        }
 
        ext_tsk();
 }
 
+LOCAL VOID bchanl_handle_httpevent(bchanl_t *bchanl)
+{
+       W err;
+       http_connector_event hevent;
+
+       set_flg(bchanl->flgid, BCHANL_NETWORK_FLAG_WAITHTTPEVENT);
+
+       err = http_connector_getevent(bchanl->connector, &hevent);
+       if (err < 0) {
+               return;
+       }
+
+       bchanl_bbsmenu_httpevent(&bchanl->bbsmenu, &hevent);
+}
+
 LOCAL W bchanl_prepare_network(bchanl_t *bchanl)
 {
        if (bchanl->retriever == NULL) {
                return 0;
        }
 
-       bchanl->mbfid = cre_mbf(sizeof(W), sizeof(W), DELEXIT);
-       if (bchanl->mbfid < 0) {
-               DP_ER("error cre_mbf:", bchanl->mbfid);
-               return -1;
-       }
-       bchanl->taskid = cre_tsk(bchanl_retriever_task, -1, (W)bchanl);
+       bchanl->taskid = cre_tsk(bchanl_http_task, -1, (W)bchanl);
        if (bchanl->taskid < 0) {
-               del_mbf(bchanl->mbfid);
-               bchanl->mbfid = -1;
                DP_ER("error cre_tsk:", bchanl->taskid);
                return -1;
        }
+       bchanl->flgid = cre_flg(0, DELEXIT);
+       if (bchanl->flgid < 0) {
+               ter_tsk(bchanl->taskid);
+               bchanl->taskid = -1;
+               DP_ER("error cre_flg:", bchanl->flgid);
+               return -1;
+       }
 
        return 0;
 }
 
 LOCAL W bchanl_networkrequest_bbsmenu(bchanl_t *bchanl)
 {
-       W msg = 1, err;
+       W err;
        static UW lastrequest = 0;
        UW etime;
 
-       if (bchanl->mbfid < 0) {
+       if (bchanl->flgid < 0) {
                return 0;
        }
 
@@ -1085,11 +1129,15 @@ LOCAL W bchanl_networkrequest_bbsmenu(bchanl_t *bchanl)
        }
        lastrequest = etime;
 
-       err = snd_mbf(bchanl->mbfid, &msg, sizeof(W), T_FOREVER);
+       bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_BUSY);
+
+       err = bbsmnretriever_sendrequest(bchanl->bbsmenu.retriever, bchanl->bbsmenu.cache);
        if (err < 0) {
-               DP_ER("snd_mbf error:", err);
+               DP_ER("bbsmnretriever_sendrequest error:", err);
+               bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_SELECT);
                return err;
        }
+       set_flg(bchanl->flgid, BCHANL_NETWORK_FLAG_WAITHTTPEVENT);
 
        bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_BUSY);
        pdsp_msg(bchanl->hmistate.msg_retr_bbsmenu);
@@ -1111,6 +1159,7 @@ LOCAL W bchanl_initialize(bchanl_t *bchanl, VID vid, W exectype, LINK *storage)
        GID gid;
        RECT w_work;
        PNT p0 = {450, 0};
+       http_connector_t *connector;
        sbjtretriever_t *retriever;
        bchanlhmi_t *hmi;
        bchanl_subjecthash_t *subjecthash;
@@ -1127,6 +1176,12 @@ LOCAL W bchanl_initialize(bchanl_t *bchanl, VID vid, W exectype, LINK *storage)
                bgpat = &bgpat0;
        }
 
+       connector = http_connector_new();
+       if (connector == NULL) {
+               DP_ER("http_connector_new error", 0);
+               goto error_http_connector;
+       }
+
        retriever = sbjtretriever_new();
        if (retriever == NULL) {
                DP_ER("sbjtretriever_new error", 0);
@@ -1171,7 +1226,7 @@ LOCAL W bchanl_initialize(bchanl_t *bchanl, VID vid, W exectype, LINK *storage)
                DP_ER("bchanlhmi_newexternalbbswindow", 0);
                goto error_externalbbswindow;
        }
-       err = bchanl_bbsmenu_initialize(&(bchanl->bbsmenu), gid, subjecthash, storage);
+       err = bchanl_bbsmenu_initialize(&(bchanl->bbsmenu), gid, subjecthash, storage, connector);
        if (err < 0) {
                DP_ER("bchanl_bbsmenu_initialize error", err);
                goto error_bbsmenu;
@@ -1193,6 +1248,7 @@ LOCAL W bchanl_initialize(bchanl_t *bchanl, VID vid, W exectype, LINK *storage)
        bbsmndraw_setviewrect(bchanl->bbsmenu.draw, 0, 0, w_work.c.right, w_work.c.bottom);
        bbsmenuwindow_setworkrect(bbsmenuwindow, 0, 0, w_work.c.right, w_work.c.bottom);
 
+       bchanl->connector = connector;
        bchanl->retriever = retriever;
        bchanl->subjecthash = subjecthash;
 
@@ -1232,6 +1288,8 @@ error_subjectwindow:
 error_bchanlhmi:
        sbjtretriever_delete(retriever);
 error_retriever:
+       http_connector_delete(connector);
+error_http_connector:
        return -1; /* TODO */
 }
 
@@ -1253,6 +1311,7 @@ LOCAL VOID bchanl_killme(bchanl_t *bchanl)
        bchanlhmi_deletesubjectwindow(bchanl->hmi, bchanl->subjectwindow);
        bchanlhmi_delete(bchanl->hmi);
        sbjtretriever_delete(bchanl->retriever);
+       http_connector_delete(bchanl->connector);
 
        ext_prc(0);
 }
@@ -1803,6 +1862,9 @@ LOCAL VOID bchanl_handletimeout(bchanl_t *bchanl, W code)
                bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_SELECT);
                pdsp_msg(NULL);
                break;
+       case BCHANL_MESSAGE_HTTP_EVENT:
+               bchanl_handle_httpevent(bchanl);
+               break;
        }
 }