void Server::add_presence(PresenceType type, const std::string &cname){ if(psubs.empty()){ return; } struct evbuffer *buf = evbuffer_new(); evbuffer_add_printf(buf, "%d %s\n", type, cname.c_str()); LinkedList<PresenceSubscriber *>::Iterator it = psubs.iterator(); while(PresenceSubscriber *psub = it.next()){ evhttp_send_reply_chunk(psub->req, buf); //struct evbuffer *output = bufferevent_get_output(req->evcon->bufev); //if(evbuffer_get_length(output) > MAX_OUTPUT_BUFFER){ // close_presence_subscriber(); //} } evbuffer_free(buf); }
void evhtp_send_reply_chunk(evhtp_request_t * request, evbuf_t * buf) { evbuf_t * output; output = bufferevent_get_output(request->conn->bev); if (evbuffer_get_length(buf) == 0) { return; } if (request->chunked) { evbuffer_add_printf(output, "%x\r\n", (unsigned)evbuffer_get_length(buf)); } evhtp_send_reply_body(request, buf); if (request->chunked) { evbuffer_add(output, "\r\n", 2); } bufferevent_flush(request->conn->bev, EV_WRITE, BEV_FLUSH); }
static int launch_request(void) { evutil_socket_t sock; struct sockaddr_in sin; struct bufferevent *b; struct request_info *ri; memset(&sin, 0, sizeof(sin)); ++total_n_launched; sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(0x7f000001); sin.sin_port = htons(8080); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1; if (evutil_make_socket_nonblocking(sock) < 0) return -1; frob_socket(sock); if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) { int e = errno; if (! EVUTIL_ERR_CONNECT_RETRIABLE(e)) { return -1; } } ri = malloc(sizeof(*ri)); ri->n_read = 0; evutil_gettimeofday(&ri->started, NULL); b = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(b, readcb, NULL, errorcb, ri); bufferevent_enable(b, EV_READ|EV_WRITE); evbuffer_add_printf(bufferevent_get_output(b), "GET %s HTTP/1.0\r\n\r\n", resource); return 0; }
void SearchapiServiceClientEvhttp::searchHandler( struct evhttp_request *req, void *arg ) { SearchapiServiceClientEvhttp *instance = static_cast<SearchapiServiceClientEvhttp*>( arg ); struct evbuffer *buf; std::string result; buf = evbuffer_new(); if (buf) { struct evkeyvalq headers; TAILQ_INIT(&headers); std::cerr << std::string(req->uri) << std::endl; evhttp_parse_query(req->uri, &headers); std::string key = "q"; std::string val = ""; if (BBRpcClientEvhttp::find_header(&headers, key, val)) { char *escaped_val = evhttp_htmlescape(val.c_str()); std::cerr << escaped_val << std::endl; result = instance->search(escaped_val); evhttp_add_header(req->output_headers, "Content-type","application/x-javascript; charset=utf-8"); std::stringstream result_size; result_size << result.size(); evhttp_add_header(req->output_headers, "Content-Length", result_size.str().c_str()); evbuffer_add_printf(buf, "%s", result.c_str()); free(escaped_val); } else { std::cerr << "not find" << std::endl; } evhttp_clear_headers(&headers); evhttp_send_reply(req, HTTP_OK, "OK", buf); } else { std::cerr << "failed to create response buffer" << std::endl; } }
//--------------------------------------------------------------------------------------// static void basic_unauth(T R, const char *realm) { char *fmt = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n" " \"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\n" "<HTML>\n" " <HEAD>\n" " <TITLE>Error</TITLE>\n" " <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\">\n" " </HEAD>\n" " <BODY><H1>401 Unauthorised.</H1></BODY>\n" "</HTML>\n"; struct evbuffer *buf = evbuffer_new(); char *r = g_strdup_printf("Basic realm=\"%s\"", realm); evhttp_add_header(R->req->output_headers, "WWW-Authenticate", r); evbuffer_add_printf(buf,"%s", fmt); Request_send(R, 401, "UNAUTHORIZED", buf); evbuffer_free(buf); g_free(r); }
void writeHeader(evbuffer *pOutputBuffer, const char* sStatus, const char* sType, int nLength) { char Headers[]= "HTTP/1.1 %s\r\n" "Content-Type: %s\r\n" "Content-Length: %d\r\n" "Server: %s\r\n" "Connection: %s\r\n" "Date: %s\r\n\r\n"; const time_t timer = time(NULL); //std::cout << sStatus << "\n"; char time_buff[64]; getTime(time_buff); /*evbuffer_add_printf(output, headers, statusMessgae(s), t, len, SERVER, time_buff, CONNECTION);*/ /*evbuffer_add_printf(pOutputBuffer, Headers, sStatus, sType, nLength, SERVER_NAME, HEADER_CONNECTION, ctime(&timer));*/ evbuffer_add_printf(pOutputBuffer, Headers, sStatus, sType, nLength, SERVER_NAME, HEADER_CONNECTION, time_buff); }
int imap_handle_request(struct imap_context *ctx, struct imap_request *req) { struct bufferevent *bev = ctx->client_bev; struct evbuffer *output = bufferevent_get_output(bev); struct imap_handler h = { req->command.bv_val, NULL }; struct imap_handler *handler = avl_find(ctx->driver->commands, &h, imap_handler_cmp); if (handler == NULL) { skeeter_log(LOG_NOTICE, "No handler defined for command '%s'", req->command.bv_val); evbuffer_add_printf(output, "%s BAD Command %s unrecognized" CRLF, req->tag.bv_val, req->command.bv_val); return IMAP_OK; } if (handler->handler != NULL) { return handler->handler(ctx, req, handler->priv); } return IMAP_OK; }
/* Add window pane tabs. */ void format_window_pane_tabs(struct format_tree *ft, struct window_pane *wp) { struct evbuffer *buffer; u_int i; buffer = evbuffer_new(); for (i = 0; i < wp->base.grid->sx; i++) { if (!bit_test(wp->base.tabs, i)) continue; if (EVBUFFER_LENGTH(buffer) > 0) evbuffer_add(buffer, ",", 1); evbuffer_add_printf(buffer, "%d", i); } format_add(ft, "pane_tabs", "%.*s", (int) EVBUFFER_LENGTH(buffer), EVBUFFER_DATA(buffer)); evbuffer_free(buffer); }
void TS3::telnetEvent(bufferevent *bev, short event, void *parentPtr) { if (event & BEV_EVENT_CONNECTED) { LOG(INFO) << "Connected to TeamSpeak server"; } else if (event & BEV_EVENT_TIMEOUT) { bufferevent_enable(bev, EV_READ|EV_WRITE); evbuffer_add_printf(bufferevent_get_output(bev), "whoami\n"); } else if (event & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) { auto parent = static_cast<TS3*>(parentPtr); if (event & BEV_EVENT_ERROR) { int err = bufferevent_socket_get_dns_error(bev); if (err) LOG(ERROR) << "Can't connect to TeamSpeak server, DNS error: " << evutil_gai_strerror(err); } LOG(ERROR) << "TeamSpeak connection closed"; // FIXME needs a reliable restart mechanism, see thread parent->SendMessage("TS3 ServerQuery connection closed, fix me please"); bufferevent_free(bev); event_base_loopexit(parent->_base, nullptr); } }
static void flush_element(struct feed *feed) { char clean_player[128]; if (!feed->navi_sent) { send_navi(feed); feed->navi_sent = 1; } /* Sure, browsers deal with unescaped &'s in URLs just fine. * But our fancy unit... massive expat-using html-parsing test * thing is picky. */ amp_to_amp(clean_player, sizeof(clean_player), feed->fields[F_PLAYER]); evbuffer_add_printf(feed->sink, "<div class='entry'>\n" " <a href='%s'>\n" " <img src='%s' class='thumbnail'/>\n" " </a>\n" " <div class='info'>\n" " <p class='title'>\n" " <a href='%s'>%s</a>\n" " </p>\n" " <p class='uploader'>%s</p>\n" " <div class='dates'>\n" " <p>Last: %s</p>\n" " <p>First: %s</p>\n" " </div>\n" " </div>\n" "</div>\n", clean_player, feed->fields[F_THUMBNAIL], clean_player, feed->fields[F_TITLE], feed->fields[F_UPLOADER], feed->fields[F_UPDATED], feed->fields[F_PUBLISHED]); }
void cmd_load_buffer_callback(struct client *c, int closed, void *data) { int *buffer = data; char *pdata; size_t psize; u_int limit; if (!closed) return; c->stdin_callback = NULL; c->references--; if (c->flags & CLIENT_DEAD) return; psize = EVBUFFER_LENGTH(c->stdin_data); if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) { free(data); goto out; } memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize); pdata[psize] = '\0'; evbuffer_drain(c->stdin_data, psize); limit = options_get_number(&global_options, "buffer-limit"); if (*buffer == -1) paste_add(&global_buffers, pdata, psize, limit); else if (paste_replace(&global_buffers, *buffer, pdata, psize) != 0) { /* No context so can't use server_client_msg_error. */ evbuffer_add_printf(c->stderr_data, "no buffer %d\n", *buffer); server_push_stderr(c); free(pdata); } free(data); out: cmdq_continue(c->cmdq); }
void Server::requestHandler( evhttp_request* evRequest, void* serverPtr) { Server* server = (Server*)serverPtr; Request::TYPE type = Request::GET; if( evRequest->type != evhttp_cmd_type::EVHTTP_REQ_GET) type = Request::OTHER; std::string evUri = evRequest->uri; std::string uri = resm::UriHelper::removeDuplicateSlashes( evUri); Request request( type, uri); Response response = server->_httpRequestHandler.handle( request); evhttp_add_header( evRequest->output_headers, "Content-Type", "application/javascript; charset=utf-8"); // evhttp_add_header( request->output_headers, "Content-Type", "application/json; charset=utf-8"); auto *evResponse = evhttp_request_get_output_buffer( evRequest); if (!evResponse) return; evbuffer_add_printf( evResponse, "%s", response.getBody().c_str()); evhttp_send_reply( evRequest, response.getStatus(), response.getReason().c_str(), evResponse); }
int main(int argc, char** argv) { struct evbuffer* buff = NULL; char c, c2[3] = {0}; buff = evbuffer_new(); assert(buff != NULL); evbuffer_add(buff, "1", 1); evbuffer_add(buff, "2", 1); evbuffer_add(buff, "3", 1); evbuffer_add_printf(buff, "%d%d", 4, 5); assert(buff->off == 5); evbuffer_remove(buff, &c, sizeof(char)); assert(c == '1'); evbuffer_remove(buff, &c, sizeof(char)); assert(c == '2'); evbuffer_remove(buff, &c, sizeof(char)); assert(c == '3'); evbuffer_remove(buff, c2, 2); assert(strcmp(c2, "45") == 0); assert(buff->off == 0); evbuffer_add(buff, "test\r\n", 6); assert(buff->off == 6); char* line = evbuffer_readline(buff); assert(strcmp(line, "test") ==0); assert(buff->off == 0); free(line); evbuffer_free(buff); printf("ok\n"); return 0; }
void cmd_load_buffer_callback(struct client *c, int closed, void *data) { const char *bufname = data; char *pdata, *cause, *saved; size_t psize; if (!closed) return; c->stdin_callback = NULL; server_client_unref(c); if (c->flags & CLIENT_DEAD) return; psize = EVBUFFER_LENGTH(c->stdin_data); if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) goto out; memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize); pdata[psize] = '\0'; evbuffer_drain(c->stdin_data, psize); if (paste_set(pdata, psize, bufname, &cause) != 0) { /* No context so can't use server_client_msg_error. */ if (~c->flags & CLIENT_UTF8) { saved = cause; cause = utf8_sanitize(saved); free(saved); } evbuffer_add_printf(c->stderr_data, "%s", cause); server_client_push_stderr(c); free(pdata); free(cause); } out: cmdq_continue(c->cmdq); }
void send_file(evhtp_request_t* req, char* path) { struct stat st; unsigned char data[1024]; int fd; int n; evbuf_t* buf = NULL; if (stat(path, &st) < 0 || S_ISDIR(st.st_mode)) goto file_error; fd = open(path, O_RDONLY); if (fd < 0) goto file_error; buf = evbuffer_new(); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", guess_content_type(path), 0, 0)); evhtp_send_reply_chunk_start(req, EVHTP_RES_OK); do { n = read(fd, data, sizeof(data)); evbuffer_add(buf, data, n); evhtp_send_reply_chunk(req, buf); evbuffer_drain(buf, -1); } while (n > 0); close(fd); evhtp_send_reply_chunk_end(req); evbuffer_free(buf); return; file_error: evbuffer_add_printf(req->buffer_out, "ERROR:%s", path); evhtp_send_reply(req, EVHTP_RES_OK); }
void tr_http_escape( struct evbuffer * out, const char * str, int len, tr_bool escape_slashes ) { const char * end; if( ( len < 0 ) && ( str != NULL ) ) len = strlen( str ); for( end=str+len; str && str!=end; ++str ) { if( ( *str == ',' ) || ( *str == '-' ) || ( *str == '.' ) || ( ( '0' <= *str ) && ( *str <= '9' ) ) || ( ( 'A' <= *str ) && ( *str <= 'Z' ) ) || ( ( 'a' <= *str ) && ( *str <= 'z' ) ) || ( ( *str == '/' ) && ( !escape_slashes ) ) ) evbuffer_add( out, str, 1 ); else evbuffer_add_printf( out, "%%%02X", (unsigned)(*str&0xFF) ); } }
void Subscriber::send_old_msgs(){ std::vector<std::string>::iterator it = channel->msg_list.end(); int msg_seq_min = channel->seq_next - channel->msg_list.size(); if (Channel::SEQ_GT(this->seq_next, channel->seq_next) || Channel::SEQ_LT(this->seq_next, msg_seq_min)) { this->seq_next = msg_seq_min; } log_info("send old msg:[%d, %d]", this->seq_next, channel->seq_next - 1); it -= (channel->seq_next - this->seq_next); struct evbuffer *buf = evbuffer_new(); if (this->type == POLL){ if (!this->callback.empty()){ evbuffer_add_printf(buf, "%s(", this->callback.c_str()); } evbuffer_add_printf(buf, "["); for (; it != channel->msg_list.end(); it++, this->seq_next++) { std::string &msg = *it; evbuffer_add_printf(buf, "{\"type\":\"data\",\"cname\":\"%s\",\"seq\":%d,\"content\":\"%s\"}", this->channel->name.c_str(), this->channel->seq_next, msg.c_str()); if (this->seq_next != channel->seq_next - 1) { evbuffer_add(buf, ",", 1); } } evbuffer_add_printf(buf, "]"); if (!this->callback.empty()) { evbuffer_add_printf(buf, ");"); } evbuffer_add_printf(buf, "\n"); evhttp_send_reply_chunk(this->req, buf); this->close(); } else if (this->type == IFRAME || this->type == STREAM){ for (; it != channel->msg_list.end(); it++, this->seq_next++) { std::string &msg = *it; this->send_chunk(this->seq_next, "data", msg.c_str()); } } evbuffer_free(buf); }
void buf_read_callback(struct bufferevent *incomming, void *arg) { struct evbuffer *ev_return; char *req = NULL; struct client *client = (struct client*)arg; size_t input_length; int echo_enable = 1; printf("call buf_read_callback #sock:%d\n", client->fd); if (echo_enable) { // req = evbuffer_readline(incomming->input); req = evbuffer_readln(incomming->input, &input_length, EVBUFFER_EOL_ANY); if (req == NULL) { return; } printf("input data length = %ld\n", input_length); } // Allocate storage for a new evbuffer. ev_return = evbuffer_new(); if (echo_enable) { // Append a formatted string to the end of an evbuffer. evbuffer_add_printf(ev_return, "You said %s\n", req); } // Write data from an evbuffer to a bufferevent buffer. The evbuffer is // being drained as a result. printf("\t before call bufferevent_write_buffer <input:%p, output:%p>\n", incomming->input, incomming->output); bufferevent_write_buffer(incomming, ev_return); printf("\t after call bufferevent_write_buffer <input:%p, output:%p>\n", incomming->input, incomming->output); evbuffer_free(ev_return); free(req); }
static void get_log(struct evbuffer *rsps) { char *log = get_file_path("log"); FILE *fd = fopen(log, "r"); if (fd == NULL) return; int lines = get_line_count(fd); int start = lines - 50; if (start < 0) start = 0; int i; char buf[MAX_URL_LEN]; for (i = 0; i < start; i++) fgets(buf, MAX_URL_LEN, fd); while (fgets(buf, MAX_URL_LEN, fd) != NULL) evbuffer_add_printf(rsps, "%s", buf); fclose(fd); }
int Server::broadcast(struct evhttp_request *req){ if(evhttp_request_get_command(req) != EVHTTP_REQ_GET){ evhttp_send_reply(req, 405, "Invalid Method", NULL); return 0; } HttpQuery query(req); const char *content = query.get_str("content", ""); LinkedList<Channel *>::Iterator it = used_channels.iterator(); while(Channel *channel = it.next()){ if(channel->idle < ServerConfig::channel_idles){ channel->idle = ServerConfig::channel_idles; } channel->send("broadcast", content, false); } struct evbuffer *buf = evhttp_request_get_output_buffer(req); evbuffer_add_printf(buf, "ok\n"); evhttp_send_reply(req, 200, "OK", buf); return 0; }
static void handle_result_callback(struct site *site, void *arg) { struct evhttp_request *request = arg; struct evbuffer *data = evbuffer_new(); int done = site->flags & ANALYSIS_COMPLETE; /* XXX - do the right thing here */ evhttp_add_header(request->output_headers, "Content-Type", "text/xml"); evbuffer_add_printf(data, "<xmlresponse>" "<danger>%s</danger>" "<complete>%s</complete>" "</xmlresponse>", danger_to_text(site_analyze_danger(site)), done ? "complete" : "pending" ); evhttp_send_reply(request, HTTP_OK, "OK", data); evbuffer_free(data); }
/* Create the headers needed for an outgoing HTTP request, adds them to * the request's header list, and writes the request line to the * connection's output buffer. */ static void evhttp_make_header_request(struct evhttp_connection *evcon, struct evhttp_request *req) { const char *method; evhttp_remove_header(req->output_headers, "Proxy-Connection"); /* Generate request line */ method = evhttp_method(req->type); evbuffer_add_printf(bufferevent_get_output(evcon->bufev), "%s %s HTTP/%d.%d\r\n", method, req->uri, req->major, req->minor); /* Add the content length on a post or put request if missing */ if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) && evhttp_find_header(req->output_headers, "Content-Length") == NULL){ char size[22]; evutil_snprintf(size, sizeof(size), EV_SIZE_FMT, EV_SIZE_ARG(evbuffer_get_length(req->output_buffer))); evhttp_add_header(req->output_headers, "Content-Length", size); } }
void Subscriber::start() { bufferevent_enable(req->evcon->bufev, EV_READ); evhttp_connection_set_closecb(req->evcon, on_sub_disconnect, this); evhttp_add_header(req->output_headers, "Connection", "keep-alive"); //evhttp_add_header(req->output_headers, "Cache-Control", "no-cache"); //evhttp_add_header(req->output_headers, "Expires", "0"); evhttp_add_header(req->output_headers, "Content-Type", "text/html; charset=utf-8"); evhttp_send_reply_start(req, HTTP_OK, "OK"); if(this->type == POLL) { // } else if(this->type == IFRAME) { struct evbuffer *buf = evbuffer_new(); evbuffer_add_printf(buf, "%s\n", iframe_header.c_str()); evhttp_send_reply_chunk(this->req, buf); evbuffer_free(buf); } // send buffered messages if(!channel->msg_list.empty() && channel->seq_next != this->seq_next) { this->send_old_msgs(); } }
bool jw_httpsrv_set_next_response( jw_httpsrv httpsrv, int status_code, const char *body) { assert(httpsrv); if (0 != evbuffer_drain(httpsrv->next_body, evbuffer_get_length(httpsrv->next_body))) { jw_log(JW_LOG_WARN, "failed to drain response buffer"); return false; } if (0 > evbuffer_add_printf(httpsrv->next_body, "%s", body)) { jw_log(JW_LOG_WARN, "failed to write to response buffer"); return false; } httpsrv->next_status = status_code; httpsrv->use_custom_response = true; return true; }
void cm_getcell(evhtp_request_t *req, void *arg) { enum { err_param = -1, err_db = -2, }; int err = 0; int x = kvs_find_int32(&err, req->uri->query, "x"); int y = kvs_find_int32(&err, req->uri->query, "y"); if (err) { return cm_send_error(err_param, req); } if (x < 0 || x >= CELL_MAX || y < 0 || y >= CELL_MAX) { return cm_send_error(err_param, req); } redisContext *redis = cm_get_context()->redis; if (redis->err) { return cm_send_error(err_db, req); } // int blockX = x / CELLS_PER_BLOCK_SIDE; // int blockY = y / CELLS_PER_BLOCK_SIDE; // int idx = (y%CELLS_PER_BLOCK_SIDE)*CELLS_PER_BLOCK_SIDE+(x%CELLS_PER_BLOCK_SIDE); redisReply *reply = (redisReply*)redisCommand(redis, "HMGET cell:%d,%d text hp",x, y); Autofree _af_reply(reply, freeReplyObject); if (reply == NULL || reply->type != REDIS_REPLY_ARRAY || reply->elements != 2) { return cm_send_error(err_db, req); } const char *text = reply->element[0]->str; const char *hp = reply->element[1]->str; if (text == NULL || hp == NULL) { text = ""; hp = "0"; } evbuffer_add_printf(req->buffer_out, "{\"error\":0, \"text\":\"%s\", \"hp\":\"%s\"}", text, hp); evhtp_send_reply(req, EVHTP_RES_OK); }
void Subscriber::send_error_reply(int sub_type, struct evhttp_request *req, const char *cb, const std::string &cname, const char *type, const char *content){ struct evbuffer *buf = evbuffer_new(); if (sub_type == POLL){ evbuffer_add_printf(buf, "%s(", cb); } else if (sub_type == IFRAME){ evbuffer_add_printf(buf, "%s", iframe_chunk_prefix.c_str()); } evbuffer_add_printf(buf, "{\"type\":\"%s\",\"cname\":\"%s\",\"seq\":%d,\"content\":\"%s\"}", type, cname.c_str(), 0, content); if (sub_type == POLL){ evbuffer_add_printf(buf, ");"); } else if (sub_type == IFRAME){ evbuffer_add_printf(buf, "%s", iframe_chunk_suffix.c_str()); } evbuffer_add_printf(buf, "\n"); evhttp_send_reply(req, HTTP_OK, "OK", buf); evbuffer_free(buf); }
static char* announce_url_new (const tr_session * session, const tr_announce_request * req) { const char * str; const unsigned char * ipv6; struct evbuffer * buf = evbuffer_new (); char escaped_info_hash[SHA_DIGEST_LENGTH*3 + 1]; tr_http_escape_sha1 (escaped_info_hash, req->info_hash); evbuffer_expand (buf, 1024); evbuffer_add_printf (buf, "%s" "%c" "info_hash=%s" "&peer_id=%*.*s" "&port=%d" "&uploaded=%" PRIu64 "&downloaded=%" PRIu64 "&left=%" PRIu64 "&numwant=%d" "&key=%x" "&compact=1" "&supportcrypto=1", req->url, strchr (req->url, '?') ? '&' : '?', escaped_info_hash, PEER_ID_LEN, PEER_ID_LEN, req->peer_id, req->port, req->up, req->down, req->leftUntilComplete, req->numwant, req->key); if (session->encryptionMode == TR_ENCRYPTION_REQUIRED) evbuffer_add_printf (buf, "&requirecrypto=1"); if (req->corrupt) evbuffer_add_printf (buf, "&corrupt=%" PRIu64, req->corrupt); str = get_event_string (req); if (str && *str) evbuffer_add_printf (buf, "&event=%s", str); str = req->tracker_id_str; if (str && *str) evbuffer_add_printf (buf, "&trackerid=%s", str); /* There are two incompatible techniques for announcing an IPv6 address. BEP-7 suggests adding an "ipv6=" parameter to the announce URL, while OpenTracker requires that peers announce twice, once over IPv4 and once over IPv6. To be safe, we should do both: add the "ipv6=" parameter and announce twice. At any rate, we're already computing our IPv6 address (for the LTEP handshake), so this comes for free. */ ipv6 = tr_globalIPv6 (); if (ipv6) { char ipv6_readable[INET6_ADDRSTRLEN]; evutil_inet_ntop (AF_INET6, ipv6, ipv6_readable, INET6_ADDRSTRLEN); evbuffer_add_printf (buf, "&ipv6="); tr_http_escape (buf, ipv6_readable, -1, true); } return evbuffer_free_to_str (buf); }
static void saveIntFunc (const tr_variant * val, void * evbuf) { evbuffer_add_printf (evbuf, "i%" PRId64 "e", val->val.i); }
/* 处理模块 */ void synchttp_handler(struct evhttp_request *req, void *arg) { struct evbuffer *buf; buf = evbuffer_new(); /* 分析URL参数 */ char *decode_uri = strdup((char*) evhttp_request_uri(req)); struct evkeyvalq synchttp_http_query; evhttp_parse_query(decode_uri, &synchttp_http_query); free(decode_uri); /* 接收GET表单参数 */ const char *synchttp_input_charset = evhttp_find_header(&synchttp_http_query, "charset"); /* 编码方式 */ const char *synchttp_input_data = evhttp_find_header(&synchttp_http_query, "data"); /* 数据 */ const char *synchttp_input_auth = evhttp_find_header(&synchttp_http_query, "auth"); /* 验证密码 */ /* 返回给用户的Header头信息 */ if (synchttp_input_charset != NULL && strlen(synchttp_input_charset) <= 40) { char content_type[64] = { 0x00 }; sprintf(content_type, "text/plain; charset=%s", synchttp_input_charset); evhttp_add_header(req->output_headers, "Content-Type", content_type); } else { evhttp_add_header(req->output_headers, "Content-Type", "text/plain"); } evhttp_add_header(req->output_headers, "Connection", "keep-alive"); evhttp_add_header(req->output_headers, "Cache-Control", "no-cache"); /* 权限校验 */ bool is_auth_pass = false; /* 是否验证通过 */ if (synchttp_settings_auth != NULL) { /* 如果命令行启动参数设置了验证密码 */ if (synchttp_input_auth != NULL && strcmp(synchttp_settings_auth, synchttp_input_auth) == 0) { is_auth_pass = true; } else { is_auth_pass = false; } } else { /* 如果命令行启动参数没有设置验证密码 */ is_auth_pass = true; } if (is_auth_pass == false) { /* 校验失败 */ evbuffer_add_printf(buf, "%s", "SYNCHTTP_AUTH_FAILED"); goto output; } int now_putpos = synchttp_now_putpos(); if(now_putpos > SYNCHTTP_DEFAULT_MAXQUEUE){ evbuffer_add_printf(buf, "%s", "SYNCHTTP_PUT_FULL"); goto output; } int buffer_data_len; char queue_name[32] = { 0x00 }; sprintf(queue_name,"Q:%d", now_putpos); /*请求消息入库*/ char *synchttp_input_buffer; char *buffer_data; if (synchttp_input_data != NULL) { /*GET请求*/ buffer_data_len = strlen(synchttp_input_data); buffer_data = (char *) tccalloc(1, buffer_data_len + 3); memcpy(buffer_data, synchttp_input_data, buffer_data_len); strcat(buffer_data, "#1"); } else { /*POST请求*/ buffer_data_len = EVBUFFER_LENGTH(req->input_buffer); buffer_data = (char *) tccalloc(1, buffer_data_len + 3); memcpy(buffer_data, EVBUFFER_DATA(req->input_buffer), buffer_data_len); strcat(buffer_data, "#2"); } synchttp_input_buffer = urldecode(buffer_data); /*参数是否存在判断 */ if (strlen(synchttp_input_buffer) < 3){ /* 参数错误 */ evbuffer_add_printf(buf, "%s", "SYNCHTTP_ERROR"); goto output; } if(tcbdbput2(synchttp_db_tcbdb, queue_name, synchttp_input_buffer) == true){ fprintf(stderr, "in:%s--->%s\n", queue_name, synchttp_input_buffer); }else{ evbuffer_add_printf(buf, "%s", "SYNCHTTP_ERROR"); goto output; } evbuffer_add_printf(buf, "%s", "SYNCHTTP_SET_OK"); free(synchttp_input_buffer); free(buffer_data); output: /* 输出内容给客户端 */ evhttp_send_reply(req, HTTP_OK, "OK", buf); /* 内存释放 */ evhttp_clear_headers(&synchttp_http_query); evbuffer_free(buf); }
static void handle_upload (struct evhttp_request * req, struct tr_rpc_server * server) { if (req->type != EVHTTP_REQ_POST) { send_simple_response (req, 405, NULL); } else { int i; int n; bool hasSessionId = false; tr_ptrArray parts = TR_PTR_ARRAY_INIT; const char * query = strchr (req->uri, '?'); const bool paused = query && strstr (query + 1, "paused=true"); extract_parts_from_multipart (req->input_headers, req->input_buffer, &parts); n = tr_ptrArraySize (&parts); /* first look for the session id */ for (i=0; i<n; ++i) { struct tr_mimepart * p = tr_ptrArrayNth (&parts, i); if (tr_memmem (p->headers, p->headers_len, TR_RPC_SESSION_ID_HEADER, strlen (TR_RPC_SESSION_ID_HEADER))) break; } if (i<n) { const struct tr_mimepart * p = tr_ptrArrayNth (&parts, i); const char * ours = get_current_session_id (server); const size_t ourlen = strlen (ours); hasSessionId = ourlen <= p->body_len && memcmp (p->body, ours, ourlen) == 0; } if (!hasSessionId) { int code = 409; const char * codetext = tr_webGetResponseStr (code); struct evbuffer * body = evbuffer_new (); evbuffer_add_printf (body, "%s", "{ \"success\": false, \"msg\": \"Bad Session-Id\" }");; evhttp_send_reply (req, code, codetext, body); evbuffer_free (body); } else for (i=0; i<n; ++i) { struct tr_mimepart * p = tr_ptrArrayNth (&parts, i); size_t body_len = p->body_len; tr_variant top, *args; tr_variant test; bool have_source = false; char * body = p->body; if (body_len >= 2 && memcmp (&body[body_len - 2], "\r\n", 2) == 0) body_len -= 2; tr_variantInitDict (&top, 2); tr_variantDictAddStr (&top, TR_KEY_method, "torrent-add"); args = tr_variantDictAddDict (&top, TR_KEY_arguments, 2); tr_variantDictAddBool (args, TR_KEY_paused, paused); if (tr_urlIsValid (body, body_len)) { tr_variantDictAddRaw (args, TR_KEY_filename, body, body_len); have_source = true; } else if (!tr_variantFromBenc (&test, body, body_len)) { char * b64 = tr_base64_encode (body, body_len, NULL); tr_variantDictAddStr (args, TR_KEY_metainfo, b64); tr_free (b64); have_source = true; } if (have_source) tr_rpc_request_exec_json (server->session, &top, NULL, NULL); tr_variantFree (&top); } tr_ptrArrayDestruct (&parts, (PtrArrayForeachFunc)tr_mimepart_free); /* send "success" response */ { int code = HTTP_OK; const char * codetext = tr_webGetResponseStr (code); struct evbuffer * body = evbuffer_new (); evbuffer_add_printf (body, "%s", "{ \"success\": true, \"msg\": \"Torrent Added\" }");; evhttp_send_reply (req, code, codetext, body); evbuffer_free (body); } } }