1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ #include <errno.h>
4
+ #include <fcntl.h>
5
+ #include <sys/stat.h>
6
+
1
7
#include <sys/types.h>
2
8
#ifndef _WIN32
3
9
#include <sys/select.h>
4
10
#include <sys/socket.h>
5
11
#else
6
12
#include <winsock2.h>
7
13
#endif
8
- #include <microhttpd.h>
9
- #include <stdio.h>
10
14
15
+ #include "microhttpd.h"
11
16
#include "httpd.h"
12
17
#include "ctemplate.h"
13
18
#include "stl.h"
14
- #include <string.h>
15
- #include <errno.h>
16
19
20
+ // macros
21
+ #define WEB_DEBUG (...) if (web_debug_flag) stl_log(__VA_ARGS__)
22
+
23
+ // forward defines
17
24
static struct MHD_Daemon * daemon ;
18
25
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 );
30
29
30
+ // local copies of the request parameters
31
+ static TMPL_varlist * web_varlist ;
31
32
static struct MHD_Connection * req_connection ;
32
33
static int req_response_status ;
33
34
static char * req_url ;
34
35
static char * req_method ;
35
36
37
+ int web_debug_flag = 1 ;
38
+
36
39
static int
37
40
page_request (void * cls , struct MHD_Connection * connection ,
38
41
const char * url , const char * method ,
39
42
const char * version , const char * upload_data ,
40
43
size_t * upload_data_size , void * * con_cls )
41
44
{
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);
53
45
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
+ */
54
50
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 ;
63
57
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
65
60
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 ();
67
66
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 ;
77
69
}
78
70
71
+ /**
72
+ * Send string to the web browser
73
+ */
79
74
void
80
75
web_html (char * html )
81
76
{
82
- struct MHD_Response * response ;
83
77
84
- //stl_log ("web_html: %s", html);
78
+ WEB_DEBUG ("web_html: %s" , html );
85
79
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" );
90
96
}
91
97
92
98
/**
@@ -95,35 +101,96 @@ web_html(char *html)
95
101
void
96
102
web_url (char * buf , int buflen )
97
103
{
98
- stl_log ("web_url: %s" , req_url );
104
+ WEB_DEBUG ("web_url: %s" , req_url );
99
105
strncpy (buf , req_url , buflen );
100
106
}
101
107
108
+ void
109
+ web_file (char * filename , char * type )
110
+ {
111
+ WEB_DEBUG ("web_file: %s, type %s" , filename , type );
102
112
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
+ }
103
133
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 )
108
136
{
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 );
111
140
}
112
141
113
- /**
114
- * Invoke the template processor
115
- */
116
- void web_template (char * filename )
142
+ int
143
+ web_ispost ()
117
144
{
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 );
120
152
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
+ }
125
186
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 );
127
194
}
128
195
129
196
void
@@ -142,4 +209,25 @@ web_start(int32_t port, char *callback)
142
209
stl_error ("web server failed to launch: %s" , strerror (errno ));
143
210
144
211
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 ;
145
233
}
0 commit comments