/*
* 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
#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;
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
"
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;
}
/*
* 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
#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)
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;
bchanl_hmistate_t hmistate;
+ http_connector_t *connector;
+
sbjtretriever_t *retriever;
bchanl_subjecthash_t *subjecthash;
}
}
-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;
if (cache == NULL) {
goto error_cache;
}
- retriever = bbsmnretriever_new();
+ retriever = bbsmnretriever_new(connector);
if (retriever == NULL) {
goto error_retriever;
}
#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;
}
}
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);
GID gid;
RECT w_work;
PNT p0 = {450, 0};
+ http_connector_t *connector;
sbjtretriever_t *retriever;
bchanlhmi_t *hmi;
bchanl_subjecthash_t *subjecthash;
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);
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;
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;
error_bchanlhmi:
sbjtretriever_delete(retriever);
error_retriever:
+ http_connector_delete(connector);
+error_http_connector:
return -1; /* TODO */
}
bchanlhmi_deletesubjectwindow(bchanl->hmi, bchanl->subjectwindow);
bchanlhmi_delete(bchanl->hmi);
sbjtretriever_delete(bchanl->retriever);
+ http_connector_delete(bchanl->connector);
ext_prc(0);
}
bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_SELECT);
pdsp_msg(NULL);
break;
+ case BCHANL_MESSAGE_HTTP_EVENT:
+ bchanl_handle_httpevent(bchanl);
+ break;
}
}