@@ -185,7 +185,7 @@ def as_dict(self):
185185 def as_strings (self ):
186186 """Return the entire Server block as nginx config strings."""
187187 ret = []
188- ret .append ('server {\n ' )
188+ ret .append ('\n server {\n ' )
189189 for x in self .children :
190190 if isinstance (x , Key ):
191191 ret .append (INDENT + x .as_strings )
@@ -401,6 +401,10 @@ def as_dict(self):
401401 @property
402402 def as_strings (self ):
403403 """Return key as nginx config string."""
404+ if self .value == '' or self .value is None :
405+ return '{0};\n ' .format (self .name )
406+ if ';' in self .value or '#' in self .value :
407+ return '{0} "{1}";\n ' .format (self .name , self .value )
404408 return '{0} {1};\n ' .format (self .name , self .value )
405409
406410
@@ -413,77 +417,95 @@ def loads(data, conf=True):
413417 """
414418 f = Conf () if conf else []
415419 lopen = []
416- for line in data .split ('\n ' ):
417- line_outside_quotes = re .sub (r'"([^"]+)"|\'([^\']+)\'|\\S+' , '' , line )
418- if re .match (r'\s*server\s*({.*)?$' , line ):
420+ index = 0
421+
422+ while True :
423+ m = re .compile (r'^\s*server\s*{' , re .S ).search (data [index :])
424+ if m :
419425 s = Server ()
420426 lopen .insert (0 , s )
421- if re .match (r'\s*location.*' , line ):
422- lpath = re .match (r'\s*location\s*(.*\S+)\s*{' , line ).group (1 )
423- l = Location (lpath )
427+ index += m .end ()
428+ continue
429+
430+ m = re .compile (r'^\s*location\s*(.*?\S+)\s*{' , re .S ).search (data [index :])
431+ if m :
432+ l = Location (m .group (1 ))
424433 lopen .insert (0 , l )
425- if re .match (r'\s*if.*({.*)?$' , line ):
426- ifs = re .match ('\s*if\s*(.*\s+)\s*' , line ).group (1 )
427- ifs = If (ifs )
434+ index += m .end ()
435+ continue
436+
437+ m = re .compile (r'^\s*if\s*(.*?\S+)\s*{' , re .S ).search (data [index :])
438+ if m :
439+ ifs = If (m .group (1 ))
428440 lopen .insert (0 , ifs )
429- if re .match (r'\s*upstream.*({.*)?$' , line ):
430- ups = re .match (r'\s*upstream\s*(.*\S+)\s*[^{]' , line ).group ().split ()[1 ]
431- u = Upstream (ups )
432- lopen .insert (0 , u )
433- if re .match (r'\s*geo\s*\$.*\s{' , line ):
434- geo = re .match ('\s*geo\s+(\$.*)\s{' , line ).group (1 )
435- s = Geo (geo )
436- lopen .insert (0 , s )
437- if re .match (r'.*;' , line ):
438- cmt_regex = r'(.*)#\s*(?![^\'\"]*[\'\"])'
439- key_regex = r'.*(?:^|^\s*|{\s*)(\S+)\s(.+);'
440-
441- oneword_regex = r'\s*(\S+[^\s+]\S+)\s*;\s*'
442-
443- to_eval = line
444- if re .match (cmt_regex , line ):
445- to_eval = re .match (cmt_regex , line ).group (1 )
446- if re .match (key_regex , to_eval ):
447- kname , kval = re .match (key_regex , to_eval ).group (1 , 2 )
448- if "#" not in kname :
449- k = Key (kname , kval )
450- if lopen and isinstance (lopen [0 ], (Container , Server )):
451- lopen [0 ].add (k )
452- else :
453- f .add (k ) if conf else f .append (k )
454-
455- if re .match (oneword_regex , line ):
456- kname = re .match (oneword_regex , line ).group (1 )
457- k = Key (kname , '' )
441+ index += m .end ()
442+ continue
458443
459- if lopen and isinstance (lopen [0 ], (Container , Server )):
460- lopen [0 ].add (k )
461- else :
462- f .add (k ) if conf else f .append (k )
463-
464-
465- if re .match (r'(^(?!#)([^#]*[}]{1}\s*)$)|(\s*{$)' , line_outside_quotes ):
466- closenum = len (re .findall ('}' , line_outside_quotes ))
467- while closenum > 0 :
468- if isinstance (lopen [0 ], Server ):
469- f .add (lopen [0 ]) if conf else f .append (lopen [0 ])
470- lopen .pop (0 )
471- elif isinstance (lopen [0 ], Container ):
472- c = lopen [0 ]
473- lopen .pop (0 )
474- if lopen and isinstance (lopen [0 ], (Container , Server )):
475- lopen [0 ].add (c )
476- else :
477- f .add (c ) if conf else f .append (c )
478- closenum = closenum - 1
479- if re .match (r'.*#\s*(?![^\'\"]*[\'\"])' , line ):
480- cmt_regex = r'.*#\s*(.*)(?![^\'\"]*[\'\"])'
481- c = Comment (re .match (cmt_regex , line ).group (1 ),
482- inline = not re .match (r'^\s*#.*' , line ))
444+ m = re .compile (r'^\s*upstream\s*(.*?\S+)\s*{' , re .S ).search (data [index :])
445+ if m :
446+ u = Upstream (m .group (1 ))
447+ lopen .insert (0 , u )
448+ index += m .end ()
449+ continue
450+
451+ m = re .compile (r'^\s*geo\s*(.*?\S+)\s*{' , re .S ).search (data [index :])
452+ if m :
453+ g = Geo (m .group (1 ))
454+ lopen .insert (0 , g )
455+ index += m .end ()
456+ continue
457+
458+ m = re .compile (r'^(\s*)#\s*(.*?)\n' , re .S ).search (data [index :])
459+ if m :
460+ c = Comment (m .group (2 ), inline = '\n ' not in m .group (1 ))
483461 if lopen and isinstance (lopen [0 ], (Container , Server )):
484462 lopen [0 ].add (c )
485463 else :
486464 f .add (c ) if conf else f .append (c )
465+ index += m .end () - 1
466+ continue
467+
468+ m = re .compile (r'^\s*}' , re .S ).search (data [index :])
469+ if m :
470+ if isinstance (lopen [0 ], Server ):
471+ f .add (lopen [0 ]) if conf else f .append (lopen [0 ])
472+ lopen .pop (0 )
473+ elif isinstance (lopen [0 ], Container ):
474+ c = lopen [0 ]
475+ lopen .pop (0 )
476+ if lopen and isinstance (lopen [0 ], (Container , Server )):
477+ lopen [0 ].add (c )
478+ else :
479+ f .add (c ) if conf else f .append (c )
480+ index += m .end ()
481+ continue
482+
483+ key_with_quoted = r'^\s*(\S*?)\s*"([^"]+)";?|\'([^\']+)\';?|\\S+;?'
484+ key_wo_quoted = r'^\s*([a-zA-Z0-9-_]+?)\s+(.+?);'
485+ m1 = re .compile (key_with_quoted , re .S ).search (data [index :])
486+ m2 = re .compile (key_wo_quoted , re .S ).search (data [index :])
487+ m = m1 or m2
488+ if m :
489+ k = Key (m .group (1 ), m .group (2 ))
490+ if lopen and isinstance (lopen [0 ], (Container , Server )):
491+ lopen [0 ].add (k )
492+ else :
493+ f .add (k ) if conf else f .append (k )
494+ index += m .end ()
495+ continue
496+
497+ m = re .compile (r'^\s*(\S+);' , re .S ).search (data [index :])
498+ if m :
499+ k = Key (m .group (1 ), '' )
500+ if lopen and isinstance (lopen [0 ], (Container , Server )):
501+ lopen [0 ].add (k )
502+ else :
503+ f .add (k ) if conf else f .append (k )
504+ index += m .end ()
505+ continue
506+
507+ break
508+
487509 return f
488510
489511
0 commit comments