4 * Copyright (c) 2009-2015 project bchan
6 * This software is provided 'as-is', without any express or implied
7 * warranty. In no event will the authors be held liable for any damages
8 * arising from the use of this software.
10 * Permission is granted to anyone to use this software for any purpose,
11 * including commercial applications, and to alter it and redistribute it
12 * freely, subject to the following restrictions:
14 * 1. The origin of this software must not be misrepresented; you must not
15 * claim that you wrote the original software. If you use this software
16 * in a product, an acknowledgment in the product documentation would be
17 * appreciated but is not required.
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source
32 #include <btron/btron.h>
33 #include <btron/bsocket.h>
35 #include "subjectretriever.h"
37 #include "subjectcache.h"
38 #include <http/http_typedef.h>
39 #include <http/http_connector.h>
41 #ifdef BCHANL_CONFIG_DEBUG
42 # define DP(arg) printf arg
43 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
46 # define DP_ER(msg, err) /**/
49 struct sbjtretriever_t_ {
50 http_connector_t *connector;
52 HTTP_STATUSCODE status;
57 EXPORT sbjtretriever_t* sbjtretriever_new(http_connector_t *connector, UB *useragent, W useragent_len)
59 sbjtretriever_t *retriever;
61 retriever = (sbjtretriever_t*)malloc(sizeof(sbjtretriever_t));
62 if (retriever == NULL) {
65 retriever->connector = connector;
66 retriever->endpoint = -1;
67 retriever->status = 0;
68 retriever->useragent = useragent;
69 retriever->useragent_len = useragent_len;
74 EXPORT VOID sbjtretriever_delete(sbjtretriever_t *retriever)
76 if (retriever->endpoint > 0) {
77 http_connector_deleteendpoint(retriever->connector, retriever->endpoint);
82 /* from http://www.monazilla.org/index.php?e=197 */
84 "GET /[ÈÄ̾]/subject.txt HTTP/1.1
88 Referer: http://[¥µ¡¼¥Ð¡¼]/[ÈÄ̾]/
90 If-Modified-Since: Tue, 23 Dec 2008 14:08:21 GMT
91 If-None-Match: \"3462-1b80-45eb74ece1f40\"
92 User-Agent: Monazilla/1.00 (monaweb/1.00)
97 EXPORT W sbjtretriever_sendrequest(sbjtretriever_t *retriever, sbjtcache_t *cache)
103 if (retriever->endpoint > 0) {
104 DP(("sbjtretriever_sendrequest: requesting\n"));
108 sbjtcache_gethost(cache, &host, &host_len);
109 sbjtcache_getport(cache, &port);
111 retriever->endpoint = http_connector_createendpoint(retriever->connector, host, host_len, port, HTTP_METHOD_GET);
112 if (retriever->endpoint < 0) {
113 DP_ER("http_connector_createendpoint error", retriever->endpoint);
120 EXPORT Bool sbjtretriever_iswaitingendpoint(sbjtretriever_t *retriever, ID endpoint)
122 if (retriever->endpoint == endpoint) {
133 "Accept-Language: ja\r\n"
135 LOCAL UB header_default_ua[] = "Monazilla/1.00";
136 LOCAL UB header_crlf[] = "\r\n";
138 EXPORT W sbjtretriever_recievehttpevent(sbjtretriever_t *retriever, sbjtcache_t *cache, http_connector_event *hevent)
140 http_connector_t *connector = retriever->connector;
141 W host_len, board_len, path_len;
142 UB *host, *board, *path;
144 if (retriever->endpoint <= 0) {
148 if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_SEND) {
149 sbjtcache_getboard(cache, &host, &host_len);
150 sbjtcache_getboard(cache, &board, &board_len);
152 path_len = 1 + board_len + 12;
153 path = malloc(sizeof(UB)*(path_len+1));
158 strncpy(path+1, board, board_len);
159 strncpy(path+1+board_len, "/subject.txt", 12);
160 path[1+board_len+12] = '\0';
161 http_connector_sendrequestline(connector, hevent->endpoint, path, path_len);
164 http_connector_sendheader(connector, hevent->endpoint, header1, strlen(header1));
165 http_connector_sendheader(connector, hevent->endpoint, host, host_len);
166 http_connector_sendheader(connector, hevent->endpoint, "/", 1);
167 http_connector_sendheader(connector, hevent->endpoint, board, board_len);
168 http_connector_sendheader(connector, hevent->endpoint, header2, strlen(header2));
169 if (retriever->useragent != NULL) {
170 http_connector_sendheader(connector, hevent->endpoint, retriever->useragent, retriever->useragent_len);
172 http_connector_sendheader(connector, hevent->endpoint, header_default_ua, strlen(header_default_ua));
174 http_connector_sendheader(connector, hevent->endpoint, header_crlf, strlen(header_crlf));
175 http_connector_sendheaderend(connector, hevent->endpoint);
176 http_connector_sendmessagebody(connector, hevent->endpoint, NULL, 0);
177 http_connector_sendmessagebodyend(connector, hevent->endpoint);
178 } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_STATUSLINE) {
179 DP(("HTTP_CONNECTOR_EVENTTYPE_RECEIVE_STATUSLINE\n"));
180 DP((" status = %d\n", hevent->data.receive_statusline.statuscode));
181 retriever->status = hevent->data.receive_statusline.statuscode;
182 if (retriever->status == HTTP_STATUSCODE_200_OK) {
183 sbjtcache_cleardata(cache);
185 } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_HEADER) {
186 #ifdef BCHANL_CONFIG_DEBUG
189 for (i = 0; i < hevent->data.receive_header.len; i++) {
190 printf("%c", hevent->data.receive_header.bin[i]);
194 } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_HEADER_END) {
195 } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_MESSAGEBODY) {
196 if (retriever->status == HTTP_STATUSCODE_200_OK) {
197 sbjtcache_appenddata(cache, hevent->data.receive_messagebody.bin, hevent->data.receive_messagebody.len);
199 } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_RECEIVE_MESSAGEBODY_END) {
200 http_connector_deleteendpoint(connector, hevent->endpoint);
201 retriever->endpoint = -1;
202 return SBJTRETRIEVER_REQUEST_ALLRELOAD;
203 } else if (hevent->type == HTTP_CONNECTOR_EVENTTYPE_ERROR) {
204 http_connector_deleteendpoint(connector, hevent->endpoint);
205 retriever->endpoint = -1;
206 return SBJTRETRIEVER_REQUEST_ERROR;
212 return SBJTRETRIEVER_REQUEST_WAITNEXT;