278 file = sstrncat(2, file, base, mf); |
279 file = sstrncat(2, file, base, mf); |
279 |
280 |
280 ConfigFile *f = cfgmgr_get_file(file); |
281 ConfigFile *f = cfgmgr_get_file(file); |
281 if(f == NULL) { |
282 if(f == NULL) { |
282 f = malloc(sizeof(ConfigFile)); |
283 f = malloc(sizeof(ConfigFile)); |
|
284 f->data = NULL; |
283 f->file = sstrdup(file); |
285 f->file = sstrdup(file); |
284 f->reload = mime_conf_reload; |
286 f->reload = mime_conf_reload; |
285 |
287 |
286 // load the file content |
288 // load the file content |
287 f->reload(f, cfg); |
289 //f->reload(f, cfg); |
|
290 if(cfgmgr_reload_file(f, cfg, NULL)) { |
|
291 free(f->file.ptr); |
|
292 free(f); |
|
293 return -1; |
|
294 } |
288 cfgmgr_attach_file(f); |
295 cfgmgr_attach_file(f); |
289 } |
296 } |
290 |
297 |
291 cfg->mimetypes = f->data; // TODO: ref |
298 cfg->mimetypes = f->data; |
292 |
299 |
293 return 0; |
300 return 0; |
294 } |
301 } |
295 |
302 |
296 int cfg_handle_logfile(ServerConfiguration *cfg, ServerConfigObject *obj) { |
303 int cfg_handle_logfile(ServerConfiguration *cfg, ServerConfigObject *obj) { |
529 |
536 |
530 // the file is managed by the configuration manager |
537 // the file is managed by the configuration manager |
531 ConfigFile *f = cfgmgr_get_file(file); |
538 ConfigFile *f = cfgmgr_get_file(file); |
532 if(f == NULL) { |
539 if(f == NULL) { |
533 f = malloc(sizeof(ConfigFile)); |
540 f = malloc(sizeof(ConfigFile)); |
|
541 f->data = NULL; |
534 f->file = sstrdup(file); |
542 f->file = sstrdup(file); |
535 f->reload = object_conf_reload; |
543 f->reload = object_conf_reload; |
536 f->reload(f, cfg); |
544 //f->reload(f, cfg); |
|
545 if(cfgmgr_reload_file(f, cfg, NULL)) { |
|
546 free(f->file.ptr); |
|
547 free(f); |
|
548 return -1; |
|
549 } |
537 cfgmgr_attach_file(f); |
550 cfgmgr_attach_file(f); |
538 } |
551 } |
539 vs->objectfile = sstrdup(file); // TODO: pool |
552 vs->objectfile = sstrdup(file); |
540 vs->objects = (HTTPObjectConfig*)f->data; // TODO: ref |
553 vs->objects = (HTTPObjectConfig*)f->data; |
541 |
554 |
542 // load acl config file |
555 // load acl config file |
543 file.length = base.length + aclfile.length + 1; |
556 file.length = base.length + aclfile.length + 1; |
544 file.ptr = alloca(file.length); |
557 file.ptr = alloca(file.length); |
545 file.ptr[file.length] = 0; |
558 file.ptr[file.length] = 0; |
546 file = sstrncat(2, file, base, aclfile); |
559 file = sstrncat(2, file, base, aclfile); |
547 |
560 |
548 ConfigFile *aclf = cfgmgr_get_file(file); |
561 ConfigFile *aclf = cfgmgr_get_file(file); |
549 if(aclf == NULL) { |
562 if(aclf == NULL) { |
550 aclf = malloc(sizeof(ConfigFile)); |
563 aclf = malloc(sizeof(ConfigFile)); |
|
564 aclf->data = NULL; |
551 aclf->file = sstrdup(file); |
565 aclf->file = sstrdup(file); |
552 aclf->reload = acl_conf_reload; |
566 aclf->reload = acl_conf_reload; |
553 aclf->reload(aclf, cfg); |
567 //aclf->reload(aclf, cfg); |
|
568 if(cfgmgr_reload_file(aclf, cfg, NULL)) { |
|
569 free(aclf->file.ptr); |
|
570 free(aclf); |
|
571 return -1; |
|
572 } |
554 cfgmgr_attach_file(aclf); |
573 cfgmgr_attach_file(aclf); |
555 } |
574 } |
|
575 vs->acls = aclf->data; |
556 |
576 |
557 // set the access log for the virtual server |
577 // set the access log for the virtual server |
558 // TODO: don't use always the default |
578 // TODO: don't use always the default |
559 vs->log = get_default_access_log(); |
579 vs->log = get_default_access_log(); |
560 |
580 |
563 return 0; |
583 return 0; |
564 } |
584 } |
565 |
585 |
566 |
586 |
567 int object_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { |
587 int object_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { |
|
588 HTTPObjectConfig *old_conf = file->data; |
568 file->data = load_obj_conf(file->file.ptr); |
589 file->data = load_obj_conf(file->file.ptr); |
569 struct stat s; |
590 if(old_conf) { |
570 if(stat(file->file.ptr, &s) != 0) { |
591 object_conf_unref(old_conf); |
571 perror("object_conf_reload: stat"); |
592 } |
572 return -1; |
593 if(file->data) { |
573 } |
594 return 0; |
574 file->last_modified = s.st_mtim.tv_sec; |
595 } else { |
575 return 0; |
596 return 1; |
|
597 } |
|
598 } |
|
599 |
|
600 void object_conf_ref(HTTPObjectConfig *conf) { |
|
601 if(conf) { |
|
602 ws_atomic_inc32(&conf->ref); |
|
603 } |
|
604 } |
|
605 |
|
606 void object_conf_unref(HTTPObjectConfig *conf) { |
|
607 uint32_t ref = ws_atomic_dec32(&conf->ref); |
|
608 if(ref == 0) { |
|
609 printf("free HTTPObjectConfig %d\n", conf); |
|
610 pool_destroy(conf->pool); |
|
611 } |
576 } |
612 } |
577 |
613 |
578 HTTPObjectConfig* load_obj_conf(char *file) { |
614 HTTPObjectConfig* load_obj_conf(char *file) { |
579 printf("load_obj_conf\n"); |
615 printf("load_obj_conf\n"); |
580 |
616 |
584 if(cfg == NULL) { |
620 if(cfg == NULL) { |
585 return NULL; |
621 return NULL; |
586 } |
622 } |
587 |
623 |
588 /* create object config */ |
624 /* create object config */ |
589 HTTPObjectConfig *conf = calloc(sizeof(HTTPObjectConfig), 1); |
625 pool_handle_t *pool = pool_create(); |
590 conf->pool = pool_create(); |
626 HTTPObjectConfig *conf = pool_calloc(pool, sizeof(HTTPObjectConfig), 1); |
|
627 conf->pool = pool; |
591 |
628 |
592 /* convert ObjectConfig to HTTPObjectConfig */ |
629 /* convert ObjectConfig to HTTPObjectConfig */ |
593 |
630 |
594 /* add objects */ |
631 /* add objects */ |
595 conf->nobj = ucx_dlist_size(cfg->objects); |
632 conf->nobj = ucx_dlist_size(cfg->objects); |
596 conf->objects = calloc(1, sizeof(httpd_object*)); |
633 conf->objects = pool_calloc(pool, 1, sizeof(httpd_object*)); |
597 |
634 |
598 UcxDlist *objlist = cfg->objects; |
635 UcxDlist *objlist = cfg->objects; |
599 int i = 0; |
636 int i = 0; |
600 while(objlist != NULL) { |
637 while(objlist != NULL) { |
601 ConfigObject *cob = objlist->data; |
638 ConfigObject *cob = objlist->data; |
602 |
639 |
603 /* get name and ppath */ |
640 /* get name and ppath */ |
604 char *name = NULL; |
641 char *name = NULL; |
605 char *ppath = NULL; |
642 char *ppath = NULL; |
606 if(cob->name.length > 0) { |
643 if(cob->name.length > 0) { |
607 name = sstrdup(cob->name).ptr; |
644 name = sstrdup_pool(pool, cob->name).ptr; |
608 } |
645 } |
609 if(cob->ppath.length > 0) { |
646 if(cob->ppath.length > 0) { |
610 ppath = sstrdup(cob->ppath).ptr; |
647 ppath = sstrdup_pool(pool, cob->ppath).ptr; |
611 } |
648 } |
612 |
649 |
613 /* create and add object */ |
650 /* create and add object */ |
614 httpd_object *obj = object_new(name); |
651 httpd_object *obj = object_new(pool, name); |
615 obj->path = NULL; |
652 obj->path = NULL; |
616 |
653 |
617 conf->objects[i] = obj; // TODO: beyond array bounds write |
654 conf->objects[i] = obj; // TODO: beyond array bounds write |
618 |
655 |
619 /* add directives */ |
656 /* add directives */ |
620 for(int i=0;i<6;i++) { |
657 for(int i=0;i<6;i++) { |
621 UcxDlist *dirs = cob->directives[i]; |
658 UcxDlist *dirs = cob->directives[i]; |
622 while(dirs != NULL) { |
659 while(dirs != NULL) { |
623 ConfigDirective *cfgdir = dirs->data; |
660 ConfigDirective *cfgdir = dirs->data; |
624 |
661 |
625 directive *d = malloc(sizeof(directive)); |
662 directive *d = pool_malloc(pool, sizeof(directive)); |
626 d->cond = NULL; |
663 d->cond = NULL; |
627 d->param = pblock_create_pool(conf->pool, 8); |
664 d->param = pblock_create_pool(pool, 8); |
628 |
665 |
629 /* add params */ |
666 /* add params */ |
630 UcxList *param = cfg_param_list(cfgdir->value, mp); |
667 UcxList *param = cfg_param_list(cfgdir->value, mp); |
631 while(param != NULL) { |
668 while(param != NULL) { |
632 ConfigParam *p = param->data; |
669 ConfigParam *p = param->data; |
660 return conf; |
697 return conf; |
661 } |
698 } |
662 |
699 |
663 int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { |
700 int mime_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { |
664 MimeConfig *mimecfg = load_mime_config(file->file.ptr); |
701 MimeConfig *mimecfg = load_mime_config(file->file.ptr); |
665 |
702 MimeMap *old_conf = file->data; |
666 UcxMap *mimemap = ucx_map_new((mimecfg->ntypes * 3) / 2); |
703 |
|
704 MimeMap *mimemap = malloc(sizeof(MimeMap)); |
|
705 mimemap->ref = 1; |
|
706 UcxMap *map = ucx_map_new((mimecfg->ntypes * 3) / 2); |
|
707 mimemap->map = map; |
667 |
708 |
668 // add ext type pairs |
709 // add ext type pairs |
669 UCX_FOREACH(UcxList*, mimecfg->directives, md) { |
710 UCX_FOREACH(UcxList*, mimecfg->directives, md) { |
670 MimeDirective *d = md->data; |
711 MimeDirective *d = md->data; |
671 // add the type for each extension to the map |
712 // add the type for each extension to the map |
672 UCX_FOREACH(UcxList*, d->exts, xl) { |
713 UCX_FOREACH(UcxList*, d->exts, xl) { |
673 sstr_t ext = sstr(xl->data); |
714 sstr_t ext = sstr(xl->data); |
674 sstr_t value = sstrdup(d->type); |
715 sstr_t value = sstrdup(d->type); |
675 ucx_map_sstr_put(mimemap, ext, value.ptr); |
716 ucx_map_sstr_put(map, ext, value.ptr); |
676 } |
717 } |
677 } |
718 } |
678 |
719 |
679 file->data = mimemap; |
720 file->data = mimemap; |
|
721 |
|
722 if(old_conf) { |
|
723 mime_conf_unref(old_conf); |
|
724 } |
|
725 |
680 return 0; |
726 return 0; |
|
727 } |
|
728 |
|
729 void mime_conf_ref(MimeMap *conf) { |
|
730 if(conf) { |
|
731 ws_atomic_inc32(&conf->ref); |
|
732 } |
|
733 } |
|
734 |
|
735 void mime_conf_unref(MimeMap *conf) { |
|
736 uint32_t ref = ws_atomic_dec32(&conf->ref); |
|
737 if(ref == 0) { |
|
738 printf("free MimeConfig %d\n", conf); |
|
739 UcxMapIterator i = ucx_map_iterator(conf->map); |
|
740 char *str; |
|
741 UCX_MAP_FOREACH(str, i) { |
|
742 free(str); |
|
743 } |
|
744 ucx_map_free(conf->map); |
|
745 free(conf); |
|
746 } |
681 } |
747 } |
682 |
748 |
683 int acl_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { |
749 int acl_conf_reload(ConfigFile *file, ServerConfiguration *cfg) { |
684 ACLFile *aclfile = load_acl_file(file->file.ptr); |
750 ACLFile *aclfile = load_acl_file(file->file.ptr); |
685 |
751 |
689 ACLList *acl = acl_config_convert(cfg, ac); |
755 ACLList *acl = acl_config_convert(cfg, ac); |
690 ucx_map_sstr_put(acldata->namedACLs, ac->id, acl); |
756 ucx_map_sstr_put(acldata->namedACLs, ac->id, acl); |
691 } |
757 } |
692 free_acl_file(aclfile); |
758 free_acl_file(aclfile); |
693 |
759 |
694 cfg->acls = acldata; |
760 ACLData *old_data = file->data; |
695 |
761 file->data = acldata; |
696 struct stat s; |
762 if(old_data) { |
697 if(stat(file->file.ptr, &s) != 0) { |
763 acl_data_unref(old_data); |
698 perror("object_conf_reload: stat"); |
764 } |
699 return -1; |
765 |
700 } |
|
701 file->last_modified = s.st_mtim.tv_sec; |
|
702 return 0; |
766 return 0; |
703 } |
767 } |
704 |
768 |
705 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) { |
769 ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) { |
706 WSAcl *acllist = malloc(sizeof(WSAcl)); |
770 WSAcl *acllist = malloc(sizeof(WSAcl)); |