1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-10-01 03:36:26 -04:00

1008: error parameter in read_http_post

This function will need to set ELinks-specific errors
and it would not be right to write those in errno.
This commit is contained in:
Kalle Olavi Niemitalo 2008-06-03 01:26:19 +03:00 committed by Kalle Olavi Niemitalo
parent 44bf538cab
commit d3ee4e2e47
4 changed files with 54 additions and 28 deletions

View File

@ -90,10 +90,11 @@ send_more_post_data(struct socket *socket)
struct http_connection_info *http = conn->info;
unsigned char buffer[POST_BUFFER_SIZE];
int got;
enum connection_state error;
got = read_http_post(&http->post, buffer, POST_BUFFER_SIZE);
got = read_http_post(&http->post, buffer, POST_BUFFER_SIZE, &error);
if (got < 0) {
abort_connection(conn, -errno);
abort_connection(conn, error);
} else if (got > 0) {
write_to_socket(socket, buffer, got, S_TRANS,
send_more_post_data);

View File

@ -602,10 +602,11 @@ send_more_post_data(struct socket *socket)
struct http_connection_info *http = conn->info;
unsigned char buffer[POST_BUFFER_SIZE];
int got;
enum connection_state error;
got = read_http_post(&http->post, buffer, POST_BUFFER_SIZE);
got = read_http_post(&http->post, buffer, POST_BUFFER_SIZE, &error);
if (got < 0) {
http_end_request(conn, -errno, 0);
http_end_request(conn, error, 0);
} else if (got > 0) {
write_to_socket(socket, buffer, got, S_TRANS,
send_more_post_data);

View File

@ -131,17 +131,22 @@ open_http_post(struct http_post *http_post, unsigned char *post_data,
return 1;
}
/** @relates http_post */
/** @return -2 if no data was read but the caller should retry;
* -1 if an error occurred and *@a error was set; 0 at end of data;
* a positive number if that many bytes were read.
*
* @relates http_post */
static int
read_http_post_inline(struct http_post *http_post,
unsigned char buffer[], int max)
unsigned char buffer[], int max,
enum connection_state *error)
{
unsigned char *post = http_post->post_data;
unsigned char *end = strchr(post, FILE_CHAR);
int total = 0;
assert(http_post->post_fd < 0);
if_assert_failed { errno = EINVAL; return -1; }
if_assert_failed { *error = S_INTERNAL; return -1; }
if (!end)
end = strchr(post, '\0');
@ -175,24 +180,31 @@ read_http_post_inline(struct http_post *http_post,
http_post->post_data = post;
if (total > 0)
return total; /* retry the open on the next call */
else
return -1; /* caller gets errno from open() */
else {
*error = -errno;
return -1;
}
}
http_post->post_data = end + 1;
return total;
return total ? total : -2;
}
/** @relates http_post */
/** @return -2 if no data was read but the caller should retry;
* -1 if an error occurred and *@a error was set; 0 at end of data;
* a positive number if that many bytes were read.
*
* @relates http_post */
static int
read_http_post_fd(struct http_post *http_post,
unsigned char buffer[], int max)
unsigned char buffer[], int max,
enum connection_state *error)
{
int ret;
/* safe_read() would set errno = EBADF anyway, but check this
* explicitly to make any such bugs easier to detect. */
assert(http_post->post_fd >= 0);
if_assert_failed { errno = EBADF; return -1; }
if_assert_failed { *error = S_INTERNAL; return -1; }
ret = safe_read(http_post->post_fd, buffer, max);
if (ret <= 0) {
@ -200,8 +212,18 @@ read_http_post_fd(struct http_post *http_post,
close(http_post->post_fd);
http_post->post_fd = -1;
http_post->file_index++;
errno = errno_from_read;
if (ret == 0) {
/* The upload file ended but there may still
* be more data in uri.post. If not,
* read_http_post_inline() will return 0 to
* indicate the final end of file. */
return -2;
} else {
*error = -errno_from_read;
return -1;
}
}
return ret;
}
@ -210,43 +232,44 @@ read_http_post_fd(struct http_post *http_post,
* refers.
*
* @return >0 if read that many bytes; 0 if EOF; -1 on error and set
* errno.
* *@a error.
*
* @relates http_post */
int
read_http_post(struct http_post *http_post,
unsigned char buffer[], int max)
unsigned char buffer[], int max,
enum connection_state *error)
{
int total = 0;
while (total < max) {
int chunk;
int post_fd = http_post->post_fd;
if (post_fd < 0)
if (http_post->post_fd < 0)
chunk = read_http_post_inline(http_post,
buffer + total,
max - total);
max - total,
error);
else
chunk = read_http_post_fd(http_post,
buffer + total,
max - total);
/* Be careful not to change errno here. */
max - total,
error);
if (chunk == 0 && http_post->post_fd == post_fd)
return total; /* EOF */
if (chunk < 0) {
if (chunk > 0)
total += chunk;
else if (chunk != -2) {
assert(chunk == -1 || chunk == 0);
/* If some data has already been successfully
* read to buffer[], tell the caller about
* that and forget about the error. The next
* http_read_post_data() call will retry the
* read_http_post() call will retry the
* operation that failed. */
if (total != 0)
return total;
else
return chunk; /* caller gets errno from above */
return chunk;
}
total += chunk;
}
return total;
}

View File

@ -50,6 +50,7 @@ void done_http_post(struct http_post *http_post);
int open_http_post(struct http_post *http_post, unsigned char *post_data,
enum connection_state *error);
int read_http_post(struct http_post *http_post,
unsigned char buffer[], int max);
unsigned char buffer[], int max,
enum connection_state *error);
#endif