Пример #1
0
static void send_http_error(struct ezcfg_worker *worker, int status,
                            const char *reason, const char *fmt, ...)
{
	struct ezcfg_http *http;
	char buf[EZCFG_BUFFER_SIZE];
	va_list ap;
	int len;
	bool handled;

	http = (struct ezcfg_http *)ezcfg_worker_get_proto_data(worker);
	ezcfg_http_set_status_code(http, status);
	handled = http_error_handler(worker);

	if (handled == false) {
		buf[0] = '\0';
		len = 0;

		/* Errors 1xx, 204 and 304 MUST NOT send a body */
		if (status > 199 && status != 204 && status != 304) {
			len = snprintf(buf, sizeof(buf),
			               "Error %d: %s\n", status, reason);
			va_start(ap, fmt);
			len += vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
			va_end(ap);
			ezcfg_worker_set_num_bytes_sent(worker, len);
		}
		ezcfg_worker_printf(worker,
		              "HTTP/1.1 %d %s\r\n"
		              "Content-Type: text/plain\r\n"
		              "Content-Length: %d\r\n"
		              "Connection: close\r\n"
		              "\r\n%s", status, reason, len, buf);
	}
}
int
download_page(char** pg_ptr, int sock_des,
	      char* url_header, int url_header_sz){
  int ret; //Para guardar valores de retorno

  char* http_header = download_header(sock_des);

  //Recuperar código HTTP y manejarlo
  char http_code[3];
  http_code[0] = http_header[8 + 1];
  http_code[1] = http_header[8 + 2];
  http_code[2] = http_header[8 + 3];
  if (http_error_handler(http_code, url_header)){
    free(http_header);
    return 1;
  }

  /*Recuperar el tamaño de contenido de la respuesta HTTP*/
  regmatch_t* matches = (regmatch_t*)smalloc(sizeof(regmatch_t)*2);
  regex_t* cpattern = (regex_t*)smalloc(sizeof(regex_t));
  const char* length_pattern = "Content-Length: \([0-9]+\)";

  //Compilar la expresion regular
  ret = regcomp(cpattern,length_pattern,REG_EXTENDED);
  handle_regex_errors(ret);

  //Ejecutar la expresion regular
  ret = regexec(cpattern,http_header,2,matches,0);
  handle_regex_errors(ret);

  //Si se obtuvo el tamaño del contenido, reservar el espacio exacto
  if(ret != REG_NOMATCH){
    int length_start = matches[1].rm_so;
    int length_size =  matches[1].rm_eo - matches[1].rm_so;
    int clength = asciinum_to_int((http_header + length_start),
				  length_size);

    download_body_clength(sock_des, pg_ptr, clength,
			  url_header, url_header_sz);
  }
  //Si no se obtuvo el tamaño del contenido, descargar por bloques
  else{
    download_body_no_clength(sock_des, pg_ptr, 600,
			     url_header, url_header_sz);
  }


  regfree(cpattern);
  free(cpattern);
  free(matches);
  free(http_header);
  return 0;
}