LCOV - code coverage report
Current view: top level - src - libhttp.c (source / functions) Hit Total Coverage
Test: mkernel.info Lines: 251 362 69.3 %
Date: 2024-12-05 21:00:54 Functions: 20 23 87.0 %

          Line data    Source code
       1             : /**
       2             :  *    @file  libhttp.c
       3             :  *   @brief  HTTP parsing and building library
       4             :  *
       5             :  *  @author  François Cerbelle (Fanfan), francois@cerbelle.net
       6             :  *
       7             :  *  @internal
       8             :  *       Created:  15/11/2024
       9             :  *      Revision:  none
      10             :  * Last modified:  2024-11-30 22:15
      11             :  *      Compiler:  gcc
      12             :  *  Organization:  Cerbelle.net
      13             :  *     Copyright:  Copyright (c) 2024, François Cerbelle
      14             :  *
      15             :  *  This source code is released for free distribution under the terms of the
      16             :  *  GNU General Public License as published by the Free Software Foundation.
      17             :  */
      18             : 
      19             : #ifdef HAVE_CONFIG_H
      20             : #include "config.h"
      21             : #endif
      22             : 
      23             : #include "libhttp.h"
      24             : #include "sclist.h"
      25             : #include "base64.h"                             /* Base64 encoder and decoder */
      26             : 
      27             : #include <stdlib.h>
      28             : #include <stdio.h>
      29             : #include <string.h>
      30             : #include <assert.h>
      31             : 
      32             : typedef struct HTTP_s {
      33             :     sclist_t* headers;
      34             :     char* body;
      35             : } HTTP_t;
      36             : 
      37             : typedef struct HTTPHeader_s {
      38             :     sclistrecord_t* self;
      39             :     char* name;
      40             :     char* value;
      41             : } HTTPHeader_t;
      42             : 
      43          10 : HTTPHeader_t* HTTPHeader_setname(HTTPHeader_t* header, const char* name) {
      44             :     char* newname;
      45             : 
      46          10 :     assert(header);
      47           8 :     assert(header->name);
      48           8 :     assert(header->value);
      49           8 :     assert(name);
      50             : 
      51           6 :     if (name[0]==0) {
      52           3 :         fprintf(stderr,"ERROR: HTTP_setname empty name\n");
      53           3 :         return NULL;
      54             :     }
      55             : 
      56           3 :     if (NULL==(newname=realloc(header->name,strlen(name)+1))) {
      57           0 :         perror("ERROR: HTTPHeader_setname realloc");
      58           0 :         return NULL;
      59             :     }
      60           3 :     header->name = newname;
      61           3 :     strcpy(header->name,name);
      62           3 :     return header;
      63             : }
      64             : 
      65         240 : char* HTTPHeader_getname(HTTPHeader_t* header) {
      66         240 :     assert(header);
      67         238 :     assert(header->name);
      68         238 :     assert(header->value);
      69             : 
      70         238 :     return header->name;
      71             : }
      72             : 
      73          10 : HTTPHeader_t* HTTPHeader_setvalue(HTTPHeader_t* header, const char* value) {
      74             :     char* newvalue;
      75             : 
      76          10 :     assert(header);
      77           8 :     assert(header->name);
      78           8 :     assert(header->value);
      79           8 :     assert(value);
      80             : 
      81           6 :     if (NULL==(newvalue=realloc(header->value,strlen(value)+1))) {
      82           0 :         perror("ERROR: HTTPHeader_setvalue realloc");
      83           0 :         return NULL;
      84             :     }
      85           6 :     header->value = newvalue;
      86           6 :     strcpy(header->value,value);
      87           6 :     return header;
      88             : }
      89             : 
      90         171 : char* HTTPHeader_getvalue(HTTPHeader_t* header) {
      91         171 :     assert(header);
      92         169 :     assert(header->name);
      93         169 :     assert(header->value);
      94             : 
      95         169 :     return header->value;
      96             : }
      97             : 
      98         213 : static HTTPHeader_t* HTTPHeader_new(const char* name, const char* value) {
      99             :     HTTPHeader_t* header;
     100             : 
     101         213 :     assert(name);
     102         213 :     assert(value);
     103             : 
     104         213 :     if (NULL==(header=malloc(sizeof(struct HTTPHeader_s)))) {
     105           0 :         perror("ERROR: HTTPHeader_new");
     106           0 :         return NULL;
     107             :     }
     108         213 :     if (NULL==(header->name=strdup(name))) {
     109           0 :         perror("ERROR: HTTPHeader_new name");
     110           0 :         free(header);
     111           0 :         return NULL;
     112             :     }
     113         213 :     if (NULL==(header->value=strdup(value))) {
     114           0 :         perror("ERROR: HTTPHeader_new value");
     115           0 :         free(header->name);
     116           0 :         free(header);
     117           0 :         return NULL;
     118             :     }
     119         213 :     header->self = NULL;
     120         213 :     return header;
     121             : }
     122             : 
     123         201 : static void HTTPHeader_del(HTTPHeader_t* header) {
     124         201 :     assert(header);
     125         201 :     assert(header->name);
     126         201 :     assert(header->value);
     127             : 
     128         201 :     free(header->name);
     129         201 :     free(header->value);
     130         201 :     free(header);
     131         201 : }
     132             : 
     133         174 : HTTP_t* HTTP_new() {
     134             :     HTTP_t* http;
     135             : 
     136         174 :     if (NULL==(http=malloc(sizeof(struct HTTP_s)))) {
     137           0 :         perror("ERROR: HTTP_new HTTP_s");
     138           0 :         return NULL;
     139             :     }
     140             : 
     141         174 :     if (NULL==(http->body=strdup(""))) {
     142           0 :         perror("ERROR: HTTP_new body");
     143           0 :         free(http);
     144           0 :         return NULL;
     145             :     };
     146             : 
     147         174 :     if (NULL==(http->headers = sclist_new())) {
     148           0 :         fprintf(stderr,"ERROR: HTTP_new headers\n");
     149           0 :         free(http->body);
     150           0 :         free(http);
     151           0 :         return NULL;
     152             :     }
     153             : 
     154         174 :     return http;
     155             : }
     156             : 
     157         152 : void HTTP_del(HTTP_t* http) {
     158             :     sclistrecord_t* headerlst_entry;
     159             : 
     160         152 :     assert(http);
     161         150 :     assert(http->headers);
     162         150 :     assert(http->body);
     163             : 
     164         150 :     headerlst_entry = sclist_firstrecord(http->headers);
     165         339 :     while (headerlst_entry) {
     166             :         HTTPHeader_t* headerlst_value;
     167             : 
     168             :         /* Free payload */
     169         189 :         headerlst_value=sclist_getvalue(headerlst_entry);
     170         189 :         HTTPHeader_del(headerlst_value);
     171             : 
     172             :         /* Remember the entry to delete before moving to the next one */
     173         189 :         sclistrecord_t* tmp = headerlst_entry;
     174         189 :         headerlst_entry = sclist_nextrecord(headerlst_entry);
     175         189 :         sclist_remrecord(http->headers,tmp);
     176             :     }
     177         150 :     sclist_del(http->headers);
     178             : 
     179         150 :     free(http->body);
     180         150 :     free(http);
     181         150 : }
     182             : 
     183          19 : HTTP_t* HTTP_setbody(HTTP_t* http, const char* body) {
     184             :     char* newbody;
     185             : 
     186          19 :     assert(http);
     187          17 :     assert(http->headers);
     188          17 :     assert(http->body);
     189          17 :     assert(body);
     190             : 
     191          15 :     if (NULL==(newbody=realloc(http->body,strlen(body)+1))) {
     192           0 :         perror("ERROR: HTTP_setbody realloc");
     193           0 :         return NULL;
     194             :     }
     195             : 
     196          15 :     http->body = newbody;
     197          15 :     strcpy(http->body, body);
     198          15 :     return http;
     199             : }
     200             : 
     201          17 : char* HTTP_getbody(HTTP_t* http) {
     202          17 :     assert(http);
     203          15 :     assert(http->headers);
     204          15 :     assert(http->body);
     205             : 
     206          15 :     return http->body;
     207             : }
     208             : 
     209         222 : HTTPHeader_t* HTTP_addheader(HTTP_t* http, const char* name, const char* value) {
     210             :     HTTPHeader_t* header;
     211             : 
     212         222 :     assert(http);
     213         220 :     assert(http->headers);
     214         220 :     assert(http->body);
     215         220 :     assert(name);
     216         218 :     assert(value);
     217             : 
     218         216 :     if (name[0]==0) {
     219           3 :         fprintf(stderr,"ERROR: HTTP_addheader empty name\n");
     220           3 :         return NULL;
     221             :     }
     222             : 
     223         213 :     if (NULL==(header = HTTPHeader_new(name,value))) {
     224           0 :         fprintf(stderr,"ERROR: HTTP_addheader HTTPHeader_new\n");
     225           0 :         return NULL;
     226             :     }
     227             : 
     228         213 :     if (NULL==(header->self=sclist_addrecord(http->headers,header))) {
     229           0 :         fprintf(stderr,"ERROR: HTTP_addheader\n");
     230           0 :         HTTPHeader_del(header);
     231           0 :         return NULL;
     232             :     }
     233         213 :     return header;
     234             : }
     235             : 
     236          15 : HTTPHeader_t* HTTP_addbasicauth(HTTP_t* http, const char* login, const char* pass) {
     237             :     char* auth_encoded;
     238             :     char* auth;
     239             :     HTTPHeader_t* header;
     240             : 
     241          15 :     assert(http);
     242          13 :     assert(http->headers);
     243          13 :     assert(http->body);
     244          13 :     assert(login);
     245          11 :     assert(pass);
     246             : 
     247           9 :     if (NULL==(auth=malloc(strlen(login)+1+strlen(pass)+1))) {
     248           0 :         perror("ERROR: HTTP_addbasicauth credentials");
     249           0 :         return NULL;
     250             :     }
     251             :     /* strcpy/strcat expected to be faster than sprintf */
     252           9 :     strcpy(auth,login);
     253           9 :     strcat(auth,":");
     254           9 :     strcat(auth,pass);
     255           9 :     auth_encoded=base64_encode(auth);
     256           9 :     free(auth);
     257             : 
     258           9 :     if (NULL==(auth=malloc(strlen("Basic ")+strlen(auth_encoded)+1))) {
     259           0 :         perror("ERROR: HTTP_addbasicauth value");
     260           0 :         free(auth_encoded);
     261           0 :         return NULL;
     262             :     }
     263           9 :     strcpy(auth,"Basic ");
     264           9 :     strcat(auth, auth_encoded);
     265           9 :     free(auth_encoded);
     266             : 
     267           9 :     if (NULL==(header=HTTP_addheader(http,"Authorization",auth))) {
     268           0 :         fprintf(stderr,"ERROR: HTTP_addbasicauth addheader\n");
     269           0 :         free(auth);
     270           0 :         return NULL;
     271             :     }
     272           9 :     free(auth);
     273           9 :     return header;
     274             : }
     275             : 
     276          81 : HTTPHeader_t* HTTP_firstheader(const HTTP_t* http) {
     277             :     sclistrecord_t* headerlst_entry;
     278             : 
     279          81 :     assert(http);
     280          79 :     assert(http->headers);
     281          79 :     assert(http->body);
     282             : 
     283          79 :     if (NULL==(headerlst_entry=sclist_firstrecord(http->headers)))
     284          11 :         return NULL;
     285          68 :     return sclist_getvalue(headerlst_entry);
     286             : }
     287             : 
     288          52 : HTTPHeader_t* HTTP_nextheader(const HTTPHeader_t* header) {
     289             :     sclistrecord_t* headerlst_entry;
     290             : 
     291          52 :     assert(header);
     292          48 :     assert(header->self);
     293          48 :     assert(header->name);
     294          48 :     assert(header->value);
     295             : 
     296          48 :     headerlst_entry = header->self;
     297             : 
     298             :     /* EOL reached */
     299          48 :     if (NULL==(headerlst_entry = sclist_nextrecord(headerlst_entry)))
     300          21 :         return NULL;
     301             :     else
     302          27 :         return sclist_getvalue(headerlst_entry);
     303             : }
     304             : 
     305          37 : HTTPHeader_t* HTTP_findheader(const HTTPHeader_t* start, const char* name) {
     306             :     sclistrecord_t* headerlst_entry;
     307             : 
     308          37 :     assert(start);
     309          35 :     assert(start->self);
     310          35 :     assert(start->name);
     311          35 :     assert(start->value);
     312          35 :     assert(name);
     313             : 
     314          33 :     headerlst_entry = start->self;
     315             : 
     316          75 :     while (headerlst_entry) {
     317             :         HTTPHeader_t* headerlst_value;
     318             :         char* header_name;
     319             : 
     320          69 :         headerlst_value = sclist_getvalue(headerlst_entry);
     321          69 :         assert(headerlst_value);
     322          69 :         header_name = HTTPHeader_getname(headerlst_value);
     323          69 :         if (0==strcmp(header_name,name))
     324          27 :             break;
     325          42 :         headerlst_entry=sclist_nextrecord(headerlst_entry);
     326             :     }
     327          33 :     if (!headerlst_entry)
     328             :         /* Not found */
     329           6 :         return NULL;
     330             :     else
     331             :         /* Found */
     332          27 :         return sclist_getvalue(headerlst_entry);
     333             : }
     334             : 
     335             : 
     336          19 : HTTP_t* HTTP_remheader(HTTP_t* http, HTTPHeader_t* header) {
     337          19 :     assert(http);
     338          17 :     assert(http->headers);
     339          17 :     assert(http->body);
     340          17 :     assert(header);
     341          15 :     assert(header->self);
     342          15 :     assert(header->name);
     343          15 :     assert(header->value);
     344             : 
     345             :     /* Remove from the header list */
     346          15 :     if (NULL==sclist_remrecord(http->headers, header->self)) {
     347           3 :         fprintf(stderr,"ERROR: HTTP_remheader not found\n");
     348           3 :         return NULL;
     349             :     }
     350          12 :     header->self = NULL;
     351          12 :     HTTPHeader_del(header);
     352             : 
     353          12 :     return http;
     354             : }
     355             : 
     356         367 : static char* strconcat(char* dst, const char* src) {
     357             :     char* newdst;
     358             : 
     359         367 :     assert(dst);
     360         367 :     assert(src);
     361             : 
     362         367 :     if (NULL==(newdst=realloc(dst,strlen(dst)+strlen(src)+1))) {
     363           0 :         perror("ERROR: strconcat");
     364           0 :         return NULL;
     365             :     }
     366         367 :     dst = newdst;
     367         367 :     strcat(dst,src);
     368         367 :     return dst;
     369             : }
     370             : 
     371          39 : char* HTTP_buildheaders(const HTTP_t* http) {
     372          39 :     char* headers_str=NULL;
     373             :     sclistrecord_t* headerlst_entry;
     374             : 
     375          39 :     assert(http);
     376          33 :     assert(http->headers);
     377          33 :     assert(http->body);
     378             : 
     379          33 :     if (NULL==(headers_str=strdup(""))) {
     380           0 :         perror("ERROR: HTTP_buildheaders headers_str");
     381           0 :         return NULL;
     382             :     }
     383          33 :     for (
     384          33 :         headerlst_entry=sclist_firstrecord(http->headers);
     385          66 :         headerlst_entry;
     386          33 :         headerlst_entry = sclist_nextrecord(headerlst_entry)
     387             :     ) {
     388             :         HTTPHeader_t* headerlst_value;
     389             : 
     390          33 :         headerlst_value = sclist_getvalue(headerlst_entry);
     391          33 :         assert(headerlst_value);
     392             :         /** @bug possible memory leak, check strconcat return values */
     393          33 :         headers_str=strconcat(headers_str,HTTPHeader_getname(headerlst_value));
     394          33 :         headers_str=strconcat(headers_str,": ");
     395          33 :         headers_str=strconcat(headers_str,HTTPHeader_getvalue(headerlst_value));
     396          33 :         headers_str=strconcat(headers_str,"\r\n");
     397             :     }
     398             : 
     399          33 :     return headers_str;
     400             : }
     401             : 
     402             : /* @todo redesign headers and implementation to identify different errors */
     403          22 : char* HTTP_buildrequest(const HTTP_t* http, const HTTPMethod_t method, const char* uri, const HTTPVersion_t version) {
     404             :     char* request;
     405             :     char* newrequest;
     406             :     char* headers;
     407             : 
     408          22 :     assert(uri);
     409             : 
     410          20 :     if (NULL==(request=strdup(""))) {
     411           0 :         perror("ERROR: HTTP_getrequest strdup");
     412           0 :         return NULL;
     413             :     }
     414             : 
     415          20 :     switch(method) {
     416          17 :     case HTTPMETHOD_GET:
     417          17 :         if (NULL==(newrequest=strconcat(request, "GET"))) {
     418           0 :             fprintf(stderr,"ERROR: HTTP_buildrequest method\n");
     419           0 :             free(request);
     420           0 :             return NULL;
     421             :         }
     422          17 :         request = newrequest;
     423          17 :         break;;
     424           3 :     case HTTPMETHOD_HEAD:
     425             :     case HTTPMETHOD_POST:
     426             :     case HTTPMETHOD_PUT:
     427             :     case HTTPMETHOD_DELETE:
     428             :     case HTTPMETHOD_CONNECT:
     429             :     case HTTPMETHOD_OPTIONS:
     430             :     case HTTPMETHOD_TRACE:
     431             :     case HTTPMETHOD_PATCH:
     432             :     case HTTPMETHOD_INVALID:
     433             :     default:
     434           3 :         fprintf(stderr,"ERROR: HTTP method not supported\n");
     435           3 :         free(request);
     436           3 :         return NULL;
     437             :         break;;
     438             :     }
     439             : 
     440          17 :     if (uri[0]) {
     441          14 :         if (NULL==(newrequest=strconcat(request, " "))) {
     442           0 :             fprintf(stderr,"ERROR: HTTP_buildrequest uri separator\n");
     443           0 :             free(request);
     444           0 :             return NULL;
     445             :         }
     446          14 :         request = newrequest;
     447          14 :         if (NULL==(newrequest=strconcat(request, uri))) {
     448           0 :             fprintf(stderr,"ERROR: HTTP_buildrequest uri\n");
     449           0 :             free(request);
     450           0 :             return NULL;
     451             :         }
     452          14 :         request = newrequest;
     453             :     }
     454             : 
     455          17 :     if (NULL==(newrequest=strconcat(request, " HTTP/"))) {
     456           0 :         fprintf(stderr,"ERROR: HTTP_buildrequest HTTP\n");
     457           0 :         free(request);
     458           0 :         return NULL;
     459             :     }
     460          17 :     request = newrequest;
     461          17 :     switch(version) {
     462          14 :     case HTTPVERSION_HTTP11:
     463             :     case HTTPVERSION_HTTP11b:
     464          14 :         if (NULL==(newrequest=strconcat(request, "1.1"))) {
     465           0 :             fprintf(stderr,"ERROR: HTTP_buildrequest Version\n");
     466           0 :             free(request);
     467           0 :             return NULL;
     468             :         }
     469          14 :         request = newrequest;
     470          14 :         break;;
     471           3 :     case HTTPVERSION_HTTP09:
     472             :     case HTTPVERSION_HTTP10:
     473             :     case HTTPVERSION_HTTP2:
     474             :     case HTTPVERSION_HTTP3:
     475             :     case HTTPVERSION_INVALID:
     476             :     default:
     477           3 :         fprintf(stderr,"ERROR: HTTP version not supported\n");
     478           3 :         free(request);
     479           3 :         return NULL;
     480             :         break;;
     481             :     }
     482          14 :     if (NULL==(newrequest=strconcat(request, "\r\n"))) {
     483           0 :         fprintf(stderr,"ERROR: HTTP_buildrequest version separator\n");
     484           0 :         free(request);
     485           0 :         return NULL;
     486             :     }
     487          14 :     request = newrequest;
     488             : 
     489          14 :     if (NULL==(headers=HTTP_buildheaders(http))) {
     490           0 :         fprintf(stderr,"ERROR: HTTP_buildrequest buildheaders\n");
     491           0 :         free(request);
     492           0 :         return NULL;
     493             :     }
     494             : 
     495          12 :     if (NULL==(newrequest=strconcat(request, headers))) {
     496           0 :         fprintf(stderr,"ERROR: HTTP_buildrequest headers\n");
     497           0 :         free(request);
     498           0 :         return NULL;
     499             :     }
     500          12 :     request = newrequest;
     501          12 :     free(headers);
     502             : 
     503          12 :     if (NULL==(newrequest=strconcat(request, "\r\n"))) {
     504           0 :         fprintf(stderr,"ERROR: HTTP_buildrequest header separator\n");
     505           0 :         free(request);
     506           0 :         return NULL;
     507             :     }
     508          12 :     request = newrequest;
     509             : 
     510          12 :     if (NULL==(newrequest=strconcat(request, http->body))) {
     511           0 :         fprintf(stderr,"ERROR: HTTP_buildrequest body\n");
     512           0 :         free(request);
     513           0 :         return NULL;
     514             :     }
     515          12 :     request = newrequest;
     516             : 
     517          12 :     return request;
     518             : }
     519             : 
     520          17 : char*         HTTP_buildreply(const HTTP_t* http, const HTTPVersion_t version, const HTTPStatus_t status) {
     521             :     char* reply;
     522             :     char* newreply;
     523             :     char* headers;
     524             :     char status_str[6];
     525             : 
     526          17 :     if (NULL==(reply=strdup(""))) {
     527           0 :         fprintf(stderr,"ERROR: HTTP_buildreply strdup\n");
     528           0 :         return NULL;
     529             :     }
     530             : 
     531          17 :     if (NULL==(newreply=strconcat(reply, "HTTP/"))) {
     532           0 :         fprintf(stderr,"ERROR: HTTP_buildreply HTTP\n");
     533           0 :         free(reply);
     534           0 :         return NULL;
     535             :     }
     536          17 :     reply = newreply;
     537          17 :     switch(version) {
     538          14 :     case HTTPVERSION_HTTP11:
     539             :     case HTTPVERSION_HTTP11b:
     540          14 :         if (NULL==(newreply=strconcat(reply, "1.1"))) {
     541           0 :             fprintf(stderr,"ERROR: HTTP_buildreply Version\n");
     542           0 :             free(reply);
     543           0 :             return NULL;
     544             :         }
     545          14 :         reply = newreply;
     546          14 :         break;;
     547           3 :     case HTTPVERSION_HTTP09:
     548             :     case HTTPVERSION_HTTP10:
     549             :     case HTTPVERSION_HTTP2:
     550             :     case HTTPVERSION_HTTP3:
     551             :     case HTTPVERSION_INVALID:
     552             :     default:
     553           3 :         fprintf(stderr,"ERROR: HTTP version not supported\n");
     554           3 :         free(reply);
     555           3 :         return NULL;
     556             :         break;;
     557             :     }
     558             : 
     559          14 :     snprintf(status_str,6," %d ",status);
     560          14 :     if (NULL==(newreply=strconcat(reply, status_str))) {
     561           0 :         fprintf(stderr,"ERROR: HTTP_buildreply status code\n");
     562           0 :         free(reply);
     563           0 :         return NULL;
     564             :     }
     565          14 :     reply = newreply;
     566             : 
     567          14 :     if (NULL==(newreply=strconcat(reply, "Dummy Reason"))) {
     568           0 :         fprintf(stderr,"ERROR: HTTP_buildreply reason phrase\n");
     569           0 :         free(reply);
     570           0 :         return NULL;
     571             :     }
     572          14 :     reply = newreply;
     573             : 
     574          14 :     if (NULL==(newreply=strconcat(reply, "\r\n"))) {
     575           0 :         fprintf(stderr,"ERROR: HTTP_buildreply reason separator\n");
     576           0 :         free(reply);
     577           0 :         return NULL;
     578             :     }
     579          14 :     reply = newreply;
     580             : 
     581          14 :     if (NULL==(headers=HTTP_buildheaders(http))) {
     582           0 :         fprintf(stderr,"ERROR: HTTP_buildreply buildheaders\n");
     583           0 :         free(reply);
     584           0 :         return NULL;
     585             :     }
     586             : 
     587          12 :     if (NULL==(newreply=strconcat(reply, headers))) {
     588           0 :         fprintf(stderr,"ERROR: HTTP_buildreply headers\n");
     589           0 :         free(reply);
     590           0 :         return NULL;
     591             :     }
     592          12 :     reply = newreply;
     593          12 :     free(headers);
     594             : 
     595          12 :     if (NULL==(newreply=strconcat(reply, "\r\n"))) {
     596           0 :         fprintf(stderr,"ERROR: HTTP_buildreply header separator\n");
     597           0 :         free(reply);
     598           0 :         return NULL;
     599             :     }
     600          12 :     reply = newreply;
     601             : 
     602          12 :     if (NULL==(newreply=strconcat(reply, http->body))) {
     603           0 :         fprintf(stderr,"ERROR: HTTP_buildreply body\n");
     604           0 :         free(reply);
     605           0 :         return NULL;
     606             :     }
     607          12 :     reply = newreply;
     608             : 
     609          12 :     return reply;
     610             : }
     611             : 
     612           0 : HTTP_t*       HTTP_parseheaders(const char* text) {
     613             :     (void) text;
     614           0 :     fprintf(stderr,"Not yet implemented\n");
     615           0 :     abort();
     616             :     return NULL;
     617             : }
     618             : 
     619           0 : void          HTTP_parserequest(const char* request, HTTP_t** http, HTTPMethod_t method, char* uri, HTTPVersion_t version) {
     620             :     (void) request;
     621             :     (void) http;
     622             :     (void) method;
     623             :     (void) uri;
     624             :     (void) version;
     625           0 :     fprintf(stderr,"Not yet implemented\n");
     626           0 :     abort();
     627             : }
     628             : 
     629           0 : void          HTTP_parsereply(const char* reply, HTTP_t** http, HTTPVersion_t* version, HTTPStatus_t* status) {
     630             :     (void) reply;
     631             :     (void) http;
     632             :     (void) version;
     633             :     (void) status;
     634           0 :     fprintf(stderr,"Not yet implemented\n");
     635           0 :     abort();
     636             : }

Generated by: LCOV version 1.16