Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0f51f68

Browse filesBrowse files
committed
tidy up C code, refactor html and template
add new functionality to access GET/POST/connection headers, send file and data string TODO: template var struct needs to be freed properly, file() not working, yields "connection dropped" error
1 parent 3bb4ac7 commit 0f51f68
Copy full SHA for 0f51f68

File tree

3 files changed

+272
-83
lines changed
Filter options

3 files changed

+272
-83
lines changed

‎stl/httpd.c

Copy file name to clipboard
+157-69Lines changed: 157 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,98 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <errno.h>
4+
#include <fcntl.h>
5+
#include <sys/stat.h>
6+
17
#include <sys/types.h>
28
#ifndef _WIN32
39
#include <sys/select.h>
410
#include <sys/socket.h>
511
#else
612
#include <winsock2.h>
713
#endif
8-
#include <microhttpd.h>
9-
#include <stdio.h>
1014

15+
#include "microhttpd.h"
1116
#include "httpd.h"
1217
#include "ctemplate.h"
1318
#include "stl.h"
14-
#include <string.h>
15-
#include <errno.h>
1619

20+
// macros
21+
#define WEB_DEBUG(...) if (web_debug_flag) stl_log(__VA_ARGS__)
22+
23+
// forward defines
1724
static struct MHD_Daemon *daemon;
1825
static void (*request_matlab_callback)(void);
19-
TMPL_varlist *web_varlist;
20-
21-
static int
22-
print_out_key (void *cls, enum MHD_ValueKind kind, const char *key,
23-
const char *value)
24-
{
25-
(void)cls; /* Unused. Silent compiler warning. */
26-
(void)kind; /* Unused. Silent compiler warning. */
27-
printf ("%s: %s\n", key, value);
28-
return MHD_YES;
29-
}
26+
static void send_data(void *s, int len, char *type);
27+
static int print_key (void *cls, enum MHD_ValueKind kind, const char *key,
28+
const char *value);
3029

30+
// local copies of the request parameters
31+
static TMPL_varlist *web_varlist;
3132
static struct MHD_Connection *req_connection;
3233
static int req_response_status;
3334
static char *req_url;
3435
static char *req_method;
3536

37+
int web_debug_flag = 1;
38+
3639
static int
3740
page_request (void *cls, struct MHD_Connection *connection,
3841
const char *url, const char *method,
3942
const char *version, const char *upload_data,
4043
size_t *upload_data_size, void **con_cls)
4144
{
42-
(void)cls; /* Unused. Silent compiler warning. */
43-
(void)version; /* Unused. Silent compiler warning. */
44-
(void)upload_data; /* Unused. Silent compiler warning. */
45-
(void)upload_data_size; /* Unused. Silent compiler warning. */
46-
(void)con_cls; /* Unused. Silent compiler warning. */
47-
/*
48-
printf ("New %s request for %s using version %s\n", method, url, version);
49-
50-
51-
MHD_get_connection_values (connection, MHD_HEADER_KIND, print_out_key,
52-
NULL);
5345

46+
/*
47+
MHD_get_connection_values (connection, MHD_HEADER_KIND, print_key, NULL);
48+
MHD_get_connection_values (connection, MHD_GET_ARGUMENT_KIND, print_key, NULL);
49+
*/
5450

55-
printf("URL %s\n", url);
56-
printf("version %s\n", version);
57-
printf("method %s\n", version);
58-
printf("upload data %s\n", upload_data);
59-
*/
60-
req_connection = connection;
61-
req_url = url;
62-
req_method = method;
51+
WEB_DEBUG("web: %s request for URL %s using %s", method, url, version);
52+
53+
// save some of the parameters for access by MATLAB calls
54+
req_connection = connection;
55+
req_url = (char *)url;
56+
req_method = (char *)method;
6357

64-
web_varlist = NULL; // set the template list to empty
58+
// free up the old list somewhere TMPL_free_varlist(varlist)
59+
web_varlist = NULL; // set the template list to empty
6560

66-
// free up the old list somewhere TMPL_free_varlist(varlist)
61+
// set the return status to fail, it will be set by any of the callbacks
62+
req_response_status = MHD_NO;
63+
64+
// call the user's MATLAB code
65+
request_matlab_callback();
6766

68-
/*
69-
MHD_get_connection_values (connection, MHD_GET_ARGUMENT_KIND, print_out_key,
70-
NULL);
71-
*/
72-
req_response_status = MHD_NO;
73-
stl_log("web: %s request for URL %s using %s", method, url, version);
74-
request_matlab_callback();
75-
76-
return req_response_status;
67+
// return the status
68+
return req_response_status;
7769
}
7870

