Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here's one, small enough to fit in a comment:

  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <netinet/in.h>

  main()
  {
        int rc;
        struct sockaddr_in ssa, csa;
        int ss, cs;

        memset(&ssa, 0, sizeof ssa);
        ssa.sin_family = PF_INET;
        ssa.sin_port = htons(8080);
        ssa.sin_addr.s_addr = htonl(INADDR_ANY);

        ss = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
        bind(ss, (struct sockaddr*)&ssa, sizeof ssa);
        listen(ss, 5);

        for (;;) {
                int ln;
                static char rq[1000];
                memset(&csa, 0, sizeof csa);
                ln = sizeof(struct sockaddr);
                cs = accept(ss, (struct sockaddr*)&csa, &ln);
                memset(rq, 0, sizeof rq);
                recv(cs, rq, sizeof rq, 0);
               
                if (!strncmp(rq, "GET /", 5)) {
                        char *b;
                        FILE *f;
                        char *fn;
                        if (b = strchr(rq + 5, ' ')) *b = 0;
                        else rq[sizeof rq - 1] = 0;
                        if (fn = malloc(strlen(rq + 5) + 5)) {
                            char *t, *type();
                            strcpy(fn, "www/");
                            strcat(fn, rq + 5);
                            if ((t = type(fn)) && (f = fopen(fn, "rt"))) {
                                 int n;
                                 static char h[] = "HTTP/1.1 200 OK\nContent-Type: ";
                                 static char c[1000];
                                 strcpy(c, h);
                                 strcat(c, t);
                                 strcat(c, "\n\n");
                                 sendall(cs, c, strlen(c));
                                 while ((n = fread(c, 1, sizeof c, f)) > 0) sendall(cs, c, n);
                                 fclose(f);
                            }
                            else {
                                 static char h[] = "HTTP/1.1 404 NotFound\nContent-Type: text/html\n\n404 Nice try!";
                                 sendall(cs, h, sizeof h - 1);
                         }
                         free(fn);
                        }
                }
                close(cs);
        }
       
        close(ss);
        return 0;
  }

  sendall(s, c, n)
  char *c;
  {
        int m; for (m = 0; (m += send(s, c + m, n - m, 0)) < n;);
  }

  char *type(fn)
  char *fn;
  {
      static char *s[] = {
          ".html", "text/html",
          ".asm", "text/plain",
          ".c", "text/plain",
          ".py", "text/plain" };
      int i;
      for (i = 0; i < sizeof s / sizeof *s; i += 2)
          if (strstr(fn, s[i]))
              return s[i + 1];
      return 0;
  }


I find your lack of carriage returns disturbing


Context: RFC 2616 and RFC 7230 require CRLF line endings instead of just LF.

1. https://tools.ietf.org/html/rfc2616

2. https://tools.ietf.org/html/rfc7230


It's a simple server, yes, but it fails to correctly implement HTTP. But that's the trouble with all these "look a 'simple' X in N Loc"; yes, a great many things get simpler when you ignore the requirements of the standard.

It also has what I would call some security issues, e.g., you can ask for a file outside of the www directory.


> you can ask for a file outside of the www directory.

Was going to point that out, but you beat me to it.




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

Search: