#include "cygwin.h" #include "donkey.h" #include "cHTTP.h" #include "sSocket.h" #include "sGui.h" #include "misc.h" #include "protocol.h" #include "sFile.h" #include "sPacket.h" #include "kademlia.h" #include "sSource.h" #include "db_macro.h" char head200[] ="HTTP/1.1 200 OK\r\n" "Status: 200\r\n" "Pragma: no-cache,no-cache\r\n"; char head401[]="HTTP/1.1 401 Aut horization Required\r\n" "Date: Mon, 17 Feb 2003 21:53:45 GMT\r\n" "Server: Apache/1.3.22 (Unix) PHP/4.1.0\r\n" "WWW-Authenticate: Basic realm=\"cDonkey\"\r\n" "Content-Type: text/html; charset=iso-8859-1\r\n\r\n"; char CON_CLOSE[]="Connection: close\r\n"; const char url2txt( const char* what ) {{{ register char digit; digit = (what[0] >= 'A' ? ((what[0] & 0x4F) - 'A')+10 : (what[0] - '0')); digit *= 16; digit += (what[1] >='A' ? ((what[1] & 0x4F) - 'A')+10 : (what[1] - '0')); return digit; }}} const char*url_decode(char *hexstr) {{{ if ( hexstr == NULL || strlen( hexstr ) == 0 ) return ""; unsigned int x,y; for ( x = 0, y = 0; hexstr[y]; x++, y++ ) { if( (hexstr[x] = hexstr[y]) == '+' ) { hexstr[x] = ' '; continue; } if ( hexstr[x] == '%' ) { hexstr[x] = url2txt(&hexstr[y+1]); y+=2; } } hexstr[x] = '\0'; return hexstr; }}} void split_url(char *url) {{{ char *query = strchr(url, '?'); if (query == NULL) return; query++; while(0 != *query) { char *next = strchr(query, '&'); if (next != NULL) { *next = 0; next++; } char *val = strchr(query, '='); if (val != NULL) { *val = 0; val++; printf("%s => %s\n", url_decode(query), url_decode(val)); } if (next == NULL) break; query = next; } }}} cHTTP::cHTTP (class cSocket *FD_new, struct in_addr, uint16_t) : sSocket(FD_new) {{{ url = NULL; state = 0; Type = tCommand; auth = false; if (mask != 0) doWork(mask); }}} cHTTP::~cHTTP (void) {{{ if (url != NULL) Free2 (url ); }}} int cHTTP::Parse(unsigned char *input) {{{ char *pos = reinterpret_cast(input); char *mark = NULL; unsigned char buffer[1024]; KeyMap::iterator i = param.find(std::string("fkt")); bool FILTER = false; if (i != param.end()) { FILTER = (i->second == std::string("filter")); } while (NULL != (mark = strchr(pos, '~'))) { mark[0] = 0; Write(reinterpret_cast(pos), strlen(pos)); pos = mark + 1; if (NULL == (mark = strchr(pos, '~'))) break; mark[0] = 0; if (0 == strcmp(pos, "PORT_CLIENT" )) {{{ Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "%u", pref.ports.client)); }}} else if (0 == strcmp(pos, "PORT_GUI" )) {{{ Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "%u", pref.ports.gui )); }}} else if (0 == strcmp(pos, "PORT_SERVER" )) {{{ Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "%u", pref.ports.server )); }}} else if (0 == strcmp(pos, "PORT_TELNET" )) {{{ Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "%u", pref.ports.clc )); }}} else if (0 == strcmp(pos, "PORT_WEB" )) {{{ Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "%u", pref.ports.web )); }}} else if (0 == strcmp(pos, "PORT_UDP_EMULE" )) {{{ Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "%u", pref.ports.emule )); }}} else if (0 == strcmp(pos, "PORT_UDP_OVERNET")) {{{ Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "%u", pref.ports.kademlia)); }}} else if (0 == strcmp(pos, "LISTE_SERVER" )) {{{ const struct eServers *s =nextServers (true); unsigned cnt = 0 ; while (s != NULL) { // we have reserved the maximum possible size cnt++; Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "" "%s  " "%u  " "%u  " "%lu  " "%u  " "%u  " "%s  " "%s  " "\n", cnt, inet_ntoa(s->ip), s->port, s->prio, (currentTime - s->last_action), s->user, s->file, s->name, s->desc )); s = nextServers (false); } }}} else if (0 == strcmp(pos, "LISTE_SOURCE" )) {{{ int cnt = 0; SOURCE_LIST { cnt ++; Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "" "%c " "%s  " "%li " "%i " "%s  " "%s  " "%s  " "",cnt, ((akt->this_port == pref.ports.client)?'<':'>'), inet_ntoa(akt->peer_ip), akt->ratio, akt->dl_slot, akt->name, hash_bin2hex(akt->dl_hash), hash_bin2hex(akt->ul_hash) )); } }}} if (0 == strcmp(pos, "LISTE_SOURCE_RAW")) {{{ int cnt = 0; int err = 0; struct eSources tmp; bzero (&tmp, sizeof(tmp)); time_t zeit = 0; INIT_DBT(key, &zeit, sizeof(zeit)); INIT_DBT(val, &tmp , sizeof(tmp )); DBC *c3 = NULL; DB_cursor2 (src_time, c3); while (0 == (err = c3->c_get (c3, &key, &val, DB_NEXT))) { // search next source for connect ASSERT(sizeof(tmp ) == val.size); ASSERT(sizeof(zeit) == key.size); cnt ++; char zeit_tmp[100]; strftime(zeit_tmp, 100, "%m-%d %H:%M.%S", gmtime(&tmp.next_time)); Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "" "%15s" "%i" "%32s" "%s" "\n",cnt, inet_ntoa(tmp.ip), tmp.aktive, hash_bin2hex(tmp.hash_dl), zeit_tmp )); // if (tmp.next_time - 3600*24*3 > currentTime) Delete_src(tmp.ip); } if (err != DB_NOTFOUND) DB_error(); DB_c_close(c3); }}} if (0 == strcmp(pos, "LIST_FILES")) {{{ size_t filter_size = 0; if (FILTER) { i = param.find(std::string("file_size")); if (i != param.end()) { filter_size = atoi(i->second.c_str()); } } int cnt = 0; FILE_LIST { cnt++; if (filter_size != 0 && akt->size != filter_size) continue; Write(buffer, snprintf(reinterpret_cast(buffer), 1024, "" "%s" "%s" "%u" "%u" "", cnt, hash_bin2hex(akt->hash),akt->Name(), akt->size, akt->transfered )); } }}} pos = mark + 1; } Write(reinterpret_cast(pos), strlen(pos)); return 1; }}} struct sURL2File { const char *url; const char *file; }; const struct sURL2File URLs[] = { {"/" , "http.dat/index.html"}, {"/files.html" , "http.dat/files.html"}, {"/server.html" , "http.dat/server.html"}, {"/sources.html" , "http.dat/sources.html"}, {"/sources_raw.html" , "http.dat/sources_raw.html"}, {"/global.css" , "http.dat/global.css"}, {"/main.html" , "http.dat/main.html"}, {"/options.html" , "http.dat/options.html"}, {NULL,NULL} }; int cHTTP::doRead_high (void) {{{ // printf("cHTTP::doRead_high\n"); size_t len = 0; if (state == 3) {{{ // Close Close(); return 0; }}} while (read_len > 0) {{{ for (len = 0; len < read_len; len++) { if (read_buf[len] == '\n' || read_buf[len] == '\r') break; } if (len == read_len) return 0; if (len> 4095) {{{ // too long line Read(read_buf, len); return 0; }}} char buffer[4986]; Read(reinterpret_cast(buffer), len); if (read_buf[0] == '\r') Read(read_buf, 1); if (read_buf[0] == '\n') Read(read_buf, 1); buffer[len]=0; if (strncmp(buffer, "GET ", 4) == 0 && state == 0) {{{ // catch the URL char *HTTP = strstr(buffer, " HTTP"); if (HTTP != NULL) *HTTP = 0; char *URL = buffer + 4; char *query = strchr(URL, '?'); if (query == NULL) { url = STRDUP (URL); state = 1; continue; } query[0] = 0; url = STRDUP (URL); state = 1; query++; while(0 != *query) { char *next = strchr(query, '&'); if (next != NULL) { *next = 0; next++; } char *val = strchr(query, '='); if (val != NULL) { *val = 0; val++; param[std::string(url_decode(query))] = std::string(url_decode(val)); printf("%s => %s\n", url_decode(query), url_decode(val)); } if (next == NULL) break; query = next; } continue; }}} if (buffer[0] == 0 && state == 1) {{{ state = 2; continue; }}} if (buffer[0] == 0 && state == 2) break; char *p = strstr(buffer, ": "); if (p == NULL) continue; p[0] = 0; p += 2; if (0 == strcmp(buffer, "Authorization")) {{{ // User check char check1[256]; char check2[256]; len = 256; snprintf(check1, 256, "%s:%s", ctrl_user, ctrl_pass); encode64(check1, strlen(check1), check2, 256, &len); check2[len] = 0; snprintf(check1, 256, "Basic %s", check2); auth = (0 == strcmp(check1, p)); }}} header[std::string(buffer)] = std::string(p); continue; }}} state = 3; size_t in_size = 0; unsigned char *INPUT = NULL; int idx = 0; if (param["fkt"] == "Shutdown") { running = false; } if (!auth) {{{ // Auth failed Write(reinterpret_cast(head401),strlen(head401)); INPUT = file("http.dat/401.html", &in_size); goto ende_1; }}} Write(reinterpret_cast(head200), strlen(head200)); Write(reinterpret_cast("Content-Type: text/html; charset=iso-8859-1\r\n"), strlen("Content-Type: text/html; charset=iso-8859-1\r\n")); if (url == NULL) goto error_1; for(idx = 0; URLs[idx].url != NULL; idx++) if (0 == strcmp(url, URLs[idx].url)) {{{ INPUT = file(URLs[idx].file, &in_size); if (INPUT == NULL) goto error_1; goto ende_1; }}} error_1:if (INPUT != NULL) free (INPUT); INPUT = NULL; ende_1: if (INPUT == NULL) { INPUT = reinterpret_cast(STRDUP ("cDonkey says hello!
Internal NULL error!\n")); in_size = strlen(reinterpret_cast(INPUT)); } Write(reinterpret_cast(CON_CLOSE),strlen(CON_CLOSE)); Write(reinterpret_cast("\r\n"), strlen("\r\n")); Parse(INPUT); Write(reinterpret_cast("\0"), 1); if (INPUT != NULL) free (INPUT); addEvent(32); return 1; }}} /* * vim600: fdm=marker */