/[osn-commons]/trunk/freehttpd/freehttpd.c
ViewVC logotype

Diff of /trunk/freehttpd/freehttpd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 45 by rakinar2, Sun Aug 11 17:35:46 2024 UTC revision 46 by rakinar2, Mon Aug 12 16:55:32 2024 UTC
# Line 1  Line 1 
1  #include "freehttpd.h"  #include "freehttpd.h"
2    #include "http_error.h"
3  #include "log.h"  #include "log.h"
4    #include "protocol.h"
5  #include "request.h"  #include "request.h"
6  #include "response.h"  #include "response.h"
7    
# Line 24  struct freehttpd Line 26  struct freehttpd
26      int sockfd;      int sockfd;
27      magic_t magic;      magic_t magic;
28      freehttpd_config_t *config;      freehttpd_config_t *config;
29        freehttpd_errdoc_tbl_t *errdoc_tbl;
30  };  };
31    
32  static freehttpd_config_t *  static freehttpd_config_t *
# Line 65  freehttpd_init (magic_t magic) Line 68  freehttpd_init (magic_t magic)
68          return NULL;          return NULL;
69    
70      freehttpd->sockfd = -1;      freehttpd->sockfd = -1;
     freehttpd->config = freehttpd_config_init ();  
71      freehttpd->magic = magic;      freehttpd->magic = magic;
72        freehttpd->config = freehttpd_config_init ();
73        freehttpd->errdoc_tbl = freehttpd_error_document_tbl_init ();
74    
75        freehttpd_error_document_load_defaults (freehttpd->errdoc_tbl);
76      return freehttpd;      return freehttpd;
77  }  }
78    
# Line 122  freehttpd_free (freehttpd_t *freehttpd) Line 128  freehttpd_free (freehttpd_t *freehttpd)
128      if (freehttpd == NULL)      if (freehttpd == NULL)
129          return;          return;
130    
131        freehttpd_error_document_tbl_free (freehttpd->errdoc_tbl);
132      freehttpd_config_free (freehttpd->config);      freehttpd_config_free (freehttpd->config);
133      free (freehttpd);      free (freehttpd);
134  }  }
# Line 179  freehttpd_listen (freehttpd_t *freehttpd Line 186  freehttpd_listen (freehttpd_t *freehttpd
186  }  }
187    
188  static ecode_t  static ecode_t
189  freehttpd_send_error (FILE *stream, int sockfd, freehttpd_status_t status)  freehttpd_send_error (freehttpd_t *freehttpd, FILE *stream, int sockfd,
190                          freehttpd_status_t status, const char *version)
191  {  {
192      freehttpd_response_t *response = freehttpd_response_init ("1.1", 3, status);      freehttpd_response_t *response = freehttpd_response_init (
193            stream, version == NULL ? HTTP1_1 : version, 3, status);
194        ecode_t ret = E_OK;
195    
196      if (response == NULL)      if (response == NULL)
197          return E_LIBC_MALLOC;          return E_LIBC_MALLOC;
# Line 189  freehttpd_send_error (FILE *stream, int Line 199  freehttpd_send_error (FILE *stream, int
199      if (stream == NULL)      if (stream == NULL)
200          stream = fdopen (sockfd, "w");          stream = fdopen (sockfd, "w");
201    
202        if (stream == NULL)
203            {
204                freehttpd_response_free (response);
205                return E_LIBC_FDOPEN;
206            }
207    
208      freehttpd_response_add_default_headers (response);      freehttpd_response_add_default_headers (response);
     freehttpd_response_add_header (response, "Content-Type",  
                                    "text/html; charset=\"utf-8\"", 12, 26);  
209    
210      response->body = NULL;      const freehttpd_errdoc_t *doc
211      (void) (asprintf (&response->body,          = freehttpd_error_document_get (freehttpd->errdoc_tbl, status);
                       "<center><h1>%d %s</h1><hr><p>freehttpd</p></center>\r\n",  
                       response->status.code, response->status.text)  
             + 1);  
212    
213      response->body_length = strlen (response->body);      if (doc == NULL)
214            {
215                freehttpd_response_add_header (response, "Content-Length", 0, "0");
216                freehttpd_response_head_send (response);
217                freehttpd_response_begin_end (response);
218                return E_OK;
219            }
220    
221      char *len = NULL;      freehttpd_response_add_header (response, "Content-Type", 0,
222      (void) (asprintf (&len, "%lu", response->body_length) + 1);                                     "text/html; charset=\"utf-8\"");
223        freehttpd_response_add_header (response, "Content-Length", 0, "%lu",
224                                       doc->document_length);
225    
226      freehttpd_response_add_header (response, "Content-Length", len, 14,      ret = freehttpd_response_head_send (response);
227                                     strlen (len));  
228        if (ret != E_OK)
229            log_err (LOG_ERR "failed to send error response headers: %i\n", ret);
230    
231      ecode_t ret = freehttpd_response_send (response, stream);      ret = freehttpd_response_begin_body (response);
232    
233      if (ret != E_OK)      if (ret != E_OK)
234          log_err (LOG_ERR "failed to send error response: %i\n", ret);          log_err (LOG_ERR "failed to start sending response: %i\n", ret);
235    
236        if (freehttpd_response_write (response, doc->document, 1,
237                                      doc->document_length)
238            != doc->document_length)
239            log_err (LOG_ERR "failed to write error response: %i\n", ret);
240    
     fflush (stream);  
     free (len);  
241      freehttpd_response_free (response);      freehttpd_response_free (response);
242      return ret;      return ret;
243  }  }
# Line 238  iasprintf (char **strp, const char *fmt, Line 262  iasprintf (char **strp, const char *fmt,
262      va_end (ap);      va_end (ap);
263  }  }
264    
265    /*
266  static ecode_t  static ecode_t
267  freehttpd_respond_dindex (freehttpd_t *freehttpd, freehttpd_request_t *request,  freehttpd_respond_dindex (freehttpd_t *freehttpd, freehttpd_request_t *request,
268                            freehttpd_response_t *response, FILE *stream,                            freehttpd_response_t *response, FILE *stream,
269                            const char *rpath)                            const char *rpath)
270  {  {
271      freehttpd_response_set_status (response, FREEHTTPD_STATUS_OK);      freehttpd_response_set_status (response, FREEHTTPD_STATUS_OK);
272      ecode_t code = freehttpd_response_send (response, stream);      ecode_t code = freehttpd_response_head_send (response);
273    
274      if (code != E_OK)      if (code != E_OK)
275          return code;          return code;
# Line 383  freehttpd_respond_dindex (freehttpd_t *f Line 408  freehttpd_respond_dindex (freehttpd_t *f
408      closedir (dir);      closedir (dir);
409      return E_OK;      return E_OK;
410  }  }
411    */
412    
413  static ecode_t  static ecode_t
414    freehttpd_respond_http1x (freehttpd_t *freehttpd, freehttpd_request_t *request,
415                              freehttpd_response_t *response)
416    {
417        return freehttpd_send_error (freehttpd, response->stream, 0,
418                                     FREEHTTPD_STATUS_NOT_IMPLEMENTED,
419                                     request->version);
420        // return E_OK;
421    }
422    
423    /*
424    static ecode_t
425  freehttpd_respond (freehttpd_t *freehttpd, freehttpd_request_t *request,  freehttpd_respond (freehttpd_t *freehttpd, freehttpd_request_t *request,
426                     freehttpd_response_t *response, FILE *stream)                     freehttpd_response_t *response, FILE *stream)
427  {  {
# Line 481  freehttpd_respond (freehttpd_t *freehttp Line 518  freehttpd_respond (freehttpd_t *freehttp
518          content_type = "application/javascript";          content_type = "application/javascript";
519      else      else
520          {          {
521              magic_descriptor (freehttpd->magic, fileno (file));              content_type = magic_descriptor (freehttpd->magic, fileno (file));
522    
523              if (content_type == NULL)              if (content_type == NULL)
524                  content_type = "application/octet-stream";                  content_type = "application/octet-stream";
# Line 499  freehttpd_respond (freehttpd_t *freehttp Line 536  freehttpd_respond (freehttpd_t *freehttp
536          }          }
537    
538      freehttpd_response_set_status (response, status);      freehttpd_response_set_status (response, status);
539      ecode_t code = freehttpd_response_send (response, stream);      ecode_t code = freehttpd_response_head_send (response);
540    
541      if (code != E_OK)      if (code != E_OK)
542          {          {
# Line 568  freehttpd_respond_error: Line 605  freehttpd_respond_error:
605      freehttpd_response_set_status (response, status);      freehttpd_response_set_status (response, status);
606    
607      if (status != FREEHTTPD_STATUS_OK)      if (status != FREEHTTPD_STATUS_OK)
608          freehttpd_send_error (stream, fileno (stream), status);          freehttpd_send_error (stream, 0, status, request->version);
609    
610      free (rpath);      free (rpath);
611      free (fs_path);      free (fs_path);
612      return E_OK;      return E_OK;
613  }  }
614    */
615    
616  static ecode_t  static ecode_t
617  freehttpd_loop (freehttpd_t *freehttpd)  freehttpd_loop (freehttpd_t *freehttpd)
# Line 596  freehttpd_loop (freehttpd_t *freehttpd) Line 634  freehttpd_loop (freehttpd_t *freehttpd)
634              if (code != E_OK)              if (code != E_OK)
635                  {                  {
636                      log_err (LOG_ERR "failed to parse request: %i\n", code);                      log_err (LOG_ERR "failed to parse request: %i\n", code);
637                      freehttpd_send_error (NULL, client_sockfd,                      freehttpd_send_error (freehttpd, NULL, client_sockfd,
638                                            FREEHTTPD_STATUS_BAD_REQUEST);                                            FREEHTTPD_STATUS_BAD_REQUEST,
639                                              HTTP1_1);
640                        continue;
641                    }
642    
643                FILE *stream = fdopen (client_sockfd, "w");
644    
645                if (stream == NULL)
646                    {
647                        log_err (LOG_ERR "failed to open stream\n");
648                        freehttpd_send_error (
649                            freehttpd, NULL, client_sockfd,
650                            FREEHTTPD_STATUS_INTERNAL_SERVER_ERROR,
651                            request->version);
652                        freehttpd_request_free (request);
653                        close (client_sockfd);
654                      continue;                      continue;
655                  }                  }
656    
657              freehttpd_response_t *response = freehttpd_response_init (              freehttpd_response_t *response = freehttpd_response_init (
658                  request->version, request->version_length, FREEHTTPD_STATUS_OK);                  stream, request->version, request->version_length,
659                    FREEHTTPD_STATUS_OK);
660    
661              if (response == NULL)              if (response == NULL)
662                  {                  {
663                      log_err (LOG_ERR "failed to init response\n");                      log_err (LOG_ERR "failed to init response\n");
664                      freehttpd_send_error (                      freehttpd_send_error (
665                          NULL, client_sockfd,                          freehttpd, NULL, client_sockfd,
666                          FREEHTTPD_STATUS_INTERNAL_SERVER_ERROR);                          FREEHTTPD_STATUS_INTERNAL_SERVER_ERROR,
667                            request->version);
668                      freehttpd_request_free (request);                      freehttpd_request_free (request);
669                      close (client_sockfd);                      close (client_sockfd);
670                      continue;                      continue;
671                  }                  }
672    
673              FILE *stream = fdopen (client_sockfd, "w");              code = freehttpd_respond_http1x (freehttpd, request, response);
   
             code = freehttpd_respond (freehttpd, request, response, stream);  
674    
675              log_msg (LOG_INFO "%s %s HTTP/%s - %d %s\n", request->method,              log_msg (LOG_INFO "%s %s HTTP/%s - %d %s\n", request->method,
676                       request->uri, request->version, response->status.code,                       request->uri, request->version, response->status.code,

Legend:
Removed from v.45  
changed lines
  Added in v.46

team@onesoftnet.eu.org
ViewVC Help
Powered by ViewVC 1.1.26