Hacker News new | past | comments | ask | show | jobs | submit login

Well, if you can do it in C, and I can see your solution, and it works, then I can do it in a line of perl. But I didn't test his code, so I don't know if this works:

    open( FILE, ">reddit.c"); print FILE '#include <stdio.h>'; print FILE "\n"; print FILE '#include <time.h>'; print FILE "\n"; print FILE '#include <netinet/in.h>';print FILE "\n";print FILE 'typedef struct { int ID; char * title; char * link; char * date; int upVotes; int downVotes; void * next; } Article; Article * root; char * getVal(char * query, char * key) { char * str = malloc(1); int match = 0; int pMatch = 0; char * cur = query; while (*cur != \'\0\') { if (pMatch >= 1 && (*cur == \'&\' || *cur == \'\n\' || *cur == \' \')) { break; } else if (pMatch >= 1) { str = realloc(str, pMatch+1); *(str+pMatch-1) = *cur; ++pMatch; } else if (match == strlen(key)) { pMatch = 1; } else if (*cur == key[match]) { ++match; } else { match = 0; } cur++; } if (pMatch >= 1) { str[pMatch-1] = \'\0\'; return str; } free(str); return NULL; } char from_hex(char ch) { return isdigit(ch) ? ch - \'0\' : tolower(ch) - \'a\' + 10; } char to_hex(char code) { static char hex[] = "0123456789abcdef"; return hex[code & 15]; } char *url_decode(char *str) { char *pstr = str, *buf = malloc(strlen(str) + 1), *pbuf = buf; while (*pstr) { if (*pstr == \'%\') { if (pstr[1] && pstr[2]) { *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); pstr += 2; } } else if (*pstr == \'+\') { *pbuf++ = \' \'; } else { *pbuf++ = *pstr; } pstr++; } *pbuf = \'\0\'; return buf; } void send_headers(FILE *f, int status, char *title, char *extra, char *mime, int length) { char timebuf[128]; fprintf(f, "%s %d %s\r\n", "HTTP/1.0", status, title); fprintf(f, "Server: %s\r\n", "redditserver/1.0"); if (extra) fprintf(f, "%s\r\n", extra); if (mime) fprintf(f, "Content-Type: %s\r\n", mime); if (length >= 0) fprintf(f, "Content-Length: %d\r\n", length); fprintf(f, "Connection: close\r\n"); fprintf(f, "\r\n"); } void reddit(FILE *f) { fprintf(f, "<HTML><HEAD><TITLE>Reddit Clone</TITLE></HEAD>\r\n"); fprintf(f, "<BODY><H1>Submit</H1><form action=\"/\" method=\"get\">Title:<input type=\"text\" name=\"title\" /> Link:<input type=\"text\" name=\"link\" /><input type=\"submit\" value=\"Submit\" /></form>\r\n"); if (root) { fprintf(f, "<h1>Articles</h1>"); Article * cur = root; while (cur != NULL) { fprintf(f, "<p><font size=\"5\">%d<b><a href=\"/?up=%d\">&uarr</b></font><a href=\"%s\">%s</a><br /><font size=\"5\">&nbsp;&nbsp;<b><a href=\"/?down=%d\">&darr</a></b></font>%s -- %s</p>", cur->upVotes - cur->downVotes, cur->ID, cur->link, cur->title, cur->ID, cur->link, cur->date); cur = cur->next; } }fprintf(f, "</BODY></HTML>\r\n"); } int fsize(FILE * f) { fseek(f, 0, SEEK_END); int size = ftell(f); fseek(f, 0, SEEK_SET); return size; } int main(int argc, char *argv[]) { int sock; int port = 1337; struct sockaddr_in sin; sock = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port); while (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { printf("Failed bind\n"); sleep(2); } listen(sock, 5); printf("HTTP server listening on port %d\n", port); root = NULL; while (1) { int s; int size; int hsize; char * buff; FILE * t; FILE * ht; FILE * f; s = accept(sock, NULL, NULL); if (s < 0) break; char * header = calloc(255, 1); size = read(s, header, 255); char * titleEnc = getVal(header, "title"); char * linkEnc = getVal(header, "link"); if (titleEnc && linkEnc) { char * title = url_decode(titleEnc); char * link =  url_decode(linkEnc); free(linkEnc); free(titleEnc); printf("Title: %s -- Link: %s\n", title, link); char  * s = malloc(30); size_t i; struct tm tim; time_t now; now = time(NULL); tim = *(localtime(&now)); i = strftime(s,30,"%b %d, %Y; %H:%M:%S\n",&tim); Article * new = malloc(sizeof(Article)); new->title = title; new->link = link; new->next = NULL; new->date = s; new->upVotes = 0; new->downVotes = 0; if (!root) { root = new; new->ID = 0; } else { int dupe = 0; Article * cur = root; Article * prev = NULL; while (cur != NULL) { if (strcmp(cur->title, new->title) == 0 || strcmp(cur->link, new->link) == 0) { dupe = 1; } prev = cur; cur = cur->next; } if (dupe == 0) { new->ID = prev->ID + 1; prev->next = new; } else free(new); } } char * upID = getVal(header, "up"); if (upID) { int ID = atoi(upID); Article * cur = root; while (cur != NULL) { if (cur->ID == ID) { cur->upVotes++; break; } cur = cur->next; } } char * dID = getVal(header, "down"); if (dID) { int ID = atoi(dID); Article * cur = root;  while (cur != NULL) { if (cur->ID == ID) { cur->downVotes++; break; } cur = cur->next; } } t = tmpfile(); ht = tmpfile(); reddit(t); size = fsize(t); send_headers(ht, 200, "Ok", NULL, "text/html", size); hsize = fsize(ht); buff = malloc(hsize); fread(buff, 1, hsize, ht); write(s,buff,hsize); free(buff); buff = malloc(size); fread(buff, 1, size, t); write(s,buff,size); free(buff); fclose(t); } }';print FILE "\n";`gcc ./reddit.c -o reddit && chmod a+x reddit && ./reddit`;



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: