Exemple #1
0
void *handle_connection(void *arg) {
  st_netfd_t client_nfd = (st_netfd_t)arg;
  struct http_stream *s = http_stream_create(HTTP_SERVER, SEC2USEC(10));
  char buf[4*1024];
  for (;;) {
    if (http_stream_request_read(s, client_nfd) < 0) break;
    http_request_debug_print(s->req, stderr);
    size_t total = 0;
    for (;;) {
      ssize_t nr = sizeof(buf);
      int status = http_stream_read(s, buf, &nr);
      fprintf(stderr, "http_stream_read nr: %zd\n", nr);
      if (nr < 0 || status != HTTP_STREAM_OK) { goto done; }
      if (nr == 0) break;
      /*fwrite(buf, sizeof(char), nr, stdout);*/
      total += nr;
    }
    fprintf(stderr, "http_stream_read total: %zu\n", total);

    http_response_clear(s->resp);
    s->resp->http_version = "HTTP/1.1";
    s->resp->status_code = 200;
    s->resp->reason = "OK";
    http_response_header_append(s->resp, "Content-type", "text/html");
    /*http_response_header_append(s->resp, "Connection", "close");*/
    http_response_set_body(s->resp, "<H2>It worked!</H2>");
    ssize_t nw = http_stream_response_send(s, 1);
    fprintf(stderr, "http_stream_response_send: %zd\n", nw);
    /* TODO: break loop if HTTP/1.0 and not keep-alive */
  }
done:
  fprintf(stderr, "exiting handle_connection\n");
  http_stream_close(s);
  return NULL;
}
Exemple #2
0
/* Simple error response */
void
http_send_error(struct http_client *c, short code, const char *msg) {

	struct http_response resp;
	http_response_init(&resp, code, msg);
	resp.http_version = c->http_version;
	http_response_set_connection_header(c, &resp);
	http_response_set_body(&resp, NULL, 0);

	http_response_write(&resp, c->fd);
	http_client_reset(c);
}
Exemple #3
0
/* Adobe flash cross-domain request */
void
http_crossdomain(struct http_client *c) {

	struct http_response resp;
	char out[] = "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n"
"<cross-domain-policy>\n"
  "<allow-access-from domain=\"*\" />\n"
"</cross-domain-policy>\n";

	http_response_init(&resp, 200, "OK");
	resp.http_version = c->http_version;
	http_response_set_connection_header(c, &resp);
	http_response_set_header(&resp, "Content-Type", "application/xml");
	http_response_set_body(&resp, out, sizeof(out)-1);

	http_response_write(&resp, c->fd);
	http_client_reset(c);
}
void webserver_send_response(ClientSocket*    client,
                             enum EHttpStatus status,
                             const char*      body,
                             const char*      content_type)
{
  // Build the Content-Length string
  char content_length[20] = {0};
  snprintf(content_length, 20, "%zu", (body ? strlen(body) : 0));
  if (!content_type) { content_type = "text/plain"; }

  // Build the response object
  HttpResponse* res = http_response_new();
  http_response_set_status(res, HTTP_VERSION_1_0, status);
  http_response_add_header(res, "Server", "webserver");
  http_response_add_header(res, "Content-Length", content_length);
  if (body) { http_response_add_header(res, "Content-Type", content_type); }
  if (body) { http_response_set_body(res, body); }

  // Send the response and clean up
  client_socket_send(client, http_response_string(res), http_response_length(res));
  http_response_free(res);
}
Exemple #5
0
void
format_send_reply(struct cmd *cmd, const char *p, size_t sz, const char *content_type) {

	int free_cmd = 1;
	const char *ct = cmd->mime?cmd->mime:content_type;
	struct http_response *resp;

	if(cmd->is_websocket) {
		ws_reply(cmd, p, sz);

		/* If it's a subscribe command, there'll be more responses */
		if(!cmd_is_subscribe(cmd))
			cmd_free(cmd);
		return;
	}

	if(cmd_is_subscribe(cmd)) {
		free_cmd = 0;

		/* start streaming */
		if(cmd->started_responding == 0) {
			cmd->started_responding = 1;
			resp = http_response_init(cmd->w, 200, "OK");
			resp->http_version = cmd->http_version;
			if(cmd->filename) {
				http_response_set_header(resp, "Content-Disposition", cmd->filename);
			}
			http_response_set_header(resp, "Content-Type", ct);
			http_response_set_keep_alive(resp, 1);
			http_response_set_header(resp, "Transfer-Encoding", "chunked");
			http_response_set_body(resp, p, sz);
			http_response_write(resp, cmd->fd);
		} else {
			/* Asynchronous chunk write. */
			http_response_write_chunk(cmd->fd, cmd->w, p, sz);
		}

	} else {
		/* compute ETag */
		char *etag = etag_new(p, sz);

		if(etag) {
			/* check If-None-Match */
			if(cmd->if_none_match && strcmp(cmd->if_none_match, etag) == 0) {
				/* SAME! send 304. */
				resp = http_response_init(cmd->w, 304, "Not Modified");
			} else {
				resp = http_response_init(cmd->w, 200, "OK");
				if(cmd->filename) {
					http_response_set_header(resp, "Content-Disposition", cmd->filename);
				}
				http_response_set_header(resp, "Content-Type", ct);
				http_response_set_header(resp, "ETag", etag);
				http_response_set_body(resp, p, sz);
			}
			resp->http_version = cmd->http_version;
			http_response_set_keep_alive(resp, cmd->keep_alive);
			http_response_write(resp, cmd->fd);
			free(etag);
		} else {
			format_send_error(cmd, 503, "Service Unavailable");
		}
	}
	
	/* cleanup */
	if(free_cmd) {
		cmd_free(cmd);
	}
}