void print_dict_element(onion_response *res, const char *key, const char *value, int flags){ onion_response_write0(res,"<li> "); onion_response_write0(res,key); onion_response_write0(res," = "); onion_response_write0(res,value); onion_response_write0(res,"</li>\n"); }
/** * @short Helper that is called on each header, and writes the header * @memberof onion_response_t */ static void write_header(onion_response *res, const char *key, const char *value, int flags){ //ONION_DEBUG0("Response header: %s: %s",key, value); onion_response_write0(res, key); onion_response_write(res, ": ",2); onion_response_write0(res, value); onion_response_write(res, "\r\n",2); }
/** * @short Writes the given string to the res, but encodes the data using html entities * @ingroup response * * The encoding mens that <code><html> whould become <html></code> */ ssize_t onion_response_write_html_safe(onion_response * res, const char *data) { char *tmp = onion_html_quote(data); if (tmp) { int r = onion_response_write0(res, tmp); onion_low_free(tmp); return r; } else return onion_response_write0(res, data); }
/// Default directory handler: The style + dirname on a h1 void onion_handler_export_local_header_default(onion_response *res, const char *dirname){ onion_response_write0(res, "<style>body{ background: #fefefe; font-family: sans-serif; margin-left: 5%; margin-right: 5%; }\n" " table{ background: white; width: 100%; border: 1px solid #aaa; border-radius: 5px; -moz-border-radius: 5px; } \n" " th{ background: #eee; } tbody tr:hover td{ background: yellow; } tr.dir td{ background: #D4F0FF; }\n" " table a{ display: block; } th{ cursor: pointer} h1,h2{ color: black; text-align: center; } \n" " a{ color: red; text-decoration: none; }</style>\n"); onion_response_printf(res,"<h1>Listing of directory %s</h1>\n",dirname); if (dirname[0]!='\0' && dirname[1]!='\0') // It will be 0, when showpath is "/" onion_response_write0(res,"<h2><a href=\"..\">Go up..</a></h2>\n"); }
onion_connection_status method(void *ignore, onion_request *req, onion_response *res){ if (onion_response_write_headers(res)==OR_SKIP_CONTENT) // Head return OCS_PROCESSED; onion_response_write0(res, "<html><body>\n<h1>Petition resume</h1>\n"); int flags=onion_request_get_flags(req); if (flags&OR_GET) onion_response_write0(res,"<h2>GET"); else if (flags&OR_POST) onion_response_write0(res,"<h2>POST"); else onion_response_write0(res,"<h2>UNKNOWN"); onion_response_printf(res," %s</h2>\n<ul>",onion_request_get_path(req)); const onion_dict *get=onion_request_get_query_dict(req); const onion_dict *post=onion_request_get_post_dict(req); const onion_dict *headers=onion_request_get_header_dict(req); onion_response_printf(res,"<li>Header %d elements<ul>",onion_dict_count(headers)); if (headers) onion_dict_preorder(headers, print_dict_element, res); onion_response_printf(res,"</ul></li>\n"); onion_response_printf(res,"<li>GET %d elements<ul>",onion_dict_count(get)); if (get) onion_dict_preorder(get, print_dict_element, res); onion_response_printf(res,"</ul></li>\n"); onion_response_printf(res,"<li>POST %d elements<ul>",onion_dict_count(post)); if (post) onion_dict_preorder(post, print_dict_element, res); onion_response_printf(res,"</ul></li>\n"); onion_response_write0(res,"<p>\n"); onion_response_write0(res,"<form method=\"GET\">" "<input type=\"text\" name=\"test\">" "<input type=\"submit\" name=\"submit\" value=\"GET\">" "</form><p>\n"); onion_response_write0(res,"<form method=\"POST\" enctype=\"application/x-www-form-urlencoded\">" "<textarea name=\"text\"></textarea>" "<input type=\"text\" name=\"test\">" "<input type=\"submit\" name=\"submit\" value=\"POST urlencoded\">" "</form>" "<p>\n"); onion_response_write0(res,"<form method=\"POST\" enctype=\"multipart/form-data\">" "<input type=\"file\" name=\"file\">" "<textarea name=\"text\"></textarea>" "<input type=\"text\" name=\"test\">" "<input type=\"submit\" name=\"submit\" value=\"POST multipart\">" "</form>" "<p>\n"); onion_response_write0(res,"</body></html>"); return OCS_PROCESSED; }
void extended_html__block_body(onion_dict *context, onion_response *res){ #line 1 #line 8 onion_response_write(res, "\n<h1>This is an extended template</h1>\n\n", 40); #line 8 { #line 8 void (*f)(onion_dict *context, onion_response *res); #line 8 f=(void*)onion_dict_get(context, "__block_body_in__"); #line 8 if (f) #line 8 f(context, res); #line 8 } #line 14 onion_response_write(res, "\n\nIf you see this, <span style=\"color: green;\">OK</span>.\n<br>\nRandom (only at test2): ", 87); #line 14 { #line 14 const char *tmp; #line 14 tmp=onion_dict_get(context, "random"); #line 14 if (tmp) #line 14 onion_response_write0(res, tmp); #line 14 } #line 19 onion_response_write(res, "\n<br>\n\nUnicode Chars: \342\202\254 \302\241 \303\241 \303\251 \303\255 \303\272 \303\263. \346\261\211\350\257\255/\346\274\242\350\252\236.\n\n", 61); #line 1 }
void t02_full_cycle_http10(){ INIT_LOCAL(); onion *server=onion_new(0); onion_add_listen_point(server,NULL,NULL,onion_buffer_listen_point_new()); onion_request *request; char buffer[4096]; memset(buffer,0,sizeof(buffer)); request=onion_request_new(server->listen_points[0]); onion_response *response=onion_response_new(request); onion_response_set_length(response, 30); FAIL_IF_NOT_EQUAL(response->length,30); onion_response_write_headers(response); onion_response_write0(response,"123456789012345678901234567890"); onion_response_flush(response); FAIL_IF_NOT_EQUAL(response->sent_bytes,30); onion_response_free(response); strncpy(buffer,onion_buffer_listen_point_get_buffer_data(request),sizeof(buffer)); onion_request_free(request); onion_free(server); FAIL_IF_NOT_STRSTR(buffer, "HTTP/1.0 200 OK\r\n"); FAIL_IF_NOT_STRSTR(buffer, "Connection: Keep-Alive\r\n"); FAIL_IF_NOT_STRSTR(buffer, "Content-Length: 30\r\n"); FAIL_IF_NOT_STRSTR(buffer, "Server: libonion"); FAIL_IF_NOT_STRSTR(buffer, "coralbits"); FAIL_IF_NOT_STRSTR(buffer, "\r\n\r\n123456789012345678901234567890"); END_LOCAL(); }
onion_connection_status process_request(void *_, onion_request *req, onion_response *res){ pthread_mutex_lock(&processed_mutex); processed++; pthread_mutex_unlock(&processed_mutex); onion_response_write0(res, "Done"); FAIL_IF_NOT_EQUAL_STR(onion_request_get_client_description(req),"127.0.0.1"); return OCS_PROCESSED; }
int hello(void *p, onion_request * req, onion_response * res) { //onion_response_set_length(res, 11); onion_response_write0(res, "Hello world"); if (onion_request_get_query(req, "1")) { onion_response_printf(res, "<p>Path: %s", onion_request_get_query(req, "1")); } onion_response_printf(res, "<p>Client description: %s", onion_request_get_client_description(req)); return OCS_PROCESSED; }
static onion_connection_status ask_session(void *_, onion_request *req, onion_response *res){ onion_dict *session=onion_request_get_session_dict(req); if (set_data_on_session) onion_dict_add(session,"Test","New data to create the session",0); has_set_cookie=0; onion_response_write0(res, "If I write before getting session, then there is no Set-Cookie.\n"); onion_response_printf(res, "%d elements at the session.\n", onion_dict_count(session)); ONION_DEBUG("Session ID is %s, cookies %s",req->session_id, onion_request_get_header(req, "Cookie")); strcpy(lastsessionid, req->session_id); return OCS_PROCESSED; }
onion_connection_status process_request(void *_, onion_request * req, onion_response * res) { onion_response_write0(res, "Done"); const onion_block *data = onion_request_get_data(req); FAIL_IF_NOT(data); FAIL_IF_NOT_EQUAL_STR(onion_block_data(data), "{\n \"a\": \"10\",\n \"b\": \"20\"\n}"); ONION_DEBUG(onion_block_data(data)); return OCS_PROCESSED; }
onion_connection_status sessions(void *ignore, onion_request *req){ onion_response *res=onion_response_new(req); onion_dict *session=onion_request_get_session_dict(req); if (onion_request_get_query(req, "reset")){ onion_request_session_free(req); onion_response_write0(res, "ok"); return onion_response_free(res); } const char *n=onion_dict_get(session, "count"); int count; if (n){ count=atoi(n)+1; } else count=0; char tmp[16]; snprintf(tmp,sizeof(tmp),"%d",count); onion_dict_add(session, "count", tmp, OD_DUP_ALL|OD_REPLACE); if (onion_response_write_headers(res)==OR_SKIP_CONTENT) // Head return onion_response_free(res); onion_response_write0(res, "<html><body>\n<h1>Session data</h1>\n"); if (session){ onion_response_printf(res,"<ul>\n"); onion_dict_preorder(session, print_dict_element, res); onion_response_printf(res,"</ul>\n"); } else{ onion_response_printf(res,"No session data"); } onion_response_write0(res,"</body></html>"); return onion_response_free(res); }
/** * @short Just asks the user for the answer. */ onion_connection_status ask_handler(void *none, onion_request *req, onion_response *res){ char temp[1024]; strcpy(temp, onion_request_get_path(req)); onion_dict_preorder(onion_request_get_query_dict(req),format_query,temp); char *resp=ask_question(temp); if (!resp) return OCS_INTERNAL_ERROR; onion_response_write0(res, resp); free(resp); return OCS_PROCESSED; }
int api_notification_list(ONION_FUNC_PROTO_STR) { const char * userid = onion_request_get_query(req, "userid"); const char * appkey = onion_request_get_query(req, "appkey"); const char * sessid = onion_request_get_query(req, "sessid"); if (userid == NULL || sessid == NULL || appkey == NULL) { return api_error(p, req, res, API_RT_WRONGPARAM); } struct userec *ue = getuser(userid); if (ue == 0) { return api_error(p, req, res, API_RT_NOSUCHUSER); } int r = check_user_session(ue, sessid, appkey); if (r != API_RT_SUCCESSFUL) { free(ue); return api_error(p, req, res, r); } struct json_object *obj = json_tokener_parse("{\"errcode\": 0, \"notifications\": []}"); struct json_object *noti_array = json_object_object_get(obj, "notifications"); NotifyItemList allNotifyItems = parse_notification(ue->userid); struct json_object * item = NULL; struct NotifyItem * currItem; struct boardmem *b; for (currItem = (struct NotifyItem *)allNotifyItems; currItem != NULL; currItem = currItem->next) { item = json_object_new_object(); json_object_object_add(item, "board", json_object_new_string(currItem->board)); json_object_object_add(item, "noti_time", json_object_new_int64(currItem->noti_time)); json_object_object_add(item, "from_userid", json_object_new_string(currItem->from_userid)); json_object_object_add(item, "title", json_object_new_string(currItem->title_utf)); json_object_object_add(item, "type", json_object_new_int(currItem->type)); b = getboardbyname(currItem->board); json_object_object_add(item, "secstr", json_object_new_string(b->header.sec1)); json_object_array_add(noti_array, item); } free_notification(allNotifyItems); api_set_json_header(res); onion_response_write0(res, json_object_to_json_string(obj)); json_object_put(obj); free(ue); return OCS_PROCESSED; }
void allinfo_query(allinfo_dict_print_t *aid, const char *key, const char *value, int flags){ onion_response *res=aid->res; onion_response_write0(res,aid->part); onion_response_write0(res,": "); onion_response_write0(res,key); onion_response_write0(res," = "); onion_response_write0(res,value); onion_response_write0(res,"\n"); }
//HTTP handler to forward http requests int forward(void *p, onion_request *req, onion_response *res){ if (onion_request_get_flags(req)&OR_GET){ printf("We got a GET. WOHOOOOOO!!!\n") } //Set header and type onion_response_set_header(res, "HTTP-Translator", "Forward that data"); onion_response_set_header(res, "Content-Type", "text/plain"); //Set example message onion_response_write0(res, "First try"); //Tell if everything worked properly return OCS_PROCESSED; }
/** * @short Main webdav handler, just redirects to the proper handler depending on headers and method */ onion_connection_status onion_webdav_handler(onion_webdav *wd, onion_request *req, onion_response *res){ onion_response_set_header(res, "Dav", "1,2"); onion_response_set_header(res, "MS-Author-Via", "DAV"); #ifdef __DEBUG__ const onion_block *data=onion_request_get_data(req); if (data){ ONION_DEBUG0("Have data!\n %s", onion_block_data(data)); } #endif char filename[512]; snprintf(filename, sizeof(filename), "%s/%s", wd->path, onion_request_get_path(req)); ONION_DEBUG("Check %s and %s", wd->path, filename); if (wd->check_permissions(wd->path, filename, req)!=0){ return onion_shortcut_response("Forbidden", HTTP_FORBIDDEN, req, res); } switch (onion_request_get_flags(req)&OR_METHODS){ case OR_GET: case OR_HEAD: return onion_webdav_get(filename, wd, req, res); case OR_OPTIONS: return onion_webdav_options(filename, wd, req, res); case OR_PROPFIND: return onion_webdav_propfind(filename, wd, req, res); case OR_PUT: return onion_webdav_put(filename, wd, req, res); case OR_DELETE: return onion_webdav_delete(filename, wd, req, res); case OR_MOVE: return onion_webdav_move(filename, wd, req, res); case OR_MKCOL: return onion_webdav_mkcol(filename, wd, req, res); case OR_PROPPATCH: return onion_webdav_proppatch(filename, wd, req, res); } onion_response_set_code(res, HTTP_NOT_IMPLEMENTED); onion_response_write0(res, "<h1>Work in progress...</h1>\n"); return OCS_PROCESSED; }
onion_connection_status websocket_example(void *data, onion_request *req, onion_response *res){ onion_websocket *ws=onion_websocket_new(req, res); if (!ws){ onion_response_write0(res, "<html><body><h1>Easy echo</h1><pre id=\"chat\"></pre>" " <script>\ninit = function(){\nmsg=document.getElementById('msg');\nmsg.focus();\n\nws=new WebSocket('ws://'+window.location.host);\nws.onmessage=function(ev){\n document.getElementById('chat').textContent+=ev.data+'\\n';\n};}\n" "window.addEventListener('load', init, false);\n</script>" "<input type=\"text\" id=\"msg\" onchange=\"javascript:ws.send(msg.value); msg.select(); msg.focus();\"/>\n" "</body></html>"); return OCS_PROCESSED; } onion_websocket_printf(ws,"Hello from server. Write something to echo it"); onion_websocket_set_callback(ws, websocket_example_cont); return OCS_WEBSOCKET; }
static int api_mail_get_content(ONION_FUNC_PROTO_STR, int mode) { const char * userid = onion_request_get_query(req, "userid"); const char * sessid = onion_request_get_query(req, "sessid"); const char * appkey = onion_request_get_query(req, "appkey"); const char * str_num = onion_request_get_query(req, "num"); const char * box_type = onion_request_get_query(req, "box_type"); if(!userid || !sessid || !appkey || !str_num) return api_error(p, req, res, API_RT_WRONGPARAM); struct userec * ue = getuser(userid); if(ue == 0) return api_error(p, req, res, API_RT_WRONGPARAM); if(check_user_session(ue, sessid, appkey) != API_RT_SUCCESSFUL) { free(ue); return api_error(p, req, res, API_RT_WRONGSESS); } char mail_dir[80]; struct fileheader fh; int box_type_i = (box_type != NULL && box_type[0] == '1') ? API_MAIL_SENT_BOX : API_MAIL_RECIEVE_BOX; if(box_type_i == API_MAIL_RECIEVE_BOX) setmailfile(mail_dir, ue->userid, ".DIR"); else setsentmailfile(mail_dir, ue->userid, ".DIR"); FILE *fp = fopen(mail_dir, "r"); if(fp==0) { free(ue); return api_error(p, req, res, API_RT_MAILINNERR); } int total = file_size_s(mail_dir) / sizeof(struct fileheader); int num = atoi(str_num); if(num<=0) num = 1; if(num>total) num = total; fseek(fp, (num-1)*sizeof(struct fileheader), SEEK_SET); if(fread(&fh, sizeof(fh), 1, fp) <= 0) { fclose(fp); free(ue); return api_error(p, req, res, API_RT_MAILINNERR); } fclose(fp); char title_utf[240]; g2u(fh.title, strlen(fh.title), title_utf, 240); struct attach_link *attach_link_list = NULL; char * mail_content_utf8 = parse_mail(ue->userid, fh.filetime, mode, &attach_link_list); if(!mail_content_utf8) { // 文件不存在 free(ue); free_attach_link_list(attach_link_list); return api_error(p, req, res, API_RT_MAILEMPTY); } char * mail_json_str = (char *)malloc(strlen(mail_content_utf8) + 512); if(!mail_json_str) { free(ue); free(mail_content_utf8); free_attach_link_list(attach_link_list); return api_error(p, req, res, API_RT_NOTENGMEM); } memset(mail_json_str, 0, strlen(mail_content_utf8)+512); sprintf(mail_json_str, "{\"errcode\": 0, \"attach\":[]}"); struct json_object * jp = json_tokener_parse(mail_json_str); if(!jp) { free(ue); free(mail_content_utf8); free_attach_link_list(attach_link_list); free(mail_json_str); return api_error(p, req, res, API_RT_NOTENGMEM); } json_object_object_add(jp, "content", json_object_new_string(mail_content_utf8)); json_object_object_add(jp, "title", json_object_new_string(title_utf)); if(attach_link_list) { struct json_object * attach_array = json_object_object_get(jp, "attach"); char at_buf[320]; struct attach_link * alp = attach_link_list; while(alp) { memset(at_buf, 0, 320); sprintf(at_buf, "{\"link\": \"%s\", \"size\": %d}", alp->link, alp->size); json_object_array_add(attach_array, json_tokener_parse(at_buf)); alp=alp->next; } } char * api_output = strdup(json_object_to_json_string(jp)); free(ue); free(mail_content_utf8); free_attach_link_list(attach_link_list); free(mail_json_str); json_object_put(jp); api_set_json_header(res); onion_response_write0(res, api_output); free(api_output); return OCS_PROCESSED; }
/** * @short Returns the directory listing */ int onion_handler_export_local_directory(onion_handler_export_local_data *data, const char *realp, const char *showpath, onion_request *req, onion_response *res){ DIR *dir=opendir(realp); if (!dir) // Continue on next. Quite probably a custom error. return 0; onion_response_set_header(res, "Content-Type", "text/html; charset=utf-8"); onion_response_write0(res,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" "<html>\n" " <head><meta content=\"text/html; charset=UTF-8\" http-equiv=\"content-type\"/>\n"); onion_response_printf(res,"<title>Directory listing of %s</title>\n",showpath); onion_response_write0(res,"</head>\n" " <body>\n" "<script>\n" "showListing = function(){\n" " var q = function(t){\n" " return t.replace('\"','%22')\n" " } \n" " var t=document.getElementById('filebody')\n" " while ( t.childNodes.length >= 1 )\n" " t.removeChild( t.firstChild ); \n" " for (var i=0;i<files.length;i++){\n" " var f=files[i]\n" " var h='<tr class=\"'+f[3]+'\"><td><a href=\"'+q(f[0])+'\">'+f[0]+'</a></td><td>'+f[1]+'</td><td>'+f[2]+'</td></tr>'\n" " t.innerHTML+=h\n" " }\n" "}\n" "\n" "update = function(n){\n" " var _cmp = function(a,b){\n" " if (a[n]<b[n])\n" " return -1\n" " if (a[n]>b[n])\n" " return 1\n" " return 0\n" " }\n" " files=files.sort(_cmp)\n" " showListing()\n" "}\n" "window.onload=function(){\n" " files=files.splice(0,files.length-1)\n" " update(0)\n" "}\n" "\n" "files=[\n"); struct dirent *fi; struct stat st; char temp[1024]; struct passwd *pwd; while ( (fi=readdir(dir)) != NULL ){ if (fi->d_name[0]=='.') continue; snprintf(temp,sizeof(temp),"%s/%s",realp,fi->d_name); stat(temp, &st); pwd=getpwuid(st.st_uid); if (S_ISDIR(st.st_mode)) onion_response_printf(res, " ['%s/',%d,'%s','dir'],\n",fi->d_name, st.st_size, pwd ? pwd->pw_name : "???"); else onion_response_printf(res, " ['%s',%d,'%s','file'],\n",fi->d_name, st.st_size, pwd ? pwd->pw_name : "???"); } onion_response_write0(res," [] ]\n</script>\n"); if (data->renderer_header) data->renderer_header(res, showpath); onion_response_write0(res,"<table id=\"filelist\">\n" "<thead><tr>\n" " <th onclick=\"update(0)\" id=\"filename\">Filename</th>\n" " <th onclick=\"update(1)\" id=\"size\">Size</th>" " <th onclick=\"update(2)\" id=\"owner\">Owner</th></tr>\n" "</thead>\n" "<tbody id=\"filebody\">\n</tbody>\n</table>\n</body>\n"); if (data->renderer_footer) data->renderer_footer(res, showpath); onion_response_write0(res,"</body></html>"); closedir(dir); return OCS_PROCESSED; }
void onion_handler_export_local_footer_default(onion_response *res, const char *dirname){ onion_response_write0(res,"<h2>Onion directory list. (C) 2010 <a href=\"http://www.coralbits.com\">CoralBits</a>. " "Under <a href=\"http://www.gnu.org/licenses/lgpl-3.0.html\">LGPL 3.0.</a> License.</h2>\n"); }
/// Footer that allows to upload files. void upload_file_footer(onion_response *res, const char *dirname){ onion_response_write0(res, "<p><table><tr><th>Upload a file: <form method=\"POST\" enctype=\"multipart/form-data\">" "<input type=\"file\" name=\"file\"><input type=\"submit\"><form></th></tr></table>"); onion_response_write0(res,"<h2>Onion minimal fileserver. (C) 2010 <a href=\"http://www.coralbits.com\">CoralBits</a>. " "Under <a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">AGPL 3.0.</a> License.</h2>\n"); }
int api_mail_list(ONION_FUNC_PROTO_STR) { const char * str_startnum = onion_request_get_query(req, "startnum"); const char * str_count = onion_request_get_query(req, "count"); const char * userid = onion_request_get_query(req, "userid"); const char * appkey = onion_request_get_query(req, "appkey"); const char * sessid = onion_request_get_query(req, "sessid"); const char * box_type = onion_request_get_query(req, "box_type"); if(!userid || !appkey || !sessid) return api_error(p, req, res, API_RT_WRONGPARAM); struct userec *ue = getuser(userid); if(!ue) return api_error(p, req, res, API_RT_NOSUCHUSER); int r = check_user_session(ue, sessid, appkey); if(r != API_RT_SUCCESSFUL) { free(ue); return api_error(p, req, res, r); } int startnum = (str_startnum) ? atoi(str_startnum) : 999999; int count = (str_count) ? atoi(str_count) : 20; char mail_dir[80]; int box_type_i = (box_type != NULL && box_type[0] == '1') ? API_MAIL_SENT_BOX : API_MAIL_RECIEVE_BOX; if(box_type_i == API_MAIL_RECIEVE_BOX) setmailfile(mail_dir, ue->userid, ".DIR"); else setsentmailfile(mail_dir, ue->userid, ".DIR"); int total = file_size_s(mail_dir) / sizeof(struct fileheader); if(!total) { free(ue); return api_error(p, req, res, API_RT_MAILEMPTY); } FILE *fp = fopen(mail_dir, "r"); if(fp==0) { free(ue); return api_error(p, req, res, API_RT_MAILDIRERR); } if(startnum == 0 || startnum > total-count+1) startnum = total - count + 1; if(startnum <= 0) startnum = 1; struct fileheader x; int i; struct bmy_article mail_list[count]; memset(mail_list, 0, sizeof(struct bmy_article) * count); fseek(fp, (startnum - 1) * sizeof(struct fileheader), SEEK_SET); for(i=0; i<count; ++i) { if(fread(&x, sizeof(x), 1, fp) <= 0) break; mail_list[i].sequence_num = i + startnum; mail_list[i].mark = x.accessed; strncpy(mail_list[i].author, fh2owner(&x), sizeof(mail_list[i].author)); mail_list[i].filetime = x.filetime; g2u(x.title, strlen(x.title), mail_list[i].title, sizeof(mail_list[i].title)); } fclose(fp); char *s = bmy_mail_array_to_json_string(mail_list, count, 0, ue); api_set_json_header(res); onion_response_write0(res, s); free(s); free(ue); return OCS_PROCESSED; }
/// Handles the write of static data static int onion_url_static(struct onion_url_static_data *data, onion_request *req, onion_response *res){ onion_response_set_code(res, data->code); onion_response_set_length(res, strlen(data->text)); onion_response_write0(res, data->text); return OCS_PROCESSED; }