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; }