Message ID | 1421336450-10781-1-git-send-email-zajec5@gmail.com |
---|---|
State | Changes Requested |
Headers | show |
On 2015-01-15 16:40, Rafał Miłecki wrote: > Signed-off-by: Rafał Miłecki <zajec5@gmail.com> > --- > uclient-fetch.c | 4 ++++ > uclient.c | 25 ++++++++++++++++++++++++- > uclient.h | 4 ++++ > 3 files changed, 32 insertions(+), 1 deletion(-) > > diff --git a/uclient.c b/uclient.c > index ab2d5b6..a405179 100644 > --- a/uclient.c > +++ b/uclient.c > @@ -207,12 +207,31 @@ int uclient_write(struct uclient *cl, char *buf, int len) > return cl->backend->write(cl, buf, len); > } > > +static void uclient_request_timeout(struct uloop_timeout *timeout) > +{ > + struct uclient *cl = container_of(timeout, struct uclient, request_timeout); > + > + if (cl->backend->disconnect) > + cl->backend->disconnect(cl); > + > + uclient_backend_set_error(cl, UCLIENT_ERROR_TIMEDOUT); > +} > + > int uclient_request(struct uclient *cl) > { > + int err; > + > if (!cl->backend->request) > return -1; > > - return cl->backend->request(cl); > + err = cl->backend->request(cl); > + if (err) > + return err; > + > + cl->request_timeout.cb = uclient_request_timeout; > + uloop_timeout_set(&cl->request_timeout, UCLIENT_DEFAULT_CONNECTION_TIMEOUT_MS); Please store the timeout value in struct uclient and initialize it at alloc time. I don't like forced hardcoded values. > + > + return 0; > } > > int uclient_read(struct uclient *cl, char *buf, int len) > @@ -225,6 +244,8 @@ int uclient_read(struct uclient *cl, char *buf, int len) > > void uclient_disconnect(struct uclient *cl) > { > + uloop_timeout_cancel(&cl->request_timeout); > + > if (!cl->backend->disconnect) > return; > > @@ -243,6 +264,8 @@ static void __uclient_backend_change_state(struct uloop_timeout *timeout) > > static void uclient_backend_change_state(struct uclient *cl) > { > + uloop_timeout_cancel(&cl->request_timeout); > + > cl->timeout.cb = __uclient_backend_change_state; > uloop_timeout_set(&cl->timeout, 1); > } The timeout should be cancelled or refreshed when the HTTP response is received, and on new incoming data. It should probably be cancelled if the receive buffer is full (since the data reception is throttled by the user). - Felix
diff --git a/uclient-fetch.c b/uclient-fetch.c index 22f15c6..0617a02 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -194,6 +194,10 @@ static void handle_uclient_error(struct uclient *cl, int code) type = "Connection failed"; error_ret = 4; break; + case UCLIENT_ERROR_TIMEDOUT: + type = "Connection timed out"; + error_ret = 4; + break; case UCLIENT_ERROR_SSL_INVALID_CERT: type = "Invalid SSL certificate"; ignore = !verify; diff --git a/uclient.c b/uclient.c index ab2d5b6..a405179 100644 --- a/uclient.c +++ b/uclient.c @@ -207,12 +207,31 @@ int uclient_write(struct uclient *cl, char *buf, int len) return cl->backend->write(cl, buf, len); } +static void uclient_request_timeout(struct uloop_timeout *timeout) +{ + struct uclient *cl = container_of(timeout, struct uclient, request_timeout); + + if (cl->backend->disconnect) + cl->backend->disconnect(cl); + + uclient_backend_set_error(cl, UCLIENT_ERROR_TIMEDOUT); +} + int uclient_request(struct uclient *cl) { + int err; + if (!cl->backend->request) return -1; - return cl->backend->request(cl); + err = cl->backend->request(cl); + if (err) + return err; + + cl->request_timeout.cb = uclient_request_timeout; + uloop_timeout_set(&cl->request_timeout, UCLIENT_DEFAULT_CONNECTION_TIMEOUT_MS); + + return 0; } int uclient_read(struct uclient *cl, char *buf, int len) @@ -225,6 +244,8 @@ int uclient_read(struct uclient *cl, char *buf, int len) void uclient_disconnect(struct uclient *cl) { + uloop_timeout_cancel(&cl->request_timeout); + if (!cl->backend->disconnect) return; @@ -243,6 +264,8 @@ static void __uclient_backend_change_state(struct uloop_timeout *timeout) static void uclient_backend_change_state(struct uclient *cl) { + uloop_timeout_cancel(&cl->request_timeout); + cl->timeout.cb = __uclient_backend_change_state; uloop_timeout_set(&cl->timeout, 1); } diff --git a/uclient.h b/uclient.h index d5a0d5b..095d894 100644 --- a/uclient.h +++ b/uclient.h @@ -24,12 +24,15 @@ #include <libubox/ustream.h> #include <libubox/ustream-ssl.h> +#define UCLIENT_DEFAULT_CONNECTION_TIMEOUT_MS 30000 + struct uclient_cb; struct uclient_backend; enum uclient_error_code { UCLIENT_ERROR_UNKNOWN, UCLIENT_ERROR_CONNECT, + UCLIENT_ERROR_TIMEDOUT, UCLIENT_ERROR_SSL_INVALID_CERT, UCLIENT_ERROR_SSL_CN_MISMATCH, UCLIENT_ERROR_MISSING_SSL_CONTEXT, @@ -67,6 +70,7 @@ struct uclient { int status_code; struct blob_attr *meta; + struct uloop_timeout request_timeout; struct uloop_timeout timeout; };
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> --- uclient-fetch.c | 4 ++++ uclient.c | 25 ++++++++++++++++++++++++- uclient.h | 4 ++++ 3 files changed, 32 insertions(+), 1 deletion(-)