summaryrefslogtreecommitdiff
path: root/main.c
blob: b8be592a62e43b69f5ee048917824846562900a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>

#include <err.h>
#include <errno.h>

#include <pthread.h>

void * next_customer(void * new_socket)
{
	if (new_socket == 0) return NULL;


	// read the input data...
  char * input_buffer = {0};
	size_t input_buffer_position = 0;
	FILE * f_input = open_memstream(&input_buffer, &input_buffer_position);


	for(
			int size=1024,
				read_buffer[1024] = {0};
			size>0;
			size=recv((size_t) new_socket, read_buffer, 1024, MSG_WAITALL)) {
		fwrite(read_buffer, size, 1, f_input);
		usleep(10); // TODO: implement with some sort of epoll
	}

	fflush(f_input);
  printf("input_buffer has %ld bytes and contains:\n", input_buffer_position);

	char * c = strstr(input_buffer, "Content-Type");
	printf("WE ARE HERE: %s\n", c);
	write(STDOUT_FILENO, input_buffer, input_buffer_position);



	// answer the call...

	char * buffer = {0};
	size_t buffer_position = 0;
	FILE * f = open_memstream(&buffer, &buffer_position);
	fputs("HTTP/1.0 200 OK\n", f);
	fputs("content-type: text/html\n\n", f);
	fputs("<html>", f);
	fputs("<head>", f);
	fputs("<title>test</title>", f);
	fputs("<style>label { display:block }</style>", f);
	fputs("</head>", f);
	fputs("<form action=\"/\" method=\"post\" enctype=\"multipart/form-data\">", f);
	fputs("<label>Line1<br/>\n", f);
	fputs("<textarea type=\"text\" name=\"text\"></textarea>", f);
	fputs("</label><br/>\n", f);
	fputs("<input type=\"submit\" name=\"okay\" value=\"ok\" />", f);
	fputs("</form>", f);
	fputs("</html>\n", f);
	fflush(f);
	printf("OOOOO [%ld] %s\n", buffer_position, buffer);

  send((size_t) new_socket, buffer, buffer_position, MSG_EOR);
	// fclose(f_socket);
	close((size_t) new_socket);
	fclose(f_input);
	fclose(f);

  return NULL;
}

void serve(int server_fd)
{
  struct sockaddr_in address;
  int addrlen = sizeof(address);
  warn("waiting for connections on %d", server_fd);

  for(size_t new_socket = 0
      ; 1 ; new_socket=accept(server_fd, (struct sockaddr*) &address, (socklen_t*) &addrlen))
  {
    warn("next: %ld\n", new_socket);
		// set non blocking mode...
		fcntl((size_t) new_socket, F_SETFL,
				fcntl((size_t) new_socket, F_GETFL) | O_NONBLOCK);

    // next_customer(new_socket);
    pthread_t thread_id;
    pthread_create(&thread_id, NULL, next_customer, (void*) new_socket);
    pthread_join(thread_id, NULL);
  }
}

#define PORT 8080
int main(int argc, char const *argv[]) 
{
  int server_fd;
  int opt = 1;

  struct sockaddr_in address;
  address.sin_family = AF_INET;
  address.sin_addr.s_addr = INADDR_ANY;
  address.sin_port = htons(PORT);

  0 == (server_fd = socket(AF_INET, SOCK_STREAM, 0))
    ? err(EXIT_FAILURE, NULL)
  : setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))
    ? err(EXIT_FAILURE, "setsockopt failed on socket with fileno %d", server_fd)
  : bind(server_fd, (struct sockaddr*) &address, sizeof(address))
    ? err(EXIT_FAILURE, NULL)
  : listen(server_fd, 3)
    ? err(EXIT_FAILURE, NULL)
  : serve(server_fd);


  return 0;
}

// vim: shiftwidth=2 tabstop=2 number
..