Added a file: ruby_binding/test_camping.rb
[ebb.git] / ebb.c
blob2f4dbdeed9286b3e7b5228f7c6ec5a16d40bc1bc
1 /* Ebb Web Server
2 * Copyright (c) 2007 Ry Dahl
3 * This software is released under the "MIT License". See README file for details.
4 */
6 #include <glib.h>
7 #include <ev.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <assert.h>
13 #include <errno.h>
15 #include "mongrel/parser.h"
16 #include "tcp.h"
18 #include "ebb.h"
19 #include "parser_callbacks.h"
21 void* ebb_handle_request(void *_client);
22 ebb_client* ebb_client_new(ebb_server *, tcp_peer *);
24 ebb_server* ebb_server_new(struct ev_loop *loop)
26 ebb_server *server = g_new0(ebb_server, 1);
27 server->socket = tcp_listener_new(loop);
28 return server;
31 void ebb_server_free(ebb_server *server)
33 tcp_listener_free(server->socket);
36 void ebb_server_stop(ebb_server *server)
38 tcp_listener_close(server->socket);
41 void ebb_on_read(char *buffer, int length, void *_client)
43 ebb_client *client = (ebb_client*)(_client);
44 assert(client);
45 assert(client->socket);
46 assert(client->socket->open);
47 //assert(client->socket->open);
48 assert(!http_parser_is_finished(&(client->parser)));
50 g_string_append_len(client->buffer, buffer, length);
52 http_parser_execute( &(client->parser)
53 , client->buffer->str
54 , client->buffer->len
55 , client->parser.nread
58 if(http_parser_is_finished(&(client->parser))) {
59 ebb_handle_request(client);
64 /* User is responsible for freeing the client */
65 void* ebb_handle_request(void *_client)
67 const char *ebb_input = "ebb.input";
68 const char *server_name = "SERVER_NAME";
69 const char *server_port = "SERVER_PORT";
70 char *server_name_value, *server_port_value;
71 ebb_client *client = (ebb_client*)(_client);
73 assert(client);
74 assert(client->socket);
75 assert(client->socket->open);
78 ebb_client_add_env(client, ebb_input, strlen(ebb_input)
79 , client->buffer->str, client->buffer->len);
81 server_name_value = tcp_listener_address(client->server->socket);
82 ebb_client_add_env(client, server_name, strlen(server_name)
83 , server_name_value, strlen(server_name_value));
85 server_port_value = client->server->socket->port_s;
86 ebb_client_add_env(client, server_port, strlen(server_port)
87 , server_port_value, strlen(server_port_value));
89 client->server->request_cb(client, client->server->request_cb_data);
90 /* Cannot access client beyond this point because it's possible that the
91 * user has freed it.
94 return NULL;
97 void ebb_on_request(tcp_peer *socket, void *data)
99 ebb_server *server = (ebb_server*)(data);
100 ebb_client *client = ebb_client_new(server, socket);
102 assert(client->socket->open);
103 assert(server->socket->open);
105 socket->read_cb = ebb_on_read;
106 socket->read_cb_data = client;
109 void ebb_server_start( ebb_server *server
110 , char *host
111 , int port
112 , ebb_request_cb_t request_cb
113 , void *request_cb_data
116 server->request_cb = request_cb;
117 server->request_cb_data = request_cb_data;
118 tcp_listener_listen(server->socket, host, port, ebb_on_request, server);
121 ebb_client* ebb_client_new(ebb_server *server, tcp_peer *socket)
123 ebb_client *client = g_new0(ebb_client, 1);
125 client->server = server;
126 client->socket = socket;
128 /* http_parser */
129 http_parser_init(&(client->parser));
130 client->parser.data = client;
131 client->parser.http_field = ebb_http_field_cb;
132 client->parser.request_method = ebb_request_method_cb;
133 client->parser.request_uri = ebb_request_uri_cb;
134 client->parser.fragment = ebb_fragment_cb;
135 client->parser.request_path = ebb_request_path_cb;
136 client->parser.query_string = ebb_query_string_cb;
137 client->parser.http_version = ebb_http_version_cb;
138 client->parser.header_done = ebb_header_done_cb;
140 /* buffer */
141 client->buffer = g_string_new("");
143 /* env */
144 client->env_size = 0;
146 return client;
149 void ebb_client_close(ebb_client *client)
151 tcp_peer_close(client->socket);
154 void ebb_client_free(ebb_client *client)
156 tcp_peer_close(client->socket);
158 /* http_parser */
159 http_parser_finish(&(client->parser));
161 /* buffer */
162 g_string_free(client->buffer, TRUE);
164 free(client);
167 // writes to the client
168 int ebb_client_write(ebb_client *this, const char *data, int length)
170 return tcp_peer_write(this->socket, data, length);