why isn't it working on this host?

This commit is contained in:
psyc://psyced.org/~lynX 2009-04-20 08:18:13 +02:00
parent af78406976
commit db4d7f0af7
3 changed files with 77 additions and 62 deletions

View File

@ -23,6 +23,7 @@ protected int block() { destruct(ME); return 0; }
protected connect_failure(mc, text) { protected connect_failure(mc, text) {
is_connecting = 0; is_connecting = 0;
P1(("connect failure %O in %O, %O.\n", mc, ME, text))
monitor_report("_failure_network_connect"+ mc, monitor_report("_failure_network_connect"+ mc,
object_name(ME) +" · "+ text); object_name(ME) +" · "+ text);
} }
@ -42,7 +43,7 @@ protected int logon(int failure) {
} }
is_connecting = 0; is_connecting = 0;
if (failure == -1 || !interactive(ME)) { if (failure == -1 || !interactive(ME)) {
PT(("Warning: Failed connect attempt in %O\n", ME)) P3(("Warning: Failed connect attempt in %O\n", ME))
#if __EFUN_DEFINED__(errno) #if __EFUN_DEFINED__(errno)
connect_failure("_attempt", sprintf("connect failed: errno %s", connect_failure("_attempt", sprintf("connect failed: errno %s",
errno())); errno()));

View File

@ -4,6 +4,11 @@
// but we could fetch any page or data with it, really // but we could fetch any page or data with it, really
// tobij even allowed the object to have the URL as its object name. fancy! ;) // tobij even allowed the object to have the URL as its object name. fancy! ;)
#ifdef Dfetch
# undef DEBUG
# define DEBUG Dfetch
#endif
#include <ht/http.h> #include <ht/http.h>
#include <net.h> #include <net.h>
#include <uniform.h> #include <uniform.h>
@ -66,7 +71,7 @@ void connect() {
thehost = lower_case(thehost); thehost = lower_case(thehost);
ssl = t == "s"; ssl = t == "s";
} }
PT(("URL, THEHOST: %O, %O\n", url, thehost)) P4(("URL, THEHOST: %O, %O\n", url, thehost))
unless (port) unless (port)
unless (sscanf(thehost, "%s:%d", thehost, port) == 2) unless (sscanf(thehost, "%s:%d", thehost, port) == 2)
port = ssl? HTTPS_SERVICE: HTTP_SERVICE; port = ssl? HTTPS_SERVICE: HTTP_SERVICE;
@ -74,14 +79,14 @@ void connect() {
::connect(thehost, port); ::connect(thehost, port);
} }
varargs int real_logon(int arg) { varargs int real_logon(int failure) {
string scheme; string scheme;
headers = ([ ]); headers = ([ ]);
http_status = 500; http_status = 500;
http_message = "(failure)"; // used by debug only http_message = "(failure)"; // used by debug only
unless(::logon(arg)) return -1; unless(::logon(failure)) return -1;
unless (url) return -3; unless (url) return -3;
unless (resource) sscanf(url, "%s://%s/%s", scheme, host, resource); unless (resource) sscanf(url, "%s://%s/%s", scheme, host, resource);
@ -93,7 +98,7 @@ varargs int real_logon(int arg) {
// emit("If-None-Match: " + etag + "\r\n"); // emit("If-None-Match: " + etag + "\r\n");
// we won't need connection: close w/ http/1.0 // we won't need connection: close w/ http/1.0
//emit("Connection: close\r\n\r\n"); //emit("Connection: close\r\n\r\n");
PT(("%O using %O\n", ME, buffer)) P4(("%O using %O\n", ME, buffer))
emit("GET /"+ resource +" HTTP/1.0\r\n" emit("GET /"+ resource +" HTTP/1.0\r\n"
"Host: "+ host +"\r\n" "Host: "+ host +"\r\n"
+ buffer + + buffer +
@ -104,7 +109,7 @@ varargs int real_logon(int arg) {
return 0; // duh. return 0; // duh.
} }
varargs int logon(int arg, int sub) { varargs int logon(int failure, int sub) {
// net/connect disables telnet for all robots and circuits // net/connect disables telnet for all robots and circuits
#if 0 //__EFUN_DEFINED__(enable_telnet) #if 0 //__EFUN_DEFINED__(enable_telnet)
// when fetching the spiegel rss feed, telnet_neg() occasionally // when fetching the spiegel rss feed, telnet_neg() occasionally
@ -113,9 +118,9 @@ varargs int logon(int arg, int sub) {
enable_telnet(0); enable_telnet(0);
#endif #endif
// when called from xmlrpc.c we can't do TLS anyway // when called from xmlrpc.c we can't do TLS anyway
if (sub) return ::logon(arg); if (sub) return ::logon(failure);
if (ssl) tls_init_connection(ME, #'real_logon); if (ssl) tls_init_connection(ME, #'real_logon);
else real_logon(arg); else real_logon(failure);
return 0; // duh. return 0; // duh.
} }
@ -125,8 +130,9 @@ int parse_status(string all) {
sscanf(all, "%s%t%s", prot, state); sscanf(all, "%s%t%s", prot, state);
sscanf(state, "%d%t%s", http_status, http_message); sscanf(state, "%d%t%s", http_status, http_message);
P3(("%O got %O %O from %O\n", ME, http_status, http_message, host));
if (http_status != R_OK) { if (http_status != R_OK) {
P1(("%O got %O %O from %O\n", ME,
http_status, http_message, host));
monitor_report("_failure_unsupported_code_HTTP", monitor_report("_failure_unsupported_code_HTTP",
S("http/fetch'ing %O returned %O %O", url || ME, S("http/fetch'ing %O returned %O %O", url || ME,
http_status, http_message)); http_status, http_message));
@ -137,9 +143,9 @@ int parse_status(string all) {
int parse_header(string all) { int parse_header(string all) {
string key, val; string key, val;
D2(D("htroom::parse is: " + all + "\n");)
// TODO: parse status code // TODO: parse status code
if (all != "") { if (all != "") {
P2(("http/fetch::parse_header %O\n", all))
if (sscanf(all, "%s:%1.0t%s", key, val) == 2) { if (sscanf(all, "%s:%1.0t%s", key, val) == 2) {
headers[lower_case(key)] = val; headers[lower_case(key)] = val;
// P2(("ht head: %O = %O\n", key, val)) // P2(("ht head: %O = %O\n", key, val))
@ -148,6 +154,7 @@ int parse_header(string all) {
return 1; return 1;
} else { } else {
// das wollen wir nur bei status 200 // das wollen wir nur bei status 200
P2(("%O now waiting for http body\n", ME))
next_input_to(#'buffer_content); next_input_to(#'buffer_content);
return 1; return 1;
} }
@ -155,70 +162,72 @@ int parse_header(string all) {
} }
int buffer_content(string all) { int buffer_content(string all) {
P2(("%O body %O\n", ME, all))
buffer += all + "\n"; buffer += all + "\n";
next_input_to(#'buffer_content); next_input_to(#'buffer_content);
return 1; return 1;
} }
disconnected(remainder) { disconnected(remainder) {
headers["_fetchtime"] = isotime(ctime(time()), 1); P2(("%O got disconnected.. %O\n", ME, remainder))
if (headers["last-modified"]) headers["_fetchtime"] = isotime(ctime(time()), 1);
if (headers["last-modified"])
modificationtime = headers["last-modified"]; modificationtime = headers["last-modified"];
if (headers["etag"]) if (headers["etag"])
etag = headers["etag"]; // heise does not work with etag etag = headers["etag"]; // heise does not work with etag
fetched = buffer; fetched = buffer;
if (remainder) fetched += remainder; if (remainder) fetched += remainder;
fheaders = headers; fheaders = headers;
buffer = headers = 0; buffer = headers = 0;
switch (http_status) { switch (http_status) {
case R_OK: case R_OK:
mixed *waiter; mixed *waiter;
while (qSize(ME)) { while (qSize(ME)) {
waiter = shift(ME); waiter = shift(ME);
funcall(waiter[0], fetched, waiter[1] ? fheaders : copy(fheaders)); P2(("%O calls back.. body is %O\n", ME, fetched))
funcall(waiter[0], fetched, waiter[1] ? fheaders : copy(fheaders));
}
break;
default:
// doesn't seem to get here when HTTP returns 301 or 302. strange.
// fall thru
case R_NOTMODIFIED:
qDel(ME);
qInit(ME, 150, 5);
} }
break; fetching = 0;
default: return 1; // presume this disc was expected
// doesn't seem to get here when HTTP returns 301 or 302. strange.
// fall thru
case R_NOTMODIFIED:
qDel(ME);
qInit(ME, 150, 5);
}
fetching = 0;
return 1; // presume this disc was expected
} }
varargs string content(closure cb, int force, int willbehave) { varargs string content(closure cb, int force, int willbehave) {
if (cb) { if (cb) {
if (fetched) { if (fetched) {
if (force) { if (force) {
funcall(cb, fetched, willbehave ? fheaders : copy(fheaders)); funcall(cb, fetched, willbehave ? fheaders : copy(fheaders));
}
} else {
enqueue(ME, ({ cb, willbehave }));
} }
} else {
enqueue(ME, ({ cb, willbehave }));
} }
} return fetched;
return fetched;
} }
varargs mapping headers(int willbehave) { varargs mapping headers(int willbehave) {
return willbehave ? fheaders : copy(fheaders); return willbehave ? fheaders : copy(fheaders);
} }
string qHeader(mixed key) { string qHeader(mixed key) {
if (mappingp(fheaders)) return fheaders[key]; if (mappingp(fheaders)) return fheaders[key];
return 0; return 0;
} }
varargs void refetch(closure cb, int willbehave) { varargs void refetch(closure cb, int willbehave) {
enqueue(ME, ({ cb, willbehave })); enqueue(ME, ({ cb, willbehave }));
unless (fetching) connect(); unless (fetching) connect();
} }
protected create() { protected create() {
qCreate(); qCreate();
qInit(ME, 150, 5); qInit(ME, 150, 5);
} }

View File

@ -9,16 +9,17 @@ persistent int lastid;
volatile object feed; volatile object feed;
parse(string body) { parse(string body, mapping headers) {
mixed wurst; mixed wurst;
string nick; string nick;
object o; object o;
mapping d, p; mapping d, p;
int i; int i;
//body = read_file("/net/twitter/many.json");
if (!body || body == "") { if (!body || body == "") {
P1(("%O failed to get its timeline.\n", ME)) P1(("%O failed to get its timeline from %O.\n", ME,
previous_object()))
PT(("Got headers: %O", headers))
return; return;
} }
//#if DEBUG > 0 //#if DEBUG > 0
@ -60,16 +61,20 @@ parse(string body) {
// should i send text as _action? // should i send text as _action?
"_nick": nick, "_nick": nick,
// _count seems to be the better word for this // _count seems to be the better word for this
"_amount_updates": p["statuses_count"],
"_amount_followers": p["followers_count"], "_amount_followers": p["followers_count"],
"_color": "#"+ p["profile_text_color"], "_amount_sources": p["friends_count"],
"_description": p["description"], "_color": "#"+ p["profile_sidebar_fill_color"],
"_uniform_photo": p["profile_image_url"], "_description": p["description"] || "",
"_page": p["url"], "_page": p["url"] || "",
"_name": p["name"], "_name": p["name"] || "",
// "_contact_twitter": p["id"], // "_contact_twitter": p["id"],
"_description_agent_HTML": d["source"], "_description_agent_HTML": d["source"],
"_reference_reply": d["in_reply_to_screen_name"], "_reference_reply": d["in_reply_to_screen_name"],
// "_twit": d["id"], // "_twit": d["id"],
"_uniform_photo": p["profile_image_url"] || "",
"_uniform_photo_background":
p["profile_background_image_url"] || ""
]), "/"); // send as root ]), "/"); // send as root
// der spiegel u.a. twittern übrigens in latin-1 // der spiegel u.a. twittern übrigens in latin-1
@ -81,8 +86,8 @@ parse(string body) {
fetch() { fetch() {
feed -> content( #'parse, 0, 1 ); feed -> content( #'parse, 0, 1 );
feed -> fetch("http://twitter.com/statuses/friends_timeline.json" feed -> fetch("http://twitter.com/statuses/friends_timeline.json"
"?since_id="+ lastid +"&count=123"); "?count="+( lastid? ("44&since_id="+ lastid) : "44"));
call_out( #'fetch, 9 * 60 ); call_out( #'fetch, 6 * 59 ); // odd is better
} }
create() { create() {
@ -91,14 +96,14 @@ create() {
if (o) config = o->qConfig(); if (o) config = o->qConfig();
if (!config) { if (!config) {
P1(("No configuration for twitter gateway found.\n"); P1(("\nNo configuration for twitter gateway found.\n"))
destruct(ME); //destruct(ME);
return; return;
} }
restore_object(DATA_PATH "twitter"); restore_object(DATA_PATH "twitter");
// we could even choose to inherit this instead... // we could even choose to inherit this instead...
feed = clone_object(HTTP_PATH "fetch"); feed = clone_object(NET_PATH "http/fetch");
//feed -> sAgent(SERVER_VERSION " builtin Twitter to PSYC gateway"); //feed -> sAgent(SERVER_VERSION " builtin Twitter to PSYC gateway");
feed -> sAuth(config["nickname"], config["password"]); feed -> sAuth(config["nickname"], config["password"]);
call_out( #'fetch, 14 ); call_out( #'fetch, 14 );