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; }
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; }
/** * @short Gets a query data, but has a default value if the key is not there. * @memberof onion_request_t */ const char *onion_request_get_queryd(onion_request *req, const char *key, const char *def) { const char *ret; ret=onion_request_get_query(req,key); if (ret) return ret; return def; }
/// Gets the output data int oterm_out(process *o, onion_request *req, onion_response *res){ pthread_mutex_lock(&o->mutex); if (onion_request_get_query(req, "initial")){ if (o->buffer[BUFFER_SIZE-1]!=0){ // If 0 then never wrote on it. So if not, write from pos to end too, first. onion_response_write(res, &o->buffer[o->buffer_pos], BUFFER_SIZE-o->buffer_pos); } onion_response_write(res, o->buffer, o->buffer_pos); onion_response_printf(res, "\033]oterm;%d;", o->buffer_pos); onion_response_printf(res, "\033]url;https://localhost:8080/uuid/%s/;", o->uuid); pthread_mutex_unlock(&o->mutex); return OCS_PROCESSED; } int16_t p=atoi(onion_request_get_queryd(req, "pos", "0")); //o->buffer_pos; ONION_DEBUG("Wait for data at %d", p); while(p==o->buffer_pos) // We need it to be diferent, if not does not make sense to wake up pthread_cond_wait(&o->dataReady, &o->mutex); ONION_DEBUG("Data ready at %d (waiting from %d)", o->buffer_pos, p); if (o->buffer_pos<p){ onion_response_write(res, &o->buffer[p], BUFFER_SIZE-p); p=0; } onion_response_write(res, &o->buffer[p], o->buffer_pos-p); onion_response_printf(res, "\033]oterm;%d;", o->buffer_pos); pthread_mutex_unlock(&o->mutex); return OCS_PROCESSED; }
void t03_create_add_free_full_flow(){ INIT_LOCAL(); onion_request *req; int ok; req=onion_request_new(custom_io); FAIL_IF_EQUAL(req,NULL); FAIL_IF_NOT_EQUAL(req->connection.fd, -1); ok=REQ_WRITE(req,"GET /myurl%20/is/very/deeply/nested?test=test&query2=query%202&more_query=%20more%20query+10&empty&empty2 HTTP/1.0\n"); FAIL_IF_NOT(ok); ok=REQ_WRITE(req,"Host: 127.0.0.1\r\n"); FAIL_IF_NOT(ok); ok=REQ_WRITE(req,"Other-Header: My header is very long and with spaces...\n"); FAIL_IF_NOT(ok); ok=REQ_WRITE(req,"Final-Header: This header do not get into headers as a result of now knowing if its finished, or if its multiline.\n"); FAIL_IF_NOT(ok); FAIL_IF_EQUAL(req->flags,OR_GET|OR_HTTP11); FAIL_IF_EQUAL(req->headers, NULL); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->headers,"Host"), "127.0.0.1"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->headers,"Other-Header"), "My header is very long and with spaces..."); FAIL_IF_NOT_EQUAL_STR(req->fullpath,"/myurl /is/very/deeply/nested"); FAIL_IF_NOT_EQUAL(req->path,NULL); onion_request_process(req); // this should set the req->path. FAIL_IF_NOT_EQUAL_STR(req->path,"myurl /is/very/deeply/nested"); FAIL_IF_EQUAL(req->GET, NULL); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"test"), "test"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"query2"), "query 2"); FAIL_IF_NOT_EQUAL_STR( onion_dict_get(req->GET,"more_query"), " more query 10"); FAIL_IF_EQUAL(onion_request_get_query(req, "empty"), NULL); FAIL_IF_EQUAL(onion_request_get_query(req, "empty2"), NULL); FAIL_IF_NOT_EQUAL(onion_request_get_query(req, "empty3"), NULL); onion_request_free(req); END_LOCAL(); }
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); }
int api_notification_del(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); } const char * type = onion_request_get_query(req, "type"); const char * board = onion_request_get_query(req, "board"); const char * aid_str = onion_request_get_query(req, "aid"); if (type == NULL && (board == NULL || aid_str == 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); } if ((type != NULL) && (strcasecmp(type, "delall") == 0)) { del_all_notification(ue->userid); } else { del_post_notification(ue->userid, board, atoi(aid_str)); } free(ue); return api_error(p, req, res, API_RT_SUCCESSFUL); }
static int api_mail_do_post(ONION_FUNC_PROTO_STR, int mode) { 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 * token = onion_request_get_query(req, "token"); const char * to_userid = onion_request_get_query(req, "to_userid"); const char * title = onion_request_get_query(req, "title"); const char * backup = onion_request_get_query(req, "backup"); if(!userid || !appkey || !sessid || !title || !to_userid || !token) 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); struct userec currentuser; memcpy(¤tuser, ue, sizeof(currentuser)); free(ue); int r = check_user_session(¤tuser, sessid, appkey); if(r != API_RT_SUCCESSFUL) { return api_error(p, req, res, r); } if(HAS_PERM(PERM_DENYMAIL)) { return api_error(p, req, res, API_RT_MAILNOPPERM); } int uent_index = get_user_utmp_index(sessid); struct user_info *ui = &(shm_utmp->uinfo[uent_index]); if(strcmp(ui->token, token) != 0) { return api_error(p, req, res, API_RT_WRONGTOKEN); } // 更新 token 和来源 IP getrandomstr_r(ui->token, TOKENLENGTH+1); const char * fromhost = onion_request_get_header(req, "X-Real-IP"); memset(ui->from, 0, 20); strncpy(ui->from, fromhost, 20); if(check_user_maxmail(currentuser)) { return api_error(p, req, res, API_RT_MAILFULL); } struct userec *to_user = getuser(to_userid); if(!to_user) { return api_error(p, req, res, API_RT_NOSUCHUSER); } if(inoverride(currentuser.userid, to_user->userid, "rejects")) { free(to_user); return api_error(p, req, res, API_RT_INUSERBLIST); } const char * data = onion_request_get_post(req, "content"); char filename[80]; sprintf(filename, "bbstmpfs/tmp/%s_%s.tmp", currentuser.userid, ui->token); char * data2 = strdup(data); while(strstr(data2, "[ESC]") != NULL) data2 = string_replace(data2, "[ESC]", "\033"); char * data_gbk = (char *)malloc(strlen(data2)*2); u2g(data2, strlen(data2), data_gbk, strlen(data2)*2); f_write(filename, data_gbk); free(data2); int mark=0; // 文件标记 //if(insertattachments(filename, data_gbk, currentuser->userid)>0) //mark |= FH_ATTACHED; free(data_gbk); char * title_tmp = (char *)malloc(strlen(title)*2); u2g(title, strlen(title), title_tmp, strlen(title)*2); char title_gbk[80], title_tmp2[80]; strncpy(title_gbk, title_tmp[0]==0 ? "No Subject" : title_tmp, 80); snprintf(title_tmp2, 80, "{%s} %s", to_user->userid, title); free(title_tmp); r = do_mail_post(to_user->userid, title, filename, currentuser.userid, currentuser.username, fromhost, 0, mark); if(backup && strcasecmp(backup, "true")==0) { do_mail_post_to_sent_box(currentuser.userid, title_tmp2, filename, currentuser.userid, currentuser.username, fromhost, 0, mark); } unlink(filename); free(to_user); if(r<0) { return api_error(p, req, res, API_RT_MAILINNERR); } api_set_json_header(res); onion_response_printf(res, "{ \"errcode\":0, \"token\":\"%s\" }", ui->token); return OCS_PROCESSED; }
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; }
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; }