1 /***************************************************************************
2 * Copyright (C) 2007,2008 Øyvind Harboe *
3 * oyvind.harboe@zylin.com *
5 * Copyright (C) 2008 Free Software Foundation
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
23 /* some bits were copied from ahttpd which is under eCos license and
30 #include "replacements.h"
35 #include "telnet_server.h"
43 #include <sys/types.h>
47 #include <sys/types.h>
48 #include <sys/select.h>
49 #include <sys/socket.h>
50 #include <microhttpd.h>
55 #define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
57 static const char *appendf(const char *prev
, const char *format
, ...)
61 char *string
= alloc_vprintf(format
, ap
);
67 string2
= alloc_printf("%s%s", (prev
== NULL
) ? "" : prev
, string
);
81 static const char *httpd_exec_cgi_tcl_error(Jim_Interp
*interp
)
86 t
= appendf(t
, "<html><body>\n");
88 t
= appendf(t
, "Runtime error, file \"%s\", line %d:<br>",
89 interp
->errorFileName
, interp
->errorLine
);
90 t
= appendf(t
, " %s<br>", Jim_GetString(interp
->result
, NULL
));
91 Jim_ListLength(interp
, interp
->stackTrace
, &len
);
92 for (i
= 0; i
< len
; i
+= 3)
95 const char *proc
, *file
, *line
;
97 Jim_ListIndex(interp
, interp
->stackTrace
, i
, &objPtr
, JIM_NONE
);
98 proc
= Jim_GetString(objPtr
, NULL
);
99 Jim_ListIndex(interp
, interp
->stackTrace
, i
+ 1, &objPtr
, JIM_NONE
);
100 file
= Jim_GetString(objPtr
, NULL
);
101 Jim_ListIndex(interp
, interp
->stackTrace
, i
+ 2, &objPtr
, JIM_NONE
);
102 line
= Jim_GetString(objPtr
, NULL
);
103 t
= appendf(t
, "In procedure '%s' called at file \"%s\", line %s<br>",
106 t
= appendf(t
, "</html></body>\n");
111 static int httpd_Jim_Command_writeform(Jim_Interp
*interp
, int argc
,
112 Jim_Obj
* const *argv
)
116 Jim_WrongNumArgs(interp
, 1, argv
, "method ?args ...?");
119 char *name
= (char*) Jim_GetString(argv
[1], NULL
);
120 char *file
= (char*) Jim_GetString(argv
[2], NULL
);
128 const char *script
= alloc_printf("set dummy_val $httppostdata(%s); set dummy_val",
130 retcode
= Jim_Eval_Named(interp
, script
, "httpd.c", __LINE__
);
131 free((void *) script
);
132 if (retcode
!= JIM_OK
)
135 data
= Jim_GetString(Jim_GetResult(interp
), &actual
);
138 f
= fopen(file
, "wb");
142 ok
= fwrite(data
, 1, actual
, f
) == actual
;
147 Jim_SetResultString(interp
, "Could not write to file", -1);
153 Jim_SetResultString(interp
, "Could not create file", -1);
161 httpd_Jim_Command_formfetch(Jim_Interp
*interp
,
163 Jim_Obj
*const *argv
)
167 Jim_WrongNumArgs(interp
, 1, argv
, "method ?args ...?");
170 char *name
= (char*)Jim_GetString(argv
[1], NULL
);
173 const char *script
= alloc_printf("set dummy_val $httppostdata(%s); set dummy_val",
175 int retcode
= Jim_Eval_Named(interp
, script
, "httpd.c", __LINE__
);
176 free((void *) script
);
177 if (retcode
!= JIM_OK
)
179 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
182 Jim_SetResult(interp
, Jim_GetResult(interp
));
191 struct MHD_PostProcessor
*postprocessor
;
195 int complete
; /* did we receive the entire post ? */
199 static void request_completed(void *cls
, struct MHD_Connection
*connection
,
200 void **con_cls
, enum MHD_RequestTerminationCode toe
)
202 struct httpd_request
*r
= (struct httpd_request
*) *con_cls
;
207 if (r
->postprocessor
)
209 MHD_destroy_post_processor(r
->postprocessor
);
216 /* append to said key in dictonary */
217 static void append_key(struct httpd_request
*r
, const char *key
,
218 const char *data
, size_t off
, size_t size
)
220 Jim_Obj
*keyObj
= Jim_NewStringObj(interp
, key
, -1);
221 Jim_Obj
*value
= NULL
;
223 Jim_Obj
*dict
= Jim_GetVariableStr(interp
, "httppostdata", 0);
227 if (Jim_DictKey(interp
, dict
, keyObj
, &value
, 0) != JIM_OK
)
233 value
= Jim_NewStringObj(interp
, "", -1);
235 /* create a new object we append to and insert into this location */
236 Jim_Obj
*newObj
= Jim_NewStringObj(interp
, "", -1);
237 Jim_AppendObj(interp
, newObj
, value
);
238 Jim_AppendString(interp
, newObj
, data
, size
);
239 /* uhh... use name here of dictionary */
240 Jim_SetDictKeysVector(interp
, Jim_NewStringObj(interp
, "httppostdata", -1), &keyObj
, 1, newObj
);
243 /* append data to each key */
244 static int iterate_post(void *con_cls
, enum MHD_ValueKind kind
,
245 const char *key
, const char *filename
, const char *content_type
,
246 const char *transfer_encoding
, const char *data
, size_t off
,
249 struct httpd_request
*r
= (struct httpd_request
*) con_cls
;
251 append_key(r
, key
, data
, off
, size
);
256 static int record_arg(void *cls
, enum MHD_ValueKind kind
, const char *key
,
259 struct httpd_request
*r
= (struct httpd_request
*) cls
;
260 append_key(r
, key
, value
, 0, strlen(value
));
265 int handle_request(struct MHD_Connection
* connection
, const char * url
)
267 struct MHD_Response
* response
;
271 suffix
= strrchr(url
, '.');
272 if ((suffix
!= NULL
) && (strcmp(suffix
, ".tcl") == 0))
274 printf("Run tcl %s\n", url
);
278 const char *script
= alloc_printf(
279 "global httpdata; source {%s}; set httpdata", url
);
280 retcode
= Jim_Eval_Named(interp
, script
, "httpd.c", __LINE__
);
281 free((void *) script
);
283 if (retcode
== JIM_ERR
)
285 printf("Tcl failed\n");
286 const char *t
= httpd_exec_cgi_tcl_error(interp
);
290 response
= MHD_create_response_from_data(strlen(t
), (void *) t
,
292 ret
= MHD_queue_response(connection
,
293 MHD_HTTP_INTERNAL_SERVER_ERROR
, response
);
294 MHD_destroy_response(response
);
300 /* FIX!!! how to handle mime types??? */
303 result
= Jim_GetString(Jim_GetResult(interp
), &reslen
);
305 response
= MHD_create_response_from_data(reslen
, (void *) result
,
307 ret
= MHD_queue_response(connection
,
308 MHD_HTTP_INTERNAL_SERVER_ERROR
, response
);
309 MHD_destroy_response(response
);
318 int retval
= loadFile(url
, &data
, &len
);
319 if (retval
!= ERROR_OK
)
321 printf("Did not find %s\n", url
);
323 response
= MHD_create_response_from_data(strlen(PAGE_NOT_FOUND
),
324 (void *) PAGE_NOT_FOUND
, MHD_NO
, MHD_NO
);
325 ret
= MHD_queue_response(connection
, MHD_HTTP_NOT_FOUND
, response
);
326 MHD_destroy_response(response
);
330 LOG_DEBUG("Serving %s length=%d", url
, len
);
331 /* serve file directly */
332 response
= MHD_create_response_from_data(len
, data
, MHD_YES
, MHD_NO
);
333 MHD_add_response_header(response
, "Content-Type", "image/png");
335 ret
= MHD_queue_response(connection
, MHD_HTTP_OK
, response
);
336 MHD_destroy_response(response
);
343 static int ahc_echo(void * cls
, struct MHD_Connection
* connection
,
344 const char * url
, const char * method
, const char * version
,
345 const char * upload_data
, unsigned int * upload_data_size
, void ** ptr
)
349 if (0 == strcmp(method
, "POST"))
353 else if (0 == strcmp(method
, "GET"))
358 return MHD_NO
; /* unexpected method */
361 struct httpd_request
*r
;
364 /* The first time only the headers are valid,
365 do not respond in the first round... */
367 *ptr
= malloc(sizeof(struct httpd_request
));
370 memset(*ptr
, 0, sizeof(struct httpd_request
));
372 r
= (struct httpd_request
*) *ptr
;
375 Jim_SetVariableStr(interp
, "httppostdata", Jim_NewDictObj(interp
, NULL
, 0));
377 /* fill in url query strings in dictonary */
378 MHD_get_connection_values(connection
, MHD_GET_ARGUMENT_KIND
,
383 r
->postprocessor
= MHD_create_post_processor(connection
, 2048
384 * 1024, iterate_post
, r
);
390 r
= (struct httpd_request
*) *ptr
;
394 /* consume post data */
395 if (*upload_data_size
)
397 MHD_post_process(r
->postprocessor
, upload_data
, *upload_data_size
);
398 *upload_data_size
= 0;
408 /* hand over to request who will be using it. */
412 /* FIX!!!! we need more advanced handling of url's to avoid them
413 * being subverted to evil purposes
416 const char *httpd_dir
=PKGLIBDIR
"/httpd";
420 url
++; /* skip '/' */
425 const char *file_name
=alloc_printf("%s/%s", httpd_dir
, url
);
426 int result
= handle_request(connection
, file_name
);
427 free((void *)file_name
);
431 static struct MHD_Daemon
* d
;
433 int httpd_start(void)
437 LOG_USER("Launching httpd server on port %d", port
);
438 d
= MHD_start_daemon(MHD_USE_SELECT_INTERNALLY
, port
, NULL
, NULL
,
439 &ahc_echo
, NULL
, /* could be data for handler, but we only have a single handler, use global variables instead */
440 MHD_OPTION_NOTIFY_COMPLETED
, request_completed
, NULL
, /* Closure... what's that??? */
445 Jim_CreateCommand(interp
,
447 httpd_Jim_Command_formfetch
,
451 Jim_CreateCommand(interp
,
453 httpd_Jim_Command_writeform
,
461 void httpd_stop(void)
466 void openocd_sleep_prelude(void)
468 /* FIX!!!! add locking here!!!! */
471 void openocd_sleep_postlude(void)
473 /* FIX!!!! add locking here!!!! */
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)