check.cc (2764B)
1 #include "backend" 2 3 void Backend::check() { 4 debugmsg("About to check back end " << description() << ": " << 5 backendcheck().description() << '\n'); 6 7 ostringstream o; 8 Backend tester; 9 Httpbuffer httpbuffer; 10 11 switch (backendcheck().checktype()) { 12 case BackendCheck::c_connect: 13 // Assume we test at the true back end address/port. 14 // Override if necessary. 15 tester = *this; 16 if (backendcheck().server() != "") 17 tester.server(backendcheck().server()); 18 if (backendcheck().port() != 0) 19 tester.port(backendcheck().port()); 20 21 // Attempt CONNECT CHECK times (see /etc/Makefile.class) 22 for (int i = 0; i < CONNCHECKS; i++) { 23 tester.connect(); 24 if (tester.live()) 25 break; 26 } 27 live(tester.live()); 28 debugmsg("Check of back end " << description() << 29 " by connecting to " << tester.description() << 30 ", result: " << livestr() << '\n'); 31 break; 32 33 case BackendCheck::c_get: 34 // HTTP GET to stated server, port, uri 35 tester.server(backendcheck().server()); 36 tester.port(backendcheck().port()); 37 tester.connect(); 38 if (! tester.live()) { 39 warnmsg("HTTP GET checker: host " << backendcheck().server() 40 << ", port " << backendcheck().port() << 41 "not responding\n"); 42 live(false); 43 } else { 44 o << "GET " << backendcheck().uri() << " HTTP/1.0\r\n" 45 "Host: " << backendcheck().server() << "\r\n" 46 "Connection: close\r\n" 47 "\r\n"; 48 httpbuffer.setstring (o.str()); 49 httpbuffer.netwrite(tester.sock(), config.backend_write_timeout()); 50 httpbuffer.reset(); 51 while (!httpbuffer.headersreceived()) 52 httpbuffer.netread(tester.sock(), 53 config.backend_read_timeout()); 54 msg("HTTP GET checker got answer: '" << 55 httpbuffer.firstline() << '\n'); 56 if (httpbuffer.stringat(9, 3) == "200") 57 live(true); 58 else 59 debugmsg("Back end assumed dead.\n"); 60 } 61 break; 62 63 case BackendCheck::c_external: 64 // External program to be called, with arguments: 65 // IP:PORT availability current-connections 66 o << backendcheck().program() << ' ' << description() << ' ' 67 << availablestr() << ' ' << connections(); 68 FILE *f; 69 int result; 70 if (! (f = popen(o.str().c_str(), "r")) ) { 71 live(false); 72 warnmsg("Failed to start external checker '" << o.str() << 73 ": " << strerror(errno) << '\n'); 74 } else { 75 if (fscanf(f, "%d", &result) < 1) { 76 live(false); 77 warnmsg("External checker '" << o.str() << 78 "' did not reply with a number\n"); 79 } else { 80 msg("External checker '" << o.str() << "' replied: " << 81 result << '\n'); 82 live(result == 0); 83 } 84 if (pclose(f)) { 85 warnmsg("External checker '" << o.str() << 86 "' terminated with error\n"); 87 live(false); 88 } 89 } 90 break; 91 92 default: 93 throw Error("Internal fry in Backend::check()"); 94 } 95 }