71+
/**
72+
* Send string to the web browser
73+
*/
7974
void
8075
web_html(char *html)
8176
{
82-
struct MHD_Response *response;
8377

84-
//stl_log("web_html: %s", html);
78+
WEB_DEBUG("web_html: %s", html);
8579

86-
response = MHD_create_response_from_buffer(strlen(html), html, MHD_RESPMEM_MUST_COPY);
87-
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, "text/html");
88-
req_response_status = MHD_queue_response(req_connection, MHD_HTTP_OK, response);
89-
MHD_destroy_response(response);
80+
send_data(html, strlen(html), "text/html");
81+
}
82+
83+
/**
84+
* Invoke the template processor
85+
*/
86+
void web_template(char *filename)
87+
{
88+
char buffer[BUFSIZ];
89+
FILE *html = fmemopen(buffer, BUFSIZ, "w");
90+
91+
WEB_DEBUG("web_template: %s", filename);
92+
TMPL_write(filename, 0, 0, web_varlist, html, stderr);
93+
fclose(html);
94+
95+
send_data(buffer, strlen(buffer), "text/html");
9096
}
9197

9298
/**
@@ -95,35 +101,96 @@ web_html(char *html)
95101
void
96102
web_url(char *buf, int buflen)
97103
{
98-
stl_log("web_url: %s", req_url);
104+
WEB_DEBUG("web_url: %s", req_url);
99105
strncpy(buf, req_url, buflen);
100106
}
101107

108+
void
109+
web_file(char *filename, char *type)
110+
{
111+
WEB_DEBUG("web_file: %s, type %s", filename, type);
102112

113+
struct MHD_Response *response;
114+
int fd;
115+
struct stat statbuf;
116+
int ret;
117+
118+
fd = open(filename, O_RDONLY);
119+
if (fd == -1)
120+
stl_error("web_file: couldn't open file %s", filename);
121+
ret = fstat(fd, &statbuf);
122+
if (ret != 0)
123+
stl_error("web_file: couldn't stat file %s", filename);
124+
125+
stl_log("file is %ld bytes", (uint64_t) statbuf.st_size);
126+
response = MHD_create_response_from_fd(statbuf.st_size, fd);
127+
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, type);
128+
MHD_add_response_header(response, MHD_HTTP_HEADER_CONNECTION, "close");
129+
req_response_status = MHD_queue_response(req_connection, MHD_HTTP_OK, response);
130+
MHD_destroy_response(response);
131+
close(fd);
132+
}
103133

104-
/**
105-
* Set a value for the template processor
106-
*/
107-
void web_setvalue(char *name, char *value)
134+
void
135+
web_data(void *data, int len, char *type)
108136
{
109-
stl_log("web_setvalue: %s %s", name, value);
110-
web_varlist = TMPL_add_var(web_varlist, stl_stralloc(name), stl_stralloc(value), NULL);
137+
WEB_DEBUG("web_data: %d bytes, type %s", len, type);
138+
139+
send_data(data, len, type);
111140
}
112141

