// vim:noexpandtab:syntax=lpc // $Id: library.i,v 1.40 2008/04/27 08:20:47 lynx Exp $ // // HTTP function library -lynx // // (extension to "simul_efun") #include #include #include #include "driver.h" //#include CONFIG_PATH "ports.h" #include "ht/http.h" #if !HAS_PORT(HTTP_PORT, HTTP_PATH) # undef HTTP_PORT # define HTTP_PORT 44444 // should return null instead? #endif // not worthy of summoning uniform.h for this one.. string htuniform(object server, string prot, mapping headers) { // it is really totally crazy to trust what the browser says string host = headers["host"]; int port = HTTP_PORT; #if __EFUN_DEFINED__(tls_query_connection_state) #ifndef HTTPS_HOST string scheme = "http://"; # endif unless (server) server = this_interactive(); if (tls_query_connection_state(server)) { #ifdef HTTPS_HOST return HTTPS_HOST; #else scheme = "https://"; # if HAS_TLS_PORT(HTTPS_PORT) port = HTTPS_PORT; # endif #endif } # define SCHEME scheme # define PORT port #else # define SCHEME "http://" # define PORT HTTP_PORT #endif unless (host) { #ifdef HTTP_HOST return HTTP_HOST; #else host = SERVER_HOST; // HTTP_SERVICE is 80 from services.h if (port != HTTP_SERVICE) host += ":"+to_string(port); #endif } return SCHEME + host; } varargs string htheaders(string type, string extra) { string out; unless (stringp(type)) type = DEFAULT_CONTENT_TYPE; out = "Content-type: "+ type +"\n"; // if (length) { // printf("Content-length: %d\n", length); // } if (extra) out += extra; return out; } varargs string htheaders2(string type, string extra) { return htheaders(type, extra) + "Server: " HTTP_SERVER "\nDate: "+ ctime(time()) +"\n"; } void htrequireauth(string prot, string type, string realm) { if (prot) write(HTTP_SVERS + " " + to_string(R_UNAUTHORIZED) + "Your password, please\n"); if (type == "digest") { write("WWW-Authenticate: Digest realm=\"" + realm + "\", nonce=\"" + time() + "\"\n"); } else { write("WWW-Authenticate: Basic realm=\"" + realm + "\"\n"); } } varargs string htredirect(string prot, string target, string comment, int permanent, string extra) { if (!comment) comment = "Check this out"; if (!target) target = "/"; if (!extra) extra = ""; if (prot) { printf("%s %d %s\n%s", HTTP_SVERS, permanent ? R_MOVED : R_FOUND, comment, htheaders()); } // this page might actually be visible // if content-disposition: attachment is given // or redirects are otherwise intercepted by plugin // so a proper _PAGES form could be appropriate printf("\ Location: %s\n%s\ \n\ %s\n\ \n\ %s\n", // exposing the link to end-user may not be intended: // %s. target, extra, comment, comment); return 0; } // written and donated by _Marcus_ // // thanx!! /* convert %XX escapes to real chars */ static int xx2l(string str) { int x; str=lower_case(str); if (str[0]>='0' && str[0]<='9') x=(str[0]-'0')*16; if (str[0]>='a' && str[0]<='f') x=(str[0]-'a'+10)*16; if (str[1]>='0' && str[1]<='9') x+=str[1]-'0'; if (str[1]>='a' && str[1]<='f') x+=str[1]-'a'+10; return x; } /* Content-Encoding: url-encoded */ string urldecode(string txt) { string *xx; int i; txt=implode(explode(txt,"+")," "); #if __EFUN_DEFINED__(regexplode) xx=regexplode(txt,"%.."); for (i=1;i); foreach(string key : keys) { q += (strlen(q) ? "&" : "") + urlencode(to_string(key)) + "=" + urlencode(to_string(params[key])); } return q; } object check_query_token(mapping query) { string nick; object user; if (nick = query["user"]) user = find_person(nick); if (user && user->validToken(query["token"])) return user; return 0; }