Example #1
0
void Subscriber::close() {
    if(req->evcon) {
        evhttp_connection_set_closecb(req->evcon, NULL, NULL);
    }
    evhttp_send_reply_end(req);
    channel->serv->sub_end(this);
}
Example #2
0
static void
stream_end(struct stream_ctx *st, int failed)
{
  struct evhttp_connection *evcon;

  evcon = evhttp_request_get_connection(st->req);

  if (evcon)
    evhttp_connection_set_closecb(evcon, NULL, NULL);

  if (!failed)
    evhttp_send_reply_end(st->req);

  evbuffer_free(st->evbuf);
  event_free(st->ev);

  if (st->xcode)
    transcode_cleanup(st->xcode);
  else
    {
      free(st->buf);
      close(st->fd);
    }

#ifdef HAVE_LIBEVENT2_OLD
  if (g_st == st)
    g_st = NULL;
#endif

  free(st);
}
Example #3
0
/*
 * Stop reply to client
 * @return [nil]
 */
static VALUE t_send_reply_end(VALUE self) {
    Libevent_HttpRequest *http_request;

    Data_Get_Struct(self, Libevent_HttpRequest, http_request);
    evhttp_send_reply_end(http_request->ev_request);

    return Qnil;
}
Example #4
0
int Server::psub_end(PresenceSubscriber *psub){
	struct evhttp_request *req = psub->req;
	if(req->evcon){
		evhttp_connection_set_closecb(req->evcon, NULL, NULL);
	}
	evhttp_send_reply_end(req);
	psubs.remove(psub);
	log_info("%s:%d psub_end, psubs: %d", req->remote_host, req->remote_port, psubs.size);
	return 0;
}
bool HTTPHandler::finish(bool success, HTTPRequest *req, HTTPResponse *resp) {
  //TODO(binfei): libevent send reply
  if (func_ == NULL || req == NULL || resp == NULL)
    return false;

  evhttp_send_reply_chunk(resp->req_, resp->buffer_);
  evhttp_send_reply_end(resp->req_);

  delete req;
  delete resp;

  return true;
}
Example #6
0
void PendingResponseQueue::process() {
  // clean up the pipe for next signals
  char buf[512];
  if (read(m_ready.getOut(), buf, sizeof(buf)) < 0) {
    // an error occured but nothing we can really do
  }

  // making a copy so we don't hold up the mutex very long
  ResponsePtrVec responses;
  for (int i = 0; i < RuntimeOption::ResponseQueueCount; i++) {
    ResponseQueue &q = *m_responseQueues[i];
    Lock lock(q.m_mutex);
    responses.insert(responses.end(),
                     q.m_responses.begin(), q.m_responses.end());
    q.m_responses.clear();
  }

  for (unsigned int i = 0; i < responses.size(); i++) {
    Response &res = *responses[i];
    evhttp_request *request = res.request;
    int code = res.code;

    if (request->evcon == nullptr) {
      evhttp_request_free(request);
      continue;
    }

    bool skip_sync = false;
#ifdef _EVENT_USE_OPENSSL
    skip_sync = evhttp_is_connection_ssl(request->evcon);
#endif

    if (res.chunked) {
      if (res.chunk) {
        if (res.firstChunk) {
          const char *reason = HttpProtocol::GetReasonString(code);
          evhttp_send_reply_start(request, code, reason);
        }
        evhttp_send_reply_chunk(request, res.chunk);
      } else {
        evhttp_send_reply_end(request);
      }
    } else if (RuntimeOption::LibEventSyncSend && !skip_sync) {
      evhttp_send_reply_sync_end(res.nwritten, request);
    } else {
      const char *reason = HttpProtocol::GetReasonString(code);
      evhttp_send_reply(request, code, reason, nullptr);
    }
  }
}
void HTTPHandler::info_handle(struct evhttp_request *req, void *arg) {
  if (evhttp_request_get_command(req) != EVHTTP_REQ_GET)
    return;

  LOG(INFO) << "Request for server infomation.";

  // TODO(binfei): need memory pool
  struct evbuffer *databuf = evbuffer_new();
  evbuffer_add_printf(databuf, "hello world");
  evhttp_send_reply_start(req, 200, "OK");
  evhttp_send_reply_chunk(req, databuf);
  evhttp_send_reply_end(req);
  evbuffer_free(databuf);
}
//-----------------------------------------------------------------------------
void HTTPHandler::admin_handle(struct evhttp_request *req, void *arg) {
  //TODO(binfei): need ssl and sepecial command to do admin privilege
  LOG(INFO) << "Request for server admin.";
  // TODO(binfei): need memory pool
  struct evbuffer *databuf = evbuffer_new();
  evbuffer_add_printf(databuf, "Server will be stoped.");
  evhttp_send_reply_start(req, 200, "OK");
  evhttp_send_reply_chunk(req, databuf);
  evhttp_send_reply_end(req);
  evbuffer_free(databuf);
  
  HTTPServer *server = static_cast<HTTPServer*>(arg);
  server->Stop();
}
Example #9
0
/*
 * Send reply to client
 * @param [Fixnum] code HTTP code
 * @param [Hash] headers hash of http output headers
 * @param [Object] body object that response to each method that returns strings
 * @return [nil]
 */
