HomePort
httpd.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Aalborg University. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  * conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  * of conditions and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY Aalborg University ''AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Aalborg University OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  */
27 
28 #include "hpd/common/hpd_httpd.h"
29 #include "hpd/common/hpd_tcpd.h"
30 #include "httpd_request.h"
31 #include "hpd/hpd_shared_api.h"
32 
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 
38 struct hpd_httpd {
42 };
43 
56 static hpd_tcpd_return_t httpd_on_connect(hpd_tcpd_t *instance, hpd_tcpd_conn_t *conn, void *ws_ctx, void **conn_ctx)
57 {
58  hpd_error_t rc;
59  hpd_httpd_t *httpd = ws_ctx;
60 
61  if ((rc = http_request_create((hpd_httpd_request_t **) conn_ctx, httpd, &httpd->settings, conn, httpd->context))) {
62  HPD_LOG_ERROR(httpd->context, "Failed to create request (code: %d).", rc);
63  return HPD_TCPD_R_STOP;
64  }
65 
66  return HPD_TCPD_R_CONTINUE;
67 }
68 
82 static hpd_tcpd_return_t httpd_on_receive(hpd_tcpd_t *instance, hpd_tcpd_conn_t *conn, void *ws_ctx, void **conn_ctx, const char *buf, size_t len)
83 {
84  hpd_error_t rc;
85  hpd_httpd_t *httpd = ws_ctx;
86 
87  if ((rc = http_request_parse(*conn_ctx, buf, len))) {
88  HPD_LOG_ERROR(httpd->context, "Failed to parse request (code: %d).", rc);
89  return HPD_TCPD_R_STOP;
90  }
91  return HPD_TCPD_R_CONTINUE;
92 }
93 
107 static hpd_tcpd_return_t httpd_on_disconnect(hpd_tcpd_t *instance, hpd_tcpd_conn_t *conn, void *ws_ctx, void **conn_ctx)
108 {
109  hpd_error_t rc;
110  hpd_httpd_t *httpd = ws_ctx;
111 
112  if ((rc = http_request_destroy(*conn_ctx))) {
113  HPD_LOG_ERROR(httpd->context, "Failed to destroy request (code: %d).", rc);
114  return HPD_TCPD_R_STOP;
115  }
116  *conn_ctx = NULL;
117 
118  return HPD_TCPD_R_CONTINUE;
119 }
120 
137 {
138  if (!context) return HPD_E_NULL;
139  if (!httpd || !settings || !loop) HPD_LOG_RETURN_E_NULL(context);
140 
141  // Allocate instance
142  (*httpd) = malloc(sizeof(hpd_httpd_t));
143  if (!(*httpd)) HPD_LOG_RETURN_E_ALLOC(context);
144 
145  // Set context
146  (*httpd)->context = context;
147 
148  // Copy settings
149  memcpy(&(*httpd)->settings, settings, sizeof(hpd_httpd_settings_t));
150 
151  // Construct settings for tcpd
153  ws_settings.port = settings->port;
154  ws_settings.timeout = settings->timeout;
155  ws_settings.on_connect = httpd_on_connect;
156  ws_settings.on_receive = httpd_on_receive;
157  ws_settings.on_disconnect = httpd_on_disconnect;
158  ws_settings.tcpd_ctx = (*httpd);
159 
160  // Create tcpd
161  hpd_error_t rc;
162  if ((rc = hpd_tcpd_create(&(*httpd)->webserver, &ws_settings, context, loop))) {
163  hpd_httpd_destroy(*httpd);
164  return rc;
165  }
166 
167  return HPD_E_SUCCESS;
168 }
169 
179 {
180  if (!httpd) return HPD_E_NULL;
181 
183  free(httpd);
184  return rc;
185 }
186 
197 {
198  if (!httpd) return HPD_E_NULL;
199 
200  return hpd_tcpd_start(httpd->webserver);
201 }
202 
212 {
213  if (!httpd) return HPD_E_NULL;
214 
215  return hpd_tcpd_stop(httpd->webserver);
216 }
217 
Instance of a tcpd.
Definition: tcpd_intern.h:45
static hpd_tcpd_return_t httpd_on_connect(hpd_tcpd_t *instance, hpd_tcpd_conn_t *conn, void *ws_ctx, void **conn_ctx)
Callback for tcpd library.
Definition: httpd.c:56
struct up * instance
hpd_tcpd_nodata_f on_connect
Definition: hpd_tcpd.h:99
hpd_error_t hpd_tcpd_create(hpd_tcpd_t **tcpd, hpd_tcpd_settings_t *settings, const hpd_module_t *context, hpd_ev_loop_t *loop)
Create new tcpd instance.
Definition: tcpd.c:269
static hpd_tcpd_return_t httpd_on_disconnect(hpd_tcpd_t *instance, hpd_tcpd_conn_t *conn, void *ws_ctx, void **conn_ctx)
Callback for tcpd library.
Definition: httpd.c:107
hpd_tcpd_port_t port
Port number.
Definition: hpd_tcpd.h:95
free(data.url)
struct hp_settings settings
hpd_error_t hpd_httpd_stop(hpd_httpd_t *httpd)
Stop a httpd instance.
Definition: httpd.c:211
hpd_error_t hpd_httpd_destroy(hpd_httpd_t *httpd)
Destroy a httpd instance.
Definition: httpd.c:178
hpd_tcpd_port_t port
Definition: hpd_httpd.h:101
static hpd_tcpd_return_t httpd_on_receive(hpd_tcpd_t *instance, hpd_tcpd_conn_t *conn, void *ws_ctx, void **conn_ctx, const char *buf, size_t len)
Callback for tcpd library.
Definition: httpd.c:82
An http request.
hpd_httpd_settings_t settings
Settings.
Definition: httpd.c:39
hpd_error_t hpd_tcpd_stop(hpd_tcpd_t *tcpd)
Stop an already running tcpd.
Definition: tcpd.c:428
hpd_tcpd_nodata_f on_disconnect
Definition: hpd_tcpd.h:101
hpd_error_t hpd_tcpd_start(hpd_tcpd_t *tcpd)
Start the tcpd.
Definition: tcpd.c:318
enum hpd_error hpd_error_t
Definition: hpd_types.h:167
#define HPD_LOG_RETURN_E_ALLOC(CONTEXT)
hpd_error_t http_request_destroy(hpd_httpd_request_t *req)
Destroy a ws_request.
hpd_error_t hpd_httpd_create(hpd_httpd_t **httpd, hpd_httpd_settings_t *settings, const hpd_module_t *context, hpd_ev_loop_t *loop)
Create a new httpd instance.
Definition: httpd.c:135
#define HPD_LOG_RETURN_E_NULL(CONTEXT)
All data to represent a connection.
Definition: tcpd_intern.h:56
Settings struct for webserver.
Definition: hpd_httpd.h:100
hpd_error_t http_request_create(hpd_httpd_request_t **req, hpd_httpd_t *httpd, hpd_httpd_settings_t *settings, hpd_tcpd_conn_t *conn, const hpd_module_t *context)
Create a new ws_request.
static struct ev_loop * loop
hpd_error_t http_request_parse(hpd_httpd_request_t *req, const char *buf, size_t len)
Parse a new chunk of the message.
httpd instance struct
Definition: httpd.c:38
hpd_tcpd_data_f on_receive
Definition: hpd_tcpd.h:100
hpd_tcpd_t * webserver
Webserver instance.
Definition: httpd.c:40
struct ev_loop hpd_ev_loop_t
Definition: hpd_types.h:51
hpd_error_t hpd_tcpd_destroy(hpd_tcpd_t *tcpd)
Destroy tcpd and free used memory.
Definition: tcpd.c:297
Settings struct for tcpd.
Definition: hpd_tcpd.h:94
#define HPD_LOG_ERROR(CONTEXT, FMT,...)
const hpd_module_t * context
Definition: httpd.c:41
#define HPD_TCPD_SETTINGS_DEFAULT
Default settings for tcpd.
Definition: hpd_tcpd.h:113
enum hpd_tcpd_return hpd_tcpd_return_t
hpd_error_t hpd_httpd_start(hpd_httpd_t *httpd)
Start a httpd instance.
Definition: httpd.c:196