123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #include "private-libwebsockets.h"
- int
- lws_ranges_next(struct lws_range_parsing *rp)
- {
- static const char * const beq = "bytes=";
- char c;
- while (1) {
- c = rp->buf[rp->pos];
- switch (rp->state) {
- case LWSRS_SYNTAX:
- case LWSRS_COMPLETED:
- return 0;
- case LWSRS_NO_ACTIVE_RANGE:
- rp->state = LWSRS_COMPLETED;
- return 0;
- case LWSRS_BYTES_EQ:
- if (c != beq[rp->pos]) {
- rp->state = LWSRS_SYNTAX;
- return -1;
- }
- if (rp->pos == 5)
- rp->state = LWSRS_FIRST;
- break;
- case LWSRS_FIRST:
- rp->start = 0;
- rp->end = 0;
- rp->start_valid = 0;
- rp->end_valid = 0;
- rp->state = LWSRS_STARTING;
-
- case LWSRS_STARTING:
- if (c == '-') {
- rp->state = LWSRS_ENDING;
- break;
- }
- if (!(c >= '0' && c <= '9')) {
- rp->state = LWSRS_SYNTAX;
- return 0;
- }
- rp->start = (rp->start * 10) + (c - '0');
- rp->start_valid = 1;
- break;
- case LWSRS_ENDING:
- if (c == ',' || c == '\0') {
- rp->state = LWSRS_FIRST;
- if (c == ',')
- rp->pos++;
-
- if (!rp->start_valid) {
- if (rp->end > rp->extent)
- rp->end = rp->extent;
- rp->start = rp->extent - rp->end;
- rp->end = rp->extent - 1;
- } else
- if (!rp->end_valid)
- rp->end = rp->extent - 1;
- rp->did_try = 1;
-
- if (rp->end < rp->start) {
- if (c == ',')
- break;
- rp->state = LWSRS_COMPLETED;
- return 0;
- }
- return 1;
- }
- if (!(c >= '0' && c <= '9')) {
- rp->state = LWSRS_SYNTAX;
- return 0;
- }
- rp->end = (rp->end * 10) + (c - '0');
- rp->end_valid = 1;
- break;
- }
- rp->pos++;
- }
- }
- void
- lws_ranges_reset(struct lws_range_parsing *rp)
- {
- rp->pos = 0;
- rp->ctr = 0;
- rp->start = 0;
- rp->end = 0;
- rp->start_valid = 0;
- rp->end_valid = 0;
- rp->state = LWSRS_BYTES_EQ;
- }
- int
- lws_ranges_init(struct lws *wsi, struct lws_range_parsing *rp,
- unsigned long long extent)
- {
- rp->agg = 0;
- rp->send_ctr = 0;
- rp->inside = 0;
- rp->count_ranges = 0;
- rp->did_try = 0;
- lws_ranges_reset(rp);
- rp->state = LWSRS_COMPLETED;
- rp->extent = extent;
- if (lws_hdr_copy(wsi, (char *)rp->buf, sizeof(rp->buf),
- WSI_TOKEN_HTTP_RANGE) <= 0)
- return 0;
- rp->state = LWSRS_BYTES_EQ;
- while (lws_ranges_next(rp)) {
- rp->count_ranges++;
- rp->agg += rp->end - rp->start + 1;
- }
- lwsl_debug("%s: count %d\n", __func__, rp->count_ranges);
- lws_ranges_reset(rp);
- if (rp->did_try && !rp->count_ranges)
- return -1;
- lws_ranges_next(rp);
- return rp->count_ranges;
- }
|