static VALUE t_send_reply(VALUE self, VALUE code, VALUE headers, VALUE body) {
    Libevent_HttpRequest *http_request;

    Data_Get_Struct(self, Libevent_HttpRequest, http_request);
    Check_Type(code, T_FIXNUM);
    Check_Type(headers, T_HASH);

    t_set_output_headers(self, headers);

    evhttp_send_reply_start(http_request->ev_request, FIX2INT(code), NULL);
    rb_iterate(rb_each, body, t_send_chunk, self);
    evhttp_send_reply_end(http_request->ev_request);

    return Qnil;
}
void Subscriber::close(){
	log_debug("subscriber close invoked");
	if (req->evcon){
		evhttp_connection_set_closecb(req->evcon, NULL, NULL);
		log_debug("evhttp_connection_set_closecb invoked");
	}

	log_debug("before evhttp_send_reply_end");
	evhttp_send_reply_end(req);

	log_debug("before channel->serv->sub_end(this);");
	channel->serv->sub_end(this);
	log_debug("after channel->serv->sub_end(this);");
	
}
Example #11
0
static void
http_chunked_trickle_cb(int fd, short events, void *arg)
{
	struct evbuffer *evb = evbuffer_new();
	struct chunk_req_state *state = arg;
	struct timeval when = { 0, 0 };

	evbuffer_add_printf(evb, "%s", CHUNKS[state->i]);
	evhttp_send_reply_chunk(state->req, evb);
	evbuffer_free(evb);

	if (++state->i < sizeof(CHUNKS)/sizeof(CHUNKS[0])) {
		event_once(-1, EV_TIMEOUT,
		    http_chunked_trickle_cb, state, &when);
	} else {
		evhttp_send_reply_end(state->req);
		free(state);
	}
}
Example #12
0
void PendingResponseQueue::process() {
  // clean up the pipe for next signals
  char buf[512];
  read(m_ready.getOut(), buf, sizeof(buf));

  // making a copy so we don't hold up the mutex very long
  ResponsePtrVec responses;
  for (int i = 0; i < RuntimeOption::ResponseQueueCount; i++) {
    ResponseQueue &q = *m_responseQueues[i];
    Lock lock(q.m_mutex);
    responses.insert(responses.end(),q.m_responses.begin(),q.m_responses.end());
    q.m_responses.clear();
  }

  for (unsigned int i = 0; i < responses.size(); i++) {
    Response &res = *responses[i];
    evhttp_request *request = res.request;
    int code = res.code;

    if (res.chunked) {
      if (res.chunk) {
        if (res.firstChunk) {
          const char *reason = HttpProtocol::GetReasonString(code);
          evhttp_send_reply_start(request, code, reason);
        }
        evhttp_send_reply_chunk(request, res.chunk);
      } else {
        evhttp_send_reply_end(request);
      }
    } else if (RuntimeOption::LibEventSyncSend) {
      evhttp_send_reply_sync_end(res.nwritten, request);
    } else {
      const char *reason = HttpProtocol::GetReasonString(code);
      evhttp_send_reply(request, code, reason, NULL);
    }
  }
}
Example #13
0
static void http_handle_req(struct evhttp_request *req, lp_type longpoll, bool *req_valid)
{
	const char *clen_str;
	char *body_str;
	char username[65] = "";
	void *body, *reply = NULL;
	int clen = 0;
	unsigned int reply_len = 0;
	json_t *jreq;
	json_error_t jerr;
	bool rc;
	struct evbuffer *evbuf;

	if (!http_get_username(req, username, req->chunked))
 		return;

	if (longpoll == LP_NONE) {
		clen_str = evhttp_find_header(req->input_headers, "Content-Length");
		if (clen_str)
			clen = atoi(clen_str);
		if (clen < 1 || clen > 999999) {
			reqlog(req->remote_host, username, req->uri);
			goto err_out_bad_req;
		}

		if (EVBUFFER_LENGTH(req->input_buffer) != clen)
			goto err_out_bad_req;
		body = EVBUFFER_DATA(req->input_buffer);
		body_str = strndup(body, clen);
		if (!body_str)
			goto err_out_bad_req;
	} else if (longpoll == LP_REPLY) {
		body_str = strdup("{\"method\":\"getwork\",\"params\":[],\"id\":1}");
	} else if (longpoll == LP_KEEPALIVE || longpoll == LP_CLOSE) {
		reply = malloc(sizeof(char) * 2);
		if (!reply)
			goto err_out_bad_req;
		reply_len = snprintf(reply, 2, " ");
	}

	if (!reply) {
		jreq = JSON_LOADS(body_str, &jerr);

		free(body_str);

		if (!jreq)
			goto err_out_bad_req;

		rc = msg_json_rpc(req, jreq, username, &reply, &reply_len);

		json_decref(jreq);

		if (!rc)
			goto err_out_bad_req;
	}

	evbuf = evbuffer_new();
	if (!evbuf) {
		free(reply);
		goto err_out_bad_req;
	}
	if (evbuffer_add(evbuf, reply, reply_len)) {
		evbuffer_free(evbuf);
		free(reply);
		goto err_out_bad_req;
	}

	free(reply);

	/* req_valid is a pointer to the valid member of the list struct
	 * containing the LP request. When the connection drops and
	 * http_lp_close_cb is called, this bool is set to false. Because we
	 * have the reference, we can check before each send command if the
	 * close callback has been called or if the request is still OK.
	 *
	 * We only have to check this when sending chunked, because if we send
	 * in one go, there is nothing that could have closed the request, as
	 * we're single threaded. For now.
	 */
	if (longpoll == LP_NONE) {
		/* Send normal requests not chunked */
		evhttp_send_reply(req, HTTP_OK, "ok", evbuf);
	} else {
		if (!req->chunked && is_valid(req_valid))
			evhttp_send_reply_start(req, HTTP_OK, "ok");
		if (is_valid(req_valid))
			evhttp_send_reply_chunk(req, evbuf);
		if (longpoll != LP_KEEPALIVE && is_valid(req_valid))
			evhttp_send_reply_end(req);
	}

	evbuffer_free(evbuf);

	return;

err_out_bad_req:
	/* When we've already sent headers, we can't really give an error so
	 * we just send an empty reply...
	 */
	if (req->chunked) {
		if (is_valid(req_valid))
			evhttp_send_reply_end(req);
	} else {
		evhttp_send_reply(req, HTTP_BADREQUEST, "invalid args", NULL);
	}
}
Example #14
0
void handle_http_static(struct evhttp_request *req, void *arg){
	global_data * global = (global_data *) arg;

	struct evkeyvalq options;

	evhttp_parse_query(req->uri, &options);

	char filename[1000];
	filename[0] = '\0';

	strcat(filename, global->static_source);

//make sure it ends in / at this point
	if(filename[strlen(filename)-1] != '/')
		strcat(filename, "/");

	char * start = req->uri;
	if(*start == '/')
		++start;
	char * ptr = start;

	//look for the end of the string, end of the uri, or ..
	while(*ptr != '\0' && *ptr != '?' && !(*ptr == '.' && *(ptr+1) == '.')) 
		++ptr;

	if(*ptr == '\0'){
		strncat(filename, start, 1000 - (ptr - start) - strlen(filename));
	}else if(*ptr == '?'){
		strncat(filename, start, (ptr - start < (unsigned int)(1000 - strlen(filename)) ? ptr - start : 1000 - strlen(filename)) );
	}
	//if it included .. , just ignore the url altogether

//add index.html if it ends in / at this point
	if(filename[strlen(filename)-1] == '/')
		strcat(filename, "index.html");

	FILE *fd;
	char buf[4096];

	if((fd = fopen(filename, "r")) == NULL){
		struct evbuffer *evb;
		evb = evbuffer_new();
		evbuffer_add_printf(evb, "File Not found:  %s\n", req->uri);
		
		evhttp_send_reply(req, HTTP_NOTFOUND, "Not Found", evb);
		evbuffer_free(evb);
	}else{
		evhttp_send_reply_start(req, HTTP_OK, "OK");

		int len;
		struct evbuffer *evb;
		while((len = fread(buf, sizeof(char), 4096, fd))){
			evb = evbuffer_new();
			evbuffer_add(evb, buf, len);
		
			evhttp_send_reply_chunk(req, evb);
			evbuffer_free(evb);
		}

		evhttp_send_reply_end(req);
		
		fclose(fd);
	}
	evhttp_clear_headers(&options);
}
 static void HHVM_METHOD(EventHttpRequest, sendReplyEnd) {
     EventHttpRequestResourceData *event_http_request_resource_data = FETCH_RESOURCE(this_, EventHttpRequestResourceData, s_event_http_request);
     evhttp_send_reply_end((evhttp_request_t *) event_http_request_resource_data->getInternalResourceData());
 }