113-
/**
114-
* Invoke the template processor
115-
*/
116-
void web_template(char *filename)
142+
int
143+
web_ispost()
117144
{
118-
char buffer[BUFSIZ];
119-
FILE *html = fmemopen(buffer, BUFSIZ, "w");
145+
return strcmp(req_method, MHD_HTTP_METHOD_POST);
146+
}
147+
148+
int32_t
149+
web_getarg(char *buf, int len, char *name)
150+
{
151+
char *value = (char *)MHD_lookup_connection_value(req_connection, MHD_GET_ARGUMENT_KIND, name);
120152

121-
bzero(buffer, BUFSIZ);
122-
stl_log("web_template: %s", filename);
123-
TMPL_write(filename, 0, 0, web_varlist, html, stderr);
124-
stl_log("length %d", strlen(buffer));
153+
if (value) {
154+
strncpy(buf, value, len);
155+
buf[len-1] = 0; // for safety with long strings
156+
return 1; // key found
157+
} else
158+
return 0;
159+
}
160+
161+
int32_t
162+
web_postarg(char *buf, int len, char *name)
163+
{
164+
char *value = (char *)MHD_lookup_connection_value(req_connection, MHD_POSTDATA_KIND, name);
165+
166+
if (value) {
167+
strncpy(buf, value, len);
168+
buf[len-1] = 0; // for safety with long strings
169+
return 1; // key found
170+
} else
171+
return 0;
172+
}
173+
174+
int
175+
web_reqheader(char *buf, int len, char *name)
176+
{
177+
char *value = (char *)MHD_lookup_connection_value(req_connection, MHD_HEADER_KIND, name);
178+
179+
if (value) {
180+
strncpy(buf, value, len);
181+
buf[len-1] = 0; // for safety with long strings
182+
return 1; // key found
183+
} else
184+
return 0;
185+
}
125186

126-
web_html(buffer);
187+
/**
188+
* Set a value for the template processor
189+
*/
190+
void web_setvalue(char *name, char *value)
191+
{
192+
WEB_DEBUG("web_setvalue: %s %s", name, value);
193+
web_varlist = TMPL_add_var(web_varlist, stl_stralloc(name), stl_stralloc(value), NULL);
127194
}
128195

129196
void
@@ -142,4 +209,25 @@ web_start(int32_t port, char *callback)
142209
stl_error("web server failed to launch: %s", strerror(errno));
143210

144211
stl_log("web server starting on port %u", port);
212+
}
213+
214+
static void
215+
send_data(void *s, int len, char *type)
216+
{
217+
struct MHD_Response *response;
218+
219+
response = MHD_create_response_from_buffer(len, s, MHD_RESPMEM_MUST_COPY);
220+
MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, type);
221+
req_response_status = MHD_queue_response(req_connection, MHD_HTTP_OK, response);
222+
MHD_destroy_response(response);
223+
}
224+
225+
static int
226+
print_key (void *cls, enum MHD_ValueKind kind, const char *key,
227+
const char *value)
228+
{
229+
(void)cls; /* Unused. Silent compiler warning. */
230+
(void)kind; /* Unused. Silent compiler warning. */
231+
printf ("%s: %s\n", key, value);
232+
return MHD_YES;
145233
}

‎stl/httpd.h

Copy file name to clipboard
+15-2Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
1+
#ifndef __httpd_h_
2+
#define __httpd_h_
13

2-
void web_url(char *buf, int len);
4+
// C functions in httpd.c which are wrapped by webserver.m
35
void web_start(int32_t port, char *callback);
6+
7+
void web_url(char *buf, int len);
8+
int web_ispost();
9+
410
void web_html(char *html);
511
void web_setvalue(char *name, char *value);
6-
void web_template(char *filename);
12+
void web_template(char *filename);
13+
void web_file(char *filename, char *type);
14+
void web_data(void *data, int len, char *type);
15+
16+
int32_t web_getarg(char *buf, int len, char *name);
17+
int32_t web_postarg(char *buf, int len, char *name);
18+
int web_reqheader(char *buf, int len, char *name);
19+
#endif

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.