projects
/
project
/
uclient.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
http: assume data EOF if the connection terminates
[project/uclient.git]
/
uclient-http.c
diff --git
a/uclient-http.c
b/uclient-http.c
index
574dc01
..
5e5f996
100644
(file)
--- a/
uclient-http.c
+++ b/
uclient-http.c
@@
-19,6
+19,7
@@
#include <ctype.h>
#include <unistd.h>
#include <stdint.h>
#include <ctype.h>
#include <unistd.h>
#include <stdint.h>
+#include <fcntl.h>
#include <libubox/ustream.h>
#include <libubox/ustream-ssl.h>
#include <libubox/ustream.h>
#include <libubox/ustream-ssl.h>
@@
-107,6
+108,8
@@
static const char * const uclient_http_prefix[] = {
[__PREFIX_MAX] = NULL
};
[__PREFIX_MAX] = NULL
};
+static int uclient_http_connect(struct uclient *cl);
+
static int uclient_do_connect(struct uclient_http *uh, const char *port)
{
socklen_t sl;
static int uclient_do_connect(struct uclient_http *uh, const char *port)
{
socklen_t sl;
@@
-117,10
+120,11
@@
static int uclient_do_connect(struct uclient_http *uh, const char *port)
memset(&uh->uc.remote_addr, 0, sizeof(uh->uc.remote_addr));
memset(&uh->uc.remote_addr, 0, sizeof(uh->uc.remote_addr));
- fd = usock_inet(USOCK_TCP
| USOCK_NONBLOCK
, uh->uc.url->host, port, &uh->uc.remote_addr);
+ fd = usock_inet(USOCK_TCP, uh->uc.url->host, port, &uh->uc.remote_addr);
if (fd < 0)
return -1;
if (fd < 0)
return -1;
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
ustream_fd_init(&uh->ufd, fd);
sl = sizeof(uh->uc.local_addr);
ustream_fd_init(&uh->ufd, fd);
sl = sizeof(uh->uc.local_addr);
@@
-188,6
+192,9
@@
static void uclient_notify_eof(struct uclient_http *uh)
return;
}
return;
}
+ if (uh->content_length < 0 && uh->read_chunked >= 0)
+ uh->uc.data_eof = true;
+
uclient_backend_set_eof(&uh->uc);
if (uh->connection_close)
uclient_backend_set_eof(&uh->uc);
if (uh->connection_close)
@@
-573,7
+580,7
@@
static void uclient_http_headers_complete(struct uclient_http *uh)
if (auth_type == AUTH_TYPE_UNKNOWN && uh->uc.status_code == 401 &&
(uh->req_type == REQ_HEAD || uh->req_type == REQ_GET)) {
if (auth_type == AUTH_TYPE_UNKNOWN && uh->uc.status_code == 401 &&
(uh->req_type == REQ_HEAD || uh->req_type == REQ_GET)) {
- uclient_http_
init_request(uh
);
+ uclient_http_
connect(&uh->uc
);
uclient_http_send_headers(uh);
uh->state = HTTP_STATE_REQUEST_DONE;
return;
uclient_http_send_headers(uh);
uh->state = HTTP_STATE_REQUEST_DONE;
return;
@@
-659,28
+666,33
@@
static void __uclient_notify_read(struct uclient_http *uh)
return;
if (uh->state < HTTP_STATE_RECV_DATA) {
return;
if (uh->state < HTTP_STATE_RECV_DATA) {
- char *sep;
+ char *sep
, *next
;
int cur_len;
do {
int cur_len;
do {
- sep = str
str(data, "\r\n"
);
+ sep = str
chr(data, '\n'
);
if (!sep)
break;
if (!sep)
break;
+ next = sep + 1;
+ if (sep > data && sep[-1] == '\r')
+ sep--;
+
/* Check for multi-line HTTP headers */
if (sep > data) {
/* Check for multi-line HTTP headers */
if (sep > data) {
- if (!
sep[2]
)
+ if (!
*next
)
return;
return;
- if (isspace(
sep[2]) && sep[2] != '\r
') {
+ if (isspace(
*next) && *next != '\r' && *next != '\n
') {
sep[0] = ' ';
sep[0] = ' ';
- sep[1] = ' ';
+ if (sep + 1 < next)
+ sep[1] = ' ';
continue;
}
}
*sep = 0;
continue;
}
}
*sep = 0;
- cur_len =
sep + 2
- data;
+ cur_len =
next
- data;
uclient_parse_http_line(uh, data);
if (seq != uh->seq)
return;
uclient_parse_http_line(uh, data);
if (seq != uh->seq)
return;
@@
-846,7
+858,7
@@
static int uclient_http_connect(struct uclient *cl)
struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
int ret;
struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
int ret;
- if (!cl->eof || uh->disconnect)
+ if (!cl->eof || uh->disconnect
|| uh->connection_close
)
uclient_http_disconnect(uh);
uclient_http_init_request(uh);
uclient_http_disconnect(uh);
uclient_http_init_request(uh);
@@
-1059,7
+1071,7
@@
uclient_http_read(struct uclient *cl, char *buf, unsigned int len)
return len;
}
return len;
}
-
bool
uclient_http_redirect(struct uclient *cl)
+
int
uclient_http_redirect(struct uclient *cl)
{
struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
struct blobmsg_policy location = {
{
struct uclient_http *uh = container_of(cl, struct uclient_http, uc);
struct blobmsg_policy location = {
@@
-1091,7
+1103,9
@@
bool uclient_http_redirect(struct uclient *cl)
free(cl->url);
cl->url = url;
free(cl->url);
cl->url = url;
- uclient_http_connect(cl);
+ if (uclient_http_connect(cl))
+ return -1;
+
uclient_http_request_done(cl);
return true;
uclient_http_request_done(cl);
return true;