Changeset cbfc8b7 in mainline


Ignore:
Timestamp:
2013-10-05T20:49:27Z (11 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4f086417
Parents:
c42f50d
Message:

libhttp: Allow to specify limits when receiving HTTP response

Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/download/main.c

    rc42f50d rcbfc8b7  
    171171       
    172172        http_response_t *response = NULL;
    173         rc = http_receive_response(&http->recv_buffer, &response);
     173        rc = http_receive_response(&http->recv_buffer, &response, 16 * 1024,
     174            100);
    174175        if (rc != EOK) {
    175176                fprintf(stderr, "Failed receiving response: %s\n", str_error(rc));
  • uspace/lib/http/include/http/http.h

    rc42f50d rcbfc8b7  
    8888extern void http_header_init(http_header_t *);
    8989extern http_header_t *http_header_create(const char *, const char *);
    90 extern int http_header_receive_name(receive_buffer_t *, char **);
    91 extern int http_header_receive_value(receive_buffer_t *, char **);
    92 extern int http_header_receive(receive_buffer_t *, http_header_t *);
     90extern int http_header_receive_name(receive_buffer_t *, receive_buffer_mark_t *);
     91extern int http_header_receive_value(receive_buffer_t *, receive_buffer_mark_t *,
     92    receive_buffer_mark_t *);
     93extern int http_header_receive(receive_buffer_t *, http_header_t *, size_t,
     94    size_t *);
    9395extern void http_header_normalize_value(char *);
    9496extern bool http_header_name_match(const char *, const char *);
     
    102104extern int http_headers_set(http_headers_t *, const char *, const char *);
    103105extern int http_headers_get(http_headers_t *, const char *, char **);
    104 extern int http_headers_receive(receive_buffer_t *, http_headers_t *);
     106extern int http_headers_receive(receive_buffer_t *, http_headers_t *, size_t,
     107    unsigned);
    105108extern void http_headers_clear(http_headers_t *);
    106109
     
    126129extern int http_receive_status(receive_buffer_t *, http_version_t *, uint16_t *,
    127130    char **);
    128 extern int http_receive_response(receive_buffer_t *, http_response_t **);
     131extern int http_receive_response(receive_buffer_t *, http_response_t **,
     132    size_t, unsigned);
    129133extern void http_response_destroy(http_response_t *);
    130134extern int http_close(http_t *);
  • uspace/lib/http/src/headers.c

    rc42f50d rcbfc8b7  
    9494}
    9595
    96 int http_header_receive_name(receive_buffer_t *rb, char **out_name)
    97 {
    98         receive_buffer_mark_t name_start;
    99         receive_buffer_mark_t name_end;
    100        
    101         recv_mark(rb, &name_start);
    102         recv_mark(rb, &name_end);
    103        
     96int http_header_receive_name(receive_buffer_t *rb,
     97    receive_buffer_mark_t *name_end)
     98{
    10499        char c = 0;
    105100        do {
    106                 recv_mark_update(rb, &name_end);
     101                if (name_end)
     102                        recv_mark_update(rb, name_end);
    107103               
    108104                int rc = recv_char(rb, &c, true);
    109                 if (rc != EOK) {
    110                         recv_unmark(rb, &name_start);
    111                         recv_unmark(rb, &name_end);
    112                         return rc;
    113                 }
     105                if (rc != EOK)
     106                        return rc;
    114107        } while (is_token(c));
    115108       
    116         if (c != ':') {
    117                 recv_unmark(rb, &name_start);
    118                 recv_unmark(rb, &name_end);
     109        if (c != ':')
    119110                return EINVAL;
    120         }
    121        
    122         char *name = NULL;
    123         int rc = recv_cut_str(rb, &name_start, &name_end, &name);
    124         recv_unmark(rb, &name_start);
    125         recv_unmark(rb, &name_end);
    126         if (rc != EOK)
    127                 return rc;
    128        
    129         *out_name = name;
    130         return EOK;
    131 }
    132 
    133 int http_header_receive_value(receive_buffer_t *rb, char **out_value)
     111       
     112        return EOK;
     113}
     114
     115int http_header_receive_value(receive_buffer_t *rb,
     116    receive_buffer_mark_t *value_start, receive_buffer_mark_t *value_end)
    134117{
    135118        int rc = EOK;
    136119        char c = 0;
    137120       
    138         receive_buffer_mark_t value_start;
    139         recv_mark(rb, &value_start);
    140        
    141121        /* Ignore any inline LWS */
    142122        while (true) {
    143                 recv_mark_update(rb, &value_start);
     123                if (value_start)
     124                        recv_mark_update(rb, value_start);
     125               
    144126                rc = recv_char(rb, &c, false);
    145127                if (rc != EOK)
    146                         goto error;
     128                        return rc;
    147129               
    148130                if (c != ' ' && c != '\t')
     
    151133                rc = recv_char(rb, &c, true);
    152134                if (rc != EOK)
    153                         goto error;
    154         }
    155        
    156         receive_buffer_mark_t value_end;
    157         recv_mark(rb, &value_end);
     135                        return rc;
     136        }
    158137       
    159138        while (true) {
    160                 recv_mark_update(rb, &value_end);
     139                recv_mark_update(rb, value_end);
    161140               
    162141                rc = recv_char(rb, &c, true);
    163142                if (rc != EOK)
    164                         goto error_end;
     143                        return rc;
    165144               
    166145                if (c != '\r' && c != '\n')
     
    169148                rc = recv_discard(rb, (c == '\r' ? '\n' : '\r'));
    170149                if (rc < 0)
    171                         goto error_end;
     150                        return rc;
    172151               
    173152                rc = recv_char(rb, &c, false);
    174153                if (rc != EOK)
    175                         goto error_end;
     154                        return rc;
    176155               
    177156                if (c != ' ' && c != '\t')
     
    181160                rc = recv_char(rb, &c, true);
    182161                if (rc != EOK)
    183                         goto error_end;
     162                        return rc;
     163        }
     164       
     165        return EOK;
     166}
     167
     168int http_header_receive(receive_buffer_t *rb, http_header_t *header,
     169    size_t size_limit, size_t *out_bytes_used)
     170{
     171        receive_buffer_mark_t mark_start;
     172        receive_buffer_mark_t mark_end;
     173       
     174        recv_mark(rb, &mark_start);
     175        recv_mark(rb, &mark_end);
     176       
     177        int rc = http_header_receive_name(rb, &mark_end);
     178        if (rc != EOK)
     179                goto end;
     180       
     181        size_t name_size = mark_end.offset - mark_start.offset;
     182        if (size_limit > 0 && name_size > size_limit) {
     183                rc = ELIMIT;
     184                goto end;
     185        }
     186       
     187        char *name = NULL;
     188        rc = recv_cut_str(rb, &mark_start, &mark_end, &name);
     189        if (rc != EOK)
     190                goto end;
     191       
     192        rc = http_header_receive_value(rb, &mark_start, &mark_end);
     193        if (rc != EOK)
     194                goto end_with_name;
     195       
     196        size_t value_size = mark_end.offset - mark_start.offset;
     197        if (size_limit > 0 && (name_size + value_size) > size_limit) {
     198                rc = ELIMIT;
     199                goto end_with_name;
    184200        }
    185201       
    186202        char *value = NULL;
    187         rc = recv_cut_str(rb, &value_start, &value_end, &value);
    188         recv_unmark(rb, &value_start);
    189         recv_unmark(rb, &value_end);
    190         if (rc != EOK)
    191                 return rc;
    192        
    193         *out_value = value;
    194         return EOK;
    195 error_end:
    196         recv_unmark(rb, &value_end);
    197 error:
    198         recv_unmark(rb, &value_start);
    199         return rc;
    200 }
    201 
    202 int http_header_receive(receive_buffer_t *rb, http_header_t *header)
    203 {
    204         char *name = NULL;
    205         int rc = http_header_receive_name(rb, &name);
    206         if (rc != EOK) {
    207                 return rc;
    208         }
    209        
    210         char *value = NULL;
    211         rc = http_header_receive_value(rb, &value);
    212         if (rc != EOK) {
    213                 free(name);
    214                 return rc;
    215         }
     203        rc = recv_cut_str(rb, &mark_start, &mark_end, &value);
     204        if (rc != EOK)
     205                goto end_with_name;
     206       
     207        if (out_bytes_used)
     208                *out_bytes_used = name_size + value_size;
    216209       
    217210        header->name = name;
    218211        header->value = value;
    219         return EOK;
     212        goto end;
     213end_with_name:
     214        free(name);
     215end:
     216        recv_unmark(rb, &mark_start);
     217        recv_unmark(rb, &mark_end);
     218        return rc;
    220219}
    221220
     
    324323}
    325324
    326 int http_headers_receive(receive_buffer_t *rb, http_headers_t *headers)
     325int http_headers_receive(receive_buffer_t *rb, http_headers_t *headers,
     326    size_t limit_alloc, unsigned limit_count)
    327327{
    328328        int rc = EOK;
     
    337337                if (c == '\n' || c == '\r')
    338338                        break;
     339               
     340                if (limit_count > 0 && added >= limit_count) {
     341                        rc = ELIMIT;
     342                        goto error;
     343                }
    339344               
    340345                http_header_t *header = malloc(sizeof(http_header_t));
     
    345350                http_header_init(header);
    346351               
    347                 rc = http_header_receive(rb, header);
     352                size_t header_size;
     353                rc = http_header_receive(rb, header, limit_alloc, &header_size);
    348354                if (rc != EOK) {
    349355                        free(header);
    350356                        goto error;
    351357                }
     358                limit_alloc -= header_size;
    352359               
    353360                http_headers_append_header(headers, header);
  • uspace/lib/http/src/response.c

    rc42f50d rcbfc8b7  
    185185}
    186186
    187 int http_receive_response(receive_buffer_t *rb, http_response_t **out_response)
     187int http_receive_response(receive_buffer_t *rb, http_response_t **out_response,
     188    size_t max_headers_size, unsigned max_headers_count)
    188189{
    189190        http_response_t *resp = malloc(sizeof(http_response_t));
     
    198199                goto error;
    199200       
    200         rc = http_headers_receive(rb, &resp->headers);
     201        rc = http_headers_receive(rb, &resp->headers, max_headers_size,
     202            max_headers_count);
    201203        if (rc != EOK)
    202204                goto error;
Note: See TracChangeset for help on using the changeset viewer.