Added BoringSSL - replacement for OpenSSL, updated libcurl to use boringssl

This commit is contained in:
Sergii Pylypenko
2016-04-04 21:09:43 +03:00
parent 3f4f642d9f
commit 9fba98e5ab
364 changed files with 91224 additions and 29310 deletions

View File

@@ -5,11 +5,11 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
@@ -20,33 +20,13 @@
*
***************************************************************************/
#include "setup.h"
#include "curl_setup.h"
#ifndef CURL_DISABLE_FILE
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef WIN32
#include <time.h>
#include <io.h>
#include <fcntl.h>
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
@@ -68,8 +48,6 @@
#include <fcntl.h>
#endif
#endif /* WIN32 */
#include "strtoofft.h"
#include "urldata.h"
#include <curl/curl.h>
@@ -81,16 +59,16 @@
#include "getinfo.h"
#include "transfer.h"
#include "url.h"
#include "curl_memory.h"
#include "parsedate.h" /* for the week day and month names */
#include "warnless.h"
#include "curl_printf.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
/* The last #include files should be: */
#include "curl_memory.h"
#include "memdebug.h"
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || defined(__SYMBIAN32__)
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
defined(__SYMBIAN32__)
#define DOS_FILESYSTEM 1
#endif
@@ -108,6 +86,9 @@ static CURLcode file_do(struct connectdata *, bool *done);
static CURLcode file_done(struct connectdata *conn,
CURLcode status, bool premature);
static CURLcode file_connect(struct connectdata *conn, bool *done);
static CURLcode file_disconnect(struct connectdata *conn,
bool dead_connection);
static CURLcode file_setup_connection(struct connectdata *conn);
/*
* FILE scheme handler.
@@ -115,7 +96,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done);
const struct Curl_handler Curl_handler_file = {
"FILE", /* scheme */
ZERO_NULL, /* setup_connection */
file_setup_connection, /* setup_connection */
file_do, /* do_it */
file_done, /* done */
ZERO_NULL, /* do_more */
@@ -124,13 +105,26 @@ const struct Curl_handler Curl_handler_file = {
ZERO_NULL, /* doing */
ZERO_NULL, /* proto_getsock */
ZERO_NULL, /* doing_getsock */
ZERO_NULL, /* domore_getsock */
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
file_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
0, /* defport */
PROT_FILE /* protocol */
CURLPROTO_FILE, /* protocol */
PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
};
static CURLcode file_setup_connection(struct connectdata *conn)
{
/* allocate the FILE specific struct */
conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
if(!conn->data->req.protop)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
/*
Check if this is a range download, and if so, set the internal variables
properly. This code is copied from the FTP implementation and might as
@@ -156,14 +150,14 @@ static CURLcode file_range(struct connectdata *conn)
if((-1 == to) && (from>=0)) {
/* X - */
data->state.resume_from = from;
DEBUGF(infof(data, "RANGE %" FORMAT_OFF_T " to end of file\n",
DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
from));
}
else if(from < 0) {
/* -Y */
data->req.maxdownload = -from;
data->state.resume_from = from;
DEBUGF(infof(data, "RANGE the last %" FORMAT_OFF_T " bytes\n",
DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
-from));
}
else {
@@ -171,12 +165,13 @@ static CURLcode file_range(struct connectdata *conn)
totalsize = to-from;
data->req.maxdownload = totalsize+1; /* include last byte */
data->state.resume_from = from;
DEBUGF(infof(data, "RANGE from %" FORMAT_OFF_T
" getting %" FORMAT_OFF_T " bytes\n",
DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
" getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
from, data->req.maxdownload));
}
DEBUGF(infof(data, "range-download from %" FORMAT_OFF_T
" to %" FORMAT_OFF_T ", totally %" FORMAT_OFF_T " bytes\n",
DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
" to %" CURL_FORMAT_CURL_OFF_T ", totally %"
CURL_FORMAT_CURL_OFF_T " bytes\n",
from, to, data->req.maxdownload));
}
else
@@ -192,40 +187,19 @@ static CURLcode file_range(struct connectdata *conn)
static CURLcode file_connect(struct connectdata *conn, bool *done)
{
struct SessionHandle *data = conn->data;
char *real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
struct FILEPROTO *file;
char *real_path;
struct FILEPROTO *file = data->req.protop;
int fd;
#ifdef DOS_FILESYSTEM
int i;
char *actual_path;
#endif
int real_path_len;
real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
if(!real_path)
return CURLE_OUT_OF_MEMORY;
/* If there already is a protocol-specific struct allocated for this
sessionhandle, deal with it */
Curl_reset_reqproto(conn);
if(!data->state.proto.file) {
file = calloc(1, sizeof(struct FILEPROTO));
if(!file) {
free(real_path);
return CURLE_OUT_OF_MEMORY;
}
data->state.proto.file = file;
}
else {
/* file is not a protocol that can deal with "persistancy" */
file = data->state.proto.file;
Curl_safefree(file->freepath);
if(file->fd != -1)
close(file->fd);
file->path = NULL;
file->freepath = NULL;
file->fd = -1;
}
#ifdef DOS_FILESYSTEM
/* If the first character is a slash, and there's
something that looks like a drive at the beginning of
@@ -244,20 +218,26 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
actual_path = real_path;
if((actual_path[0] == '/') &&
actual_path[1] &&
(actual_path[2] == ':' || actual_path[2] == '|'))
{
(actual_path[2] == ':' || actual_path[2] == '|')) {
actual_path[2] = ':';
actual_path++;
real_path_len--;
}
/* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
for (i=0; actual_path[i] != '\0'; ++i)
for(i=0; i < real_path_len; ++i)
if(actual_path[i] == '/')
actual_path[i] = '\\';
else if(!actual_path[i]) /* binary zero */
return CURLE_URL_MALFORMAT;
fd = open_readonly(actual_path, O_RDONLY|O_BINARY); /* no CR/LF translation */
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
file->path = actual_path;
#else
if(memchr(real_path, 0, real_path_len))
/* binary zeroes indicate foul play */
return CURLE_URL_MALFORMAT;
fd = open_readonly(real_path, O_RDONLY);
file->path = real_path;
#endif
@@ -277,13 +257,34 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
static CURLcode file_done(struct connectdata *conn,
CURLcode status, bool premature)
{
struct FILEPROTO *file = conn->data->state.proto.file;
struct FILEPROTO *file = conn->data->req.protop;
(void)status; /* not used */
(void)premature; /* not used */
Curl_safefree(file->freepath);
if(file->fd != -1)
close(file->fd);
if(file) {
Curl_safefree(file->freepath);
file->path = NULL;
if(file->fd != -1)
close(file->fd);
file->fd = -1;
}
return CURLE_OK;
}
static CURLcode file_disconnect(struct connectdata *conn,
bool dead_connection)
{
struct FILEPROTO *file = conn->data->req.protop;
(void)dead_connection; /* not used */
if(file) {
Curl_safefree(file->freepath);
file->path = NULL;
if(file->fd != -1)
close(file->fd);
file->fd = -1;
}
return CURLE_OK;
}
@@ -296,10 +297,11 @@ static CURLcode file_done(struct connectdata *conn,
static CURLcode file_upload(struct connectdata *conn)
{
struct FILEPROTO *file = conn->data->state.proto.file;
struct FILEPROTO *file = conn->data->req.protop;
const char *dir = strchr(file->path, DIRSEP);
FILE *fp;
CURLcode res=CURLE_OK;
int fd;
int mode;
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *buf = data->state.buffer;
size_t nread;
@@ -313,49 +315,39 @@ static CURLcode file_upload(struct connectdata *conn)
* Since FILE: doesn't do the full init, we need to provide some extra
* assignments here.
*/
conn->fread_func = data->set.fread_func;
conn->fread_in = data->set.in;
conn->data->req.upload_fromhere = buf;
if(!dir)
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
if(!dir[1])
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
#ifdef O_BINARY
#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY
#else
#define MODE_DEFAULT O_WRONLY|O_CREAT
#endif
if(data->state.resume_from)
fp = fopen( file->path, "ab" );
else {
int fd;
mode = MODE_DEFAULT|O_APPEND;
else
mode = MODE_DEFAULT|O_TRUNC;
#ifdef DOS_FILESYSTEM
fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
conn->data->set.new_file_perms);
#else
fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC,
conn->data->set.new_file_perms);
#endif
if(fd < 0) {
failf(data, "Can't open %s for writing", file->path);
return CURLE_WRITE_ERROR;
}
close(fd);
fp = fopen(file->path, "wb");
}
if(!fp) {
fd = open(file->path, mode, conn->data->set.new_file_perms);
if(fd < 0) {
failf(data, "Can't open %s for writing", file->path);
return CURLE_WRITE_ERROR;
}
if(-1 != data->set.infilesize)
if(-1 != data->state.infilesize)
/* known size of data to "upload" */
Curl_pgrsSetUploadSize(data, data->set.infilesize);
Curl_pgrsSetUploadSize(data, data->state.infilesize);
/* treat the negative resume offset value as the case of "-" */
if(data->state.resume_from < 0) {
if(fstat(fileno(fp), &file_stat)) {
fclose(fp);
if(fstat(fd, &file_stat)) {
close(fd);
failf(data, "Can't get the size of %s", file->path);
return CURLE_WRITE_ERROR;
}
@@ -363,10 +355,10 @@ static CURLcode file_upload(struct connectdata *conn)
data->state.resume_from = (curl_off_t)file_stat.st_size;
}
while(res == CURLE_OK) {
while(!result) {
int readcount;
res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
if(res)
result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
if(result)
break;
if(readcount <= 0) /* fix questionable compare error. curlvms */
@@ -376,7 +368,7 @@ static CURLcode file_upload(struct connectdata *conn)
/*skip bytes before resume point*/
if(data->state.resume_from) {
if( (curl_off_t)nread <= data->state.resume_from ) {
if((curl_off_t)nread <= data->state.resume_from ) {
data->state.resume_from -= nread;
nread = 0;
buf2 = buf;
@@ -391,9 +383,9 @@ static CURLcode file_upload(struct connectdata *conn)
buf2 = buf;
/* write the data to the target */
nwrite = fwrite(buf2, 1, nread, fp);
nwrite = write(fd, buf2, nread);
if(nwrite != nread) {
res = CURLE_SEND_ERROR;
result = CURLE_SEND_ERROR;
break;
}
@@ -402,16 +394,16 @@ static CURLcode file_upload(struct connectdata *conn)
Curl_pgrsSetUploadCounter(data, bytecount);
if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
result = CURLE_ABORTED_BY_CALLBACK;
else
res = Curl_speedcheck(data, now);
result = Curl_speedcheck(data, now);
}
if(!res && Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
if(!result && Curl_pgrsUpdate(conn))
result = CURLE_ABORTED_BY_CALLBACK;
fclose(fp);
close(fd);
return res;
return result;
}
/*
@@ -429,19 +421,20 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
are supported. This means that files on remotely mounted directories
(via NFS, Samba, NT sharing) can be accessed through a file:// URL
*/
CURLcode res = CURLE_OK;
CURLcode result = CURLE_OK;
struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
Windows version to have a different struct without
having to redefine the simple word 'stat' */
curl_off_t expected_size=0;
bool size_known;
bool fstated=FALSE;
ssize_t nread;
size_t bytestoread;
struct SessionHandle *data = conn->data;
char *buf = data->state.buffer;
curl_off_t bytecount = 0;
int fd;
struct timeval now = Curl_tvnow();
struct FILEPROTO *file;
*done = TRUE; /* unconditionally */
@@ -451,11 +444,13 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
if(data->set.upload)
return file_upload(conn);
file = conn->data->req.protop;
/* get the fd from the connection phase */
fd = conn->data->state.proto.file->fd;
fd = file->fd;
/* VMS: This only works reliable for STREAMLF files */
if( -1 != fstat(fd, &statbuf)) {
if(-1 != fstat(fd, &statbuf)) {
/* we could stat it, then read out the size */
expected_size = statbuf.st_size;
/* and store the modification time */
@@ -463,13 +458,19 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
fstated = TRUE;
}
if(fstated && !data->state.range && data->set.timecondition) {
if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) {
*done = TRUE;
return CURLE_OK;
}
}
/* If we have selected NOBODY and HEADER, it means that we only want file
information. Which for FILE can't be much more than the file size and
date. */
if(data->set.opt_no_body && data->set.include_header && fstated) {
CURLcode result;
snprintf(buf, sizeof(data->state.buffer),
"Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
if(result)
return result;
@@ -480,14 +481,13 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
return result;
if(fstated) {
const struct tm *tm;
time_t filetime = (time_t)statbuf.st_mtime;
#ifdef HAVE_GMTIME_R
struct tm buffer;
tm = (const struct tm *)gmtime_r(&filetime, &buffer);
#else
tm = gmtime(&filetime);
#endif
const struct tm *tm = &buffer;
result = Curl_gmtime(filetime, &buffer);
if(result)
return result;
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
snprintf(buf, BUFSIZE-1,
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
@@ -529,11 +529,13 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
}
/* A high water mark has been specified so we obey... */
if (data->req.maxdownload > 0)
if(data->req.maxdownload > 0)
expected_size = data->req.maxdownload;
if(fstated && (expected_size == 0))
return CURLE_OK;
if(!fstated || (expected_size == 0))
size_known = FALSE;
else
size_known = TRUE;
/* The following is a shortcut implementation of file reading
this is both more efficient than the former call to download() and
@@ -550,35 +552,45 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
while(res == CURLE_OK) {
while(!result) {
/* Don't fill a whole buffer if we want less than all data */
bytestoread = (expected_size < BUFSIZE-1)?(size_t)expected_size:BUFSIZE-1;
size_t bytestoread;
if(size_known) {
bytestoread =
(expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ?
curlx_sotouz(expected_size) : BUFSIZE - 1;
}
else
bytestoread = BUFSIZE-1;
nread = read(fd, buf, bytestoread);
if( nread > 0)
if(nread > 0)
buf[nread] = 0;
if (nread <= 0 || expected_size == 0)
if(nread <= 0 || (size_known && (expected_size == 0)))
break;
bytecount += nread;
expected_size -= nread;
if(size_known)
expected_size -= nread;
res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
if(res)
return res;
result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
if(result)
return result;
Curl_pgrsSetDownloadCounter(data, bytecount);
if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
result = CURLE_ABORTED_BY_CALLBACK;
else
res = Curl_speedcheck(data, now);
result = Curl_speedcheck(data, now);
}
if(Curl_pgrsUpdate(conn))
res = CURLE_ABORTED_BY_CALLBACK;
result = CURLE_ABORTED_BY_CALLBACK;
return res;
return result;
}
#endif