static void http_client_loop(struct http_thread_env *hte)
{
	gchar *line = NULL;
	gsize nbyte = 0;
	HttpRequest *req = NULL;
	gint n;

	while ((n = getline(&line, &nbyte, hte->fp)) >= 0) {
		line[n] = '\0';
		if (n && line[n - 1] == '\n') line[--n] = '\0';
		if (n && line[n - 1] == '\r') line[--n] = '\0';

		if (n) mbb_log_lvl(MBB_LOG_HTTP, "recv: %s", line);

		if (req == NULL) {
			if ((req = http_request_new(line)) == NULL) {
				push_http_msg(hte, MBB_MSG_INVALID_HEADER, line);
				break;
			}

			if (! parse_url(req->url, &hte->json, &hte->method)) {
				push_http_error_msg(hte, "invalid url %s", req->url);
				break;
			}
		} else if (n) {
			if (http_request_add_header(req, line) == FALSE) {
				mbb_log_lvl(MBB_LOG_HTTP, "invalid header");
				push_http_msg(hte, MBB_MSG_INVALID_HEADER, line);
				break;
			}
		} else {
			if (req->method == HTTP_METHOD_POST) {
				if (process_http_body(hte, req) == FALSE)
					break;
			}

			process_http(hte, req);
			break;
		}
	}

	if (req != NULL)
		http_request_free(req);

	if (hte->root_tag != NULL) {
		xml_tag_free(hte->root_tag);
		hte->root_tag = NULL;
	}

	g_free(line);
}
Exemple #2
0
bool http_request_parse_header_line(HttpRequest* request, char* line) {
  char* line_start = line;
  HttpHeader* header = http_request_add_header(request);

  // See if we can tokenize the line. If not, bail.
  const char* key = trim(strsep(&line, ":"));
  if(!key) {
    set_error_message(request, "Error parsing HTTP header line %s", line_start);
    http_request_pop_header(request);
    return false;
  }

  // The value is the remainder of the line, trimmed
  const char* value = trim(line);

  // Store key and value
  http_header_set_key(header, key);
  http_header_set_value(header, value);
  return true;
}
/* Queue: pairing */
static int
send_pairing_request(struct remote_info *ri, char *req_uri, int family)
{
  struct http_connection *c;
  struct http_request *req;
  char *address;
  unsigned short port;
  int ret;

  switch (family)
    {
      case AF_INET:
	if (!ri->v4_address)
	  return -1;

	address = ri->v4_address;
	port = ri->v4_port;
	break;

      case AF_INET6:
	if (!ri->v6_address)
	  return -1;

	address = ri->v6_address;
	port = ri->v6_port;
	break;

      default:
	return -1;
    }

  c = http_client_new(L_REMOTE, address, port, pairing_fail_cb, pairing_free_cb, ri);
  if (!c)
    {
      DPRINTF(E_LOG, L_REMOTE, "Could not create HTTP client for pairing with %s\n", ri->pi.name);

      return -1;
    }

  req = http_client_request_new(HTTP_GET, P_VER_1_1, req_uri, pairing_request_cb);
  if (!req)
    {
      DPRINTF(E_WARN, L_REMOTE, "Could not create HTTP request for pairing\n");

      goto request_fail;
    }

  ret = http_request_add_header(req, "Connection", "close");
  if (ret < 0)
    DPRINTF(E_WARN, L_REMOTE, "Could not add Connection: close header\n");

  ret = http_client_request_run(c, req);
  if (ret < 0)
    {
      DPRINTF(E_WARN, L_REMOTE, "Could not run pairing request\n");

      goto run_fail;
    }

  return 0;

 run_fail:
  http_request_free(req);
 request_fail:
  http_client_free(c);

  return -1;
}