Example #16
0
void *cnode_run()
{
    int fd;                                  /* fd to Erlang node */
    int got;                                 /* Result of receive */
    unsigned char buf[BUFSIZE];              /* Buffer for incoming message */
    ErlMessage emsg;                         /* Incoming message */
 
    ETERM *uid, *msg;
 
    erl_init(NULL, 0);
 
    if (erl_connect_init(1, "secretcookie", 0) == -1)
        erl_err_quit("erl_connect_init");
 
    if ((fd = erl_connect("httpdmaster@localhost")) < 0)
        erl_err_quit("erl_connect");
 
    fprintf(stderr, "Connected to httpdmaster@localhost\n\r");
 
    struct evbuffer *evbuf;
 
    while (1) {
        got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
        if (got == ERL_TICK) {
            continue;
        } else if (got == ERL_ERROR) {
            fprintf(stderr, "ERL_ERROR from erl_receive_msg.\n");
            break;
        } else {
            if (emsg.type == ERL_REG_SEND) {
                fprintf(stderr, "type of emsg is ERL_REG_SEND\n");
                // get uid and body data from eg: {123, <<"Hello">>}
                uid = erl_element(1, emsg.msg);
                msg = erl_element(2, emsg.msg);
                char *token = (char *) ERL_BIN_PTR(uid);
                char *body = (char *) ERL_BIN_PTR(msg);
                int body_len = ERL_BIN_SIZE(msg);
                char *cached = fetch_memcached(token);
                int userid = atoi(cached);
                fprintf(stderr, "memc: %d\n\r", userid);
                if(clients[userid]){
                    fprintf(stderr, "Sending %d bytes to token %s\n", body_len, token);                
                    evbuf = evbuffer_new();
                    evbuffer_add(evbuf, (const void*)body, (size_t) body_len);
                    evhttp_send_reply_chunk(clients[userid], evbuf);
                    evhttp_send_reply_end(clients[userid]);
                    evbuffer_free(evbuf);
                }else{
                    fprintf(stderr, "Discarding %d bytes to uid %d - user not connected\n",
                            body_len, userid);                
                }
                free(cached);
                erl_free_term(emsg.msg);
                erl_free_term(uid);
                erl_free_term(msg);
            }
        }
        fprintf(stderr, ".");
    }
    pthread_exit(0);
}