replace http request implement for subjectretriever.
@@ -165,6 +165,7 @@ | ||
165 | 165 | bchanl_subjecthash_t *subjecthash; |
166 | 166 | bchanl_bbsmenu_t bbsmenu; |
167 | 167 | bchanl_subject_t *currentsubject; |
168 | + bchanl_subject_t *nextsubject; | |
168 | 169 | struct { |
169 | 170 | Bool resnum; |
170 | 171 | Bool since; |
@@ -425,6 +426,11 @@ | ||
425 | 426 | subjectwindow_requestredisp(bchanl->subjectwindow); |
426 | 427 | } |
427 | 428 | |
429 | +LOCAL VOID bchanl_setnextsubject(bchanl_t *bchanl, bchanl_subject_t *sbjt) | |
430 | +{ | |
431 | + bchanl->nextsubject = sbjt; | |
432 | +} | |
433 | + | |
428 | 434 | LOCAL VOID bchanl_bbsmenuwindow_draw(bchanl_t *bchanl) |
429 | 435 | { |
430 | 436 | RECT r; |
@@ -582,11 +588,7 @@ | ||
582 | 588 | LOCAL VOID bchanl_sendsubjectrequest(bchanl_t *bchanl, bchanl_subject_t *subject) |
583 | 589 | { |
584 | 590 | sbjtcache_t *cache; |
585 | - sbjtlayout_t *layout; | |
586 | - sbjtdraw_t *draw; | |
587 | - TC *title; | |
588 | - RECT w_work; | |
589 | - W l, t, r, b, title_len, err; | |
591 | + W err; | |
590 | 592 | |
591 | 593 | bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_BUSY); |
592 | 594 | pdsp_msg(bchanl->hmistate.msg_retr_subject); |
@@ -598,29 +600,8 @@ | ||
598 | 600 | bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_SELECT); |
599 | 601 | return; |
600 | 602 | } |
601 | - | |
602 | - pdsp_msg(NULL); | |
603 | - bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_SELECT); | |
604 | - | |
605 | - subjectoptionwindow_setfiltertext(bchanl->subjectoptionwindow, NULL, 0); | |
606 | - err = subjectoptionwindow_setordervalue(bchanl->subjectoptionwindow, SUBJECTOPTIONWINDOW_ORDERVALUE_ASCENDING); | |
607 | - subjectoptionwindow_setorderbyvalue(bchanl->subjectoptionwindow, SUBJECTOPTIONWINDOW_ORDERBYVALUE_NUMBER); | |
608 | - | |
609 | - bchanl_subject_relayout(subject); | |
610 | - | |
611 | - bchanl_setcurrentsubject(bchanl, subject); | |
612 | - | |
613 | - subjectwindow_getworkrect(bchanl->subjectwindow, &w_work); | |
614 | - draw = bchanl_subject_getdraw(subject); | |
615 | - sbjtdraw_setviewrect(draw, 0, 0, w_work.c.right, w_work.c.bottom); | |
616 | - subjectwindow_setworkrect(bchanl->subjectwindow, 0, 0, w_work.c.right, w_work.c.bottom); | |
617 | - | |
618 | - layout = bchanl_subject_getlayout(subject); | |
619 | - sbjtlayout_getdrawrect(layout, &l, &t, &r, &b); | |
620 | - subjectwindow_setdrawrect(bchanl->subjectwindow, l, t, r, b); | |
621 | - | |
622 | - bchanl_subject_gettitle(subject, &title, &title_len); | |
623 | - subjectwindow_settitle(bchanl->subjectwindow, title); | |
603 | + bchanl_setnextsubject(bchanl, subject); | |
604 | + set_flg(bchanl->flgid, BCHANL_NETWORK_FLAG_WAITHTTPEVENT); | |
624 | 605 | } |
625 | 606 | |
626 | 607 | LOCAL VOID bchanl_bbsmenuwindow_click(bchanl_t *bchanl, PNT pos) |
@@ -1041,6 +1022,69 @@ | ||
1041 | 1022 | return True; |
1042 | 1023 | } |
1043 | 1024 | |
1025 | +LOCAL Bool bchanl_subject_httpevent(bchanl_t *bchanl, http_connector_event *hevent) | |
1026 | +{ | |
1027 | + Bool ok; | |
1028 | + W err; | |
1029 | + sbjtcache_t *cache; | |
1030 | + sbjtlayout_t *layout; | |
1031 | + sbjtdraw_t *draw; | |
1032 | + TC *title; | |
1033 | + RECT w_work; | |
1034 | + W l, t, r, b, title_len; | |
1035 | + | |
1036 | + if (bchanl->nextsubject == NULL) { | |
1037 | + return False; | |
1038 | + } | |
1039 | + | |
1040 | + ok = sbjtretriever_iswaitingendpoint(bchanl->retriever, hevent->endpoint); | |
1041 | + if (ok == False) { | |
1042 | + return False; | |
1043 | + } | |
1044 | + cache = bchanl_subject_getcache(bchanl->nextsubject); | |
1045 | + err = sbjtretriever_recievehttpevent(bchanl->retriever, cache, hevent); | |
1046 | + | |
1047 | + switch (err) { | |
1048 | + case SBJTRETRIEVER_REQUEST_ALLRELOAD: | |
1049 | + /* should asynchronous layout? */ | |
1050 | + | |
1051 | + pdsp_msg(NULL); | |
1052 | + bchanl_hmistate_updateptrstyle(&bchanl->hmistate, PS_SELECT); | |
1053 | + | |
1054 | + subjectoptionwindow_setfiltertext(bchanl->subjectoptionwindow, NULL, 0); | |
1055 | + err = subjectoptionwindow_setordervalue(bchanl->subjectoptionwindow, SUBJECTOPTIONWINDOW_ORDERVALUE_ASCENDING); | |
1056 | + subjectoptionwindow_setorderbyvalue(bchanl->subjectoptionwindow, SUBJECTOPTIONWINDOW_ORDERBYVALUE_NUMBER); | |
1057 | + | |
1058 | + | |
1059 | + bchanl_subject_relayout(bchanl->nextsubject); | |
1060 | + | |
1061 | + bchanl_setcurrentsubject(bchanl, bchanl->nextsubject); | |
1062 | + bchanl_setnextsubject(bchanl, NULL); | |
1063 | + | |
1064 | + subjectwindow_getworkrect(bchanl->subjectwindow, &w_work); | |
1065 | + draw = bchanl_subject_getdraw(bchanl->currentsubject); | |
1066 | + sbjtdraw_setviewrect(draw, 0, 0, w_work.c.right, w_work.c.bottom); | |
1067 | + subjectwindow_setworkrect(bchanl->subjectwindow, 0, 0, w_work.c.right, w_work.c.bottom); | |
1068 | + | |
1069 | + layout = bchanl_subject_getlayout(bchanl->currentsubject); | |
1070 | + sbjtlayout_getdrawrect(layout, &l, &t, &r, &b); | |
1071 | + subjectwindow_setdrawrect(bchanl->subjectwindow, l, t, r, b); | |
1072 | + | |
1073 | + bchanl_subject_gettitle(bchanl->currentsubject, &title, &title_len); | |
1074 | + subjectwindow_settitle(bchanl->subjectwindow, title); | |
1075 | + | |
1076 | + break; | |
1077 | + case SBJTRETRIEVER_REQUEST_WAITNEXT: | |
1078 | + break; | |
1079 | + default: | |
1080 | + req_tmg(0, BCHANL_MESSAGE_RETRIEVER_ERROR); | |
1081 | + DP_ER("bbsmnretriever_recievehttpevent", err); | |
1082 | + break; | |
1083 | + } | |
1084 | + | |
1085 | + return True; | |
1086 | +} | |
1087 | + | |
1044 | 1088 | LOCAL VOID bchanl_http_task(W arg) |
1045 | 1089 | { |
1046 | 1090 | bchanl_t *bchanl; |
@@ -1076,6 +1120,7 @@ | ||
1076 | 1120 | { |
1077 | 1121 | W err; |
1078 | 1122 | http_connector_event hevent; |
1123 | + Bool rcv; | |
1079 | 1124 | |
1080 | 1125 | set_flg(bchanl->flgid, BCHANL_NETWORK_FLAG_WAITHTTPEVENT); |
1081 | 1126 |
@@ -1084,7 +1129,12 @@ | ||
1084 | 1129 | return; |
1085 | 1130 | } |
1086 | 1131 | |
1087 | - bchanl_bbsmenu_httpevent(&bchanl->bbsmenu, &hevent); | |
1132 | + rcv = bchanl_bbsmenu_httpevent(&bchanl->bbsmenu, &hevent); | |
1133 | + if (rcv != False) { | |
1134 | + return; | |
1135 | + } | |
1136 | + | |
1137 | + rcv = bchanl_subject_httpevent(bchanl, &hevent); | |
1088 | 1138 | } |
1089 | 1139 | |
1090 | 1140 | LOCAL W bchanl_prepare_network(bchanl_t *bchanl) |
@@ -1182,7 +1232,7 @@ | ||
1182 | 1232 | goto error_http_connector; |
1183 | 1233 | } |
1184 | 1234 | |
1185 | - retriever = sbjtretriever_new(); | |
1235 | + retriever = sbjtretriever_new(connector); | |
1186 | 1236 | if (retriever == NULL) { |
1187 | 1237 | DP_ER("sbjtretriever_new error", 0); |
1188 | 1238 | goto error_retriever; |
@@ -1253,6 +1303,7 @@ | ||
1253 | 1303 | bchanl->subjecthash = subjecthash; |
1254 | 1304 | |
1255 | 1305 | bchanl->currentsubject = NULL; |
1306 | + bchanl->nextsubject = NULL; | |
1256 | 1307 | bchanl->subjectdisplay.resnum = True; |
1257 | 1308 | bchanl->subjectdisplay.since = False; |
1258 | 1309 | bchanl->subjectdisplay.vigor = False; |
@@ -1,7 +1,7 @@ | ||
1 | 1 | /* |
2 | 2 | * subjectretriever.c |
3 | 3 | * |
4 | - * Copyright (c) 2009-2010 project bchan | |
4 | + * Copyright (c) 2009-2012 project bchan | |
5 | 5 | * |
6 | 6 | * This software is provided 'as-is', without any express or implied |
7 | 7 | * warranty. In no event will the authors be held liable for any damages |
@@ -34,8 +34,9 @@ | ||
34 | 34 | |
35 | 35 | #include "subjectretriever.h" |
36 | 36 | |
37 | -#include "retriever.h" | |
38 | 37 | #include "subjectcache.h" |
38 | +#include <http/http_typedef.h> | |
39 | +#include <http/http_connector.h> | |
39 | 40 | |
40 | 41 | #ifdef BCHANL_CONFIG_DEBUG |
41 | 42 | # define DP(arg) printf arg |
@@ -46,10 +47,12 @@ | ||
46 | 47 | #endif |
47 | 48 | |
48 | 49 | struct sbjtretriever_t_ { |
49 | - retriever_t *retr; | |
50 | + http_connector_t *connector; | |
51 | + ID endpoint; | |
52 | + HTTP_STATUSCODE status; | |
50 | 53 | }; |
51 | 54 | |
52 | -EXPORT sbjtretriever_t* sbjtretriever_new() | |
55 | +EXPORT sbjtretriever_t* sbjtretriever_new(http_connector_t *connector) | |
53 | 56 | { |
54 | 57 | sbjtretriever_t *retriever; |
55 | 58 |
@@ -57,11 +60,9 @@ | ||
57 | 60 | if (retriever == NULL) { |
58 | 61 | return NULL; |
59 | 62 | } |
60 | - retriever->retr = retriever_new(); | |
61 | - if (retriever->retr == NULL) { | |
62 | - free(retriever); | |
63 | - return NULL; | |
64 | - } | |
63 | + retriever->connector = connector; | |
64 | + retriever->endpoint = -1; | |
65 | + retriever->status = 0; | |
65 | 66 | |
66 | 67 | return retriever; |
67 | 68 | } |
@@ -68,40 +69,12 @@ | ||
68 | 69 | |
69 | 70 | EXPORT VOID sbjtretriever_delete(sbjtretriever_t *retriever) |
70 | 71 | { |
71 | - retriever_delete(retriever->retr); | |
72 | + if (retriever->endpoint > 0) { | |
73 | + http_connector_deleteendpoint(retriever->connector, retriever->endpoint); | |
74 | + } | |
72 | 75 | free(retriever); |
73 | 76 | } |
74 | 77 | |
75 | -#define SO_ERR_SEND_LEN(sockID, str, len) \ | |
76 | - err = so_send(sockID, (str), (len), 0); \ | |
77 | - if(err < 0){ \ | |
78 | - return err; \ | |
79 | - } | |
80 | - | |
81 | -#define SO_ERR_SEND(sockID, str) SO_ERR_SEND_LEN(sockID, (str), strlen((str))) | |
82 | - | |
83 | -LOCAL W sbjtretriver_sendheader(W sock, UB *host, UB *board) | |
84 | -{ | |
85 | - W err; | |
86 | - | |
87 | - SO_ERR_SEND(sock, "GET /"); | |
88 | - SO_ERR_SEND(sock, board); | |
89 | - SO_ERR_SEND(sock, "/subject.txt HTTP/1.1\r\n"); | |
90 | - SO_ERR_SEND(sock, "Accept-Encoding: gzip\r\n"); | |
91 | - SO_ERR_SEND(sock, "HOST: "); | |
92 | - SO_ERR_SEND(sock, host); | |
93 | - SO_ERR_SEND(sock, "\r\n"); | |
94 | - SO_ERR_SEND(sock, "Accept: */*\r\n"); | |
95 | - SO_ERR_SEND(sock, "Referer: http://"); | |
96 | - SO_ERR_SEND(sock, host); | |
97 | - SO_ERR_SEND(sock, "/"); | |
98 | - SO_ERR_SEND(sock, board); | |
99 | - SO_ERR_SEND(sock, "/"); | |
100 | - SO_ERR_SEND(sock, "/\r\n"); | |
101 | - SO_ERR_SEND(sock, "Accept-Language: ja\r\nUser-Agent: Monazilla/1.00 (bchanl/0.101)\r\nConnection: close\r\n\r\n"); | |
102 | - | |
103 | - return 0; | |
104 | -} | |
105 | 78 | /* from http://www.monazilla.org/index.php?e=197 */ |
106 | 79 | #if 0 |
107 | 80 | "GET /[板名]/subject.txt HTTP/1.1 |
@@ -119,60 +92,107 @@ | ||
119 | 92 | |
120 | 93 | EXPORT W sbjtretriever_sendrequest(sbjtretriever_t *retriever, sbjtcache_t *cache) |
121 | 94 | { |
122 | - W sock, err, ret = -1, len, status, host_len, board_len; | |
123 | - UB *bin, *host, *board; | |
95 | + W host_len; | |
96 | + UB *host; | |
124 | 97 | |
125 | - retriever_clearbuffer(retriever->retr); | |
98 | + if (retriever->endpoint > 0) { | |
99 | + DP(("sbjtretriever_sendrequest: requesting\n")); | |
100 | + return -1; | |
101 | + } | |
126 | 102 | |
127 | 103 | sbjtcache_gethost(cache, &host, &host_len); |
128 | - sbjtcache_getboard(cache, &board, &board_len); | |
129 | 104 | |
130 | - err = retriever_gethost(retriever->retr, host); | |
131 | - if (err < 0) { | |
132 | - return err; | |
105 | + retriever->endpoint = http_connector_createendpoint(retriever->connector, host, host_len, 80, HTTP_METHOD_GET); | |
106 | + if (retriever->endpoint < 0) { | |
107 | + DP_ER("http_connector_createendpoint error", retriever->endpoint); | |
108 | + return -1; | |
133 | 109 | } |
134 | - sock = retriver_connectsocket(retriever->retr); | |
135 | - if (sock < 0) { | |
136 | - return sock; | |
137 | - } | |
138 | 110 | |
139 | - err = sbjtretriver_sendheader(sock, host, board); | |
140 | - if (err < 0) { | |
141 | - so_close(sock); | |
142 | - return err; | |
143 | - } | |
111 | + return 0; | |
112 | +} | |
144 | 113 | |
145 | - err = retriever_recieve(retriever->retr, sock); | |
146 | - if (err < 0) { | |
147 | - so_close(sock); | |
148 | - return err; | |
114 | +EXPORT Bool sbjtretriever_iswaitingendpoint(sbjtretriever_t *retriever, ID endpoint) | |
115 | +{ | |
116 | + if (retriever->endpoint == endpoint) { | |
117 | + return True; | |
149 | 118 | } |
119 | + return False; | |
120 | +} | |
150 | 121 | |
151 | - err = retriever_parsehttpresponse(retriever->retr); | |
152 | - if (err < 0) { | |
153 | - so_close(sock); | |
154 | - return err; | |
155 | - } | |
156 | - retriever_dumpheader(retriever->retr); | |
122 | +LOCAL UB header1[] = | |
123 | +"Accept: */*\r\n" | |
124 | +"Referer: http://"; | |
125 | +LOCAL UB header2[] = | |
126 | +"/\r\n" | |
127 | +"Accept-Language: ja\r\n" | |
128 | +"User-Agent: Monazilla/1.00\r\n"; | |
157 | 129 | |
158 | - err = retriever_decompress(retriever->retr); | |
159 | - if (err < 0) { | |
160 | - so_close(sock); | |
161 | - return err; | |
162 | - } | |
130 | +EXPORT W sbjtretriever_recievehttpevent(sbjtretriever_t *retriever, sbjtcache_t *cache, http_connector_event *hevent) | |
131 | +{ | |
132 | + http_connector_t *connector = retriever->connector; | |
133 | + W host_len, board_len, path_len; | |
134 | + UB *host, *board, *path; | |
163 | 135 | |
164 | - status = retriever_parse_response_status(retriever->retr); | |
165 | - if (status == 200) { | |
166 | - bin = retriever_getbody(retriever->retr); | |
167 | - len = retriever_getbodylength(retriever->retr); | |
168 | - sbjtcache_cleardata(cache); | |
169 | - sbjtcache_appenddata(cache, bin, len); | |
170 | - ret = 0; | |
136 | + if (retriever->endpoint <= 0) { | |
137 | + return -1; | |
171 | 138 | } |
172 | 139 | |
173 | - so_close(sock); | |
140 | + if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_SEND) { | |
141 | + sbjtcache_getboard(cache, &host, &host_len); | |
142 | + sbjtcache_getboard(cache, &board, &board_len); | |
174 | 143 | |
175 | - retriever_clearbuffer(retriever->retr); | |
144 | + path_len = 1 + board_len + 12; | |
145 | + path = malloc(sizeof(UB)*(path_len+1)); | |
146 | + if (path == NULL) { | |
147 | + return -1; | |
148 | + } | |
149 | + path[0] = '/'; | |
150 | + strncpy(path+1, board, board_len); | |
151 | + strncpy(path+1+board_len, "/subject.txt", 12); | |
152 | + path[1+board_len+12] = '\0'; | |
153 | + http_connector_sendrequestline(connector, hevent->endpoint, path, path_len); | |
154 | + free(path); | |
176 | 155 | |
177 | - return ret; | |
156 | + http_connector_sendheader(connector, hevent->endpoint, header1, strlen(header1)); | |
157 | + http_connector_sendheader(connector, hevent->endpoint, host, host_len); | |
158 | + http_connector_sendheader(connector, hevent->endpoint, "/", 1); | |
159 | + http_connector_sendheader(connector, hevent->endpoint, board, board_len); | |
160 | + http_connector_sendheader(connector, hevent->endpoint, header2, strlen(header2)); | |
161 | + http_connector_sendheaderend(connector, hevent->endpoint); | |
162 | + http_connector_sendmessagebody(connector, hevent->endpoint, NULL, 0); | |
163 | + http_connector_sendmessagebodyend(connector, hevent->endpoint); | |
164 | + } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_STATUSLINE) { | |
165 | + DP(("HTTP_CONNECTOR_EVENTTYPE_RECEIVE_STATUSLINE\n")); | |
166 | + DP((" status = %d\n", hevent->data.receive_statusline.statuscode)); | |
167 | + retriever->status = hevent->data.receive_statusline.statuscode; | |
168 | + if (retriever->status == HTTP_STATUSCODE_200_OK) { | |
169 | + sbjtcache_cleardata(cache); | |
170 | + } | |
171 | + } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_HEADER) { | |
172 | +#ifdef BCHANL_CONFIG_DEBUG | |
173 | + { | |
174 | + W i = 0; | |
175 | + for (i = 0; i < hevent->data.receive_header.len; i++) { | |
176 | + printf("%c", hevent->data.receive_header.bin[i]); | |
177 | + } | |
178 | + } | |
179 | +#endif | |
180 | + } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_HEADER_END) { | |
181 | + } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_MESSAGEBODY) { | |
182 | + if (retriever->status == HTTP_STATUSCODE_200_OK) { | |
183 | + sbjtcache_appenddata(cache, hevent->data.receive_messagebody.bin, hevent->data.receive_messagebody.len); | |
184 | + } | |
185 | + } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_MESSAGEBODY_END) { | |
186 | + http_connector_deleteendpoint(connector, hevent->endpoint); | |
187 | + retriever->endpoint = -1; | |
188 | + return SBJTRETRIEVER_REQUEST_ALLRELOAD; | |
189 | + } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_ERROR) { | |
190 | + http_connector_deleteendpoint(connector, hevent->endpoint); | |
191 | + retriever->endpoint = -1; | |
192 | + } else { | |
193 | + /* error */ | |
194 | + return -1; | |
195 | + } | |
196 | + | |
197 | + return SBJTRETRIEVER_REQUEST_WAITNEXT; | |
178 | 198 | } |
@@ -1,7 +1,7 @@ | ||
1 | 1 | /* |
2 | 2 | * subjectretriever.h |
3 | 3 | * |
4 | - * Copyright (c) 2009 project bchan | |
4 | + * Copyright (c) 2009-2012 project bchan | |
5 | 5 | * |
6 | 6 | * This software is provided 'as-is', without any express or implied |
7 | 7 | * warranty. In no event will the authors be held liable for any damages |
@@ -26,6 +26,7 @@ | ||
26 | 26 | |
27 | 27 | #include <basic.h> |
28 | 28 | #include "subjectcache.h" |
29 | +#include <http/http_connector.h> | |
29 | 30 | |
30 | 31 | #ifndef __SUBJECTRETREIEVER_H__ |
31 | 32 | #define __SUBJECTRETREIEVER_H__ |
@@ -32,8 +33,14 @@ | ||
32 | 33 | |
33 | 34 | typedef struct sbjtretriever_t_ sbjtretriever_t; |
34 | 35 | |
35 | -IMPORT sbjtretriever_t* sbjtretriever_new(); | |
36 | +IMPORT sbjtretriever_t* sbjtretriever_new(http_connector_t *connector); | |
36 | 37 | IMPORT VOID sbjtretriever_delete(sbjtretriever_t *retriever); |
37 | 38 | IMPORT W sbjtretriever_sendrequest(sbjtretriever_t *retriever, sbjtcache_t *cache); |
39 | +IMPORT Bool sbjtretriever_iswaitingendpoint(sbjtretriever_t *retriever, ID endpoint); | |
40 | +IMPORT W sbjtretriever_recievehttpevent(sbjtretriever_t *retriever, sbjtcache_t *cache, http_connector_event *hevent); | |
38 | 41 | |
42 | +#define SBJTRETRIEVER_REQUEST_NOT_MODIFIED 0 | |
43 | +#define SBJTRETRIEVER_REQUEST_ALLRELOAD 1 | |
44 | +#define SBJTRETRIEVER_REQUEST_WAITNEXT 2 | |
45 | + | |
39 | 46 | #endif |