Ein Regexp-Problem
Michael
- php
Hallo,
Mein Ziel wäre es, die folgende Abfrage, die einen Bildnamen nach nicht erlaubten Zeichen (Umlaute, Sonderzeichen, Leerzeichen, etc) sowie nach den erlaubten Endungen durchkämmt
if (!preg_match("/[1]([a-z0-9_-]+)(.){1}(gif|jpg|png)$/", $bildname))
{
---> Fehler
}
gleich mit einem entsprechenden preg_replace zu ersetzen, das die nicht erlaubten Zeichen sofort entfernt und wenigstens verkorkste Endungen, wie *.gift
oder ählnliches repariert
$ergebnis = preg_replace("/^([^a-z0-9])([^a-z0-9_-]+)...usw.", "", $bildname);
Und nur, wenn keine erlaubte Endung übrig bleibt, sollte der Benutzer eingreifen müssen.
Kann mir da jemand einen entscheidenden Tipp geben?
Wäre sehr dafür dankbar!
Michael
a-z0-9 ↩︎
Hallo Michael,
if (!preg_match("/[1]([a-z0-9_-]+)(.){1}(gif|jpg|png)$/", $bildname))
besser (da schneller) waere:
if(!preg_match('/[2][a-z0-9]+.(?:gif|jpg|png)$/',$bildname))
gleich mit einem entsprechenden preg_replace zu ersetzen,
das die nicht erlaubten Zeichen sofort entfernt und
wenigstens verkorkste Endungen, wie *.gift oder ählnliches
repariert
[...]
Und nur, wenn keine erlaubte Endung übrig bleibt, sollte
der Benutzer eingreifen müssen.
Ui, nicht einfach. Das grenzt schon an
Aehnlichkeits-Erkennung. Wenn du allerdings nicht auf
Genauigkeit bestehst, wuerde ich es so versuchen:
$text = preg_replace('/^([a-z0-9][a-z0-9]+).[^.]*(gif|jpg|png)[^.]*$/',"$1.$2",$text);
Aber sei ausdruecklich gewarnt! Das ist sehr ungenau. Wenn
du es besser willst, musst du mit einem richtigen Algorithmus
daran.
Gruesse,
CK
Hallo Christian,
Herzlichen Dank für deine Unterstützung. Nach einer langen Herumprobiererei kam ich auch allmählich zur Überzeugung, dass es so trivial nicht ist.
Schade nur, dass das Forum momentan so dahin kreucht und fleucht.
Grüße aus südlichen Gefilden
Michael
Hallo Michael,
Schade nur, dass das Forum momentan so dahin kreucht und
fleucht.
Jaa, ich weiss. Ich denke schon die ganze Zeit nach, wie man
eine derartige Ueberlastung verhindern kann... es scheint
so, als ob ein paar Unis und FHs (Uni Dortmund, FH Dortmund,
Uni Muenster, Uni Koeln) gerade Self vorstellen. Auf jedenfall
kommen von denen *sehr* viele Hits (bis zu 30k in einer
Stunde).
Gruesse,
CK
Hallo,
Schade nur, dass das Forum momentan so dahin kreucht und
fleucht.
Dabei war ich in einer meiner letzten Mails noch so des Lobes voll! Hätte ich besser nicht? ;-)
Jaa, ich weiss. Ich denke schon die ganze Zeit nach, wie man
eine derartige Ueberlastung verhindern kann...
Da das eine Art DDoS ist, wäre es sehr schwierig. Ist halt eine Lastspitze, muß man nehmen, wie sie kommen.
Finde es den Aufwand nicht wert, deswegen komplizierte und wenig effiziente Software zu basteln (ginge effizient nur mit Hardware, siehe Cisco.com et al, ist aber ein wenig teuer ;-)
es scheint
so, als ob ein paar Unis und FHs (Uni Dortmund, FH Dortmund,
Uni Muenster, Uni Koeln) gerade Self vorstellen. Auf jedenfall
kommen von denen *sehr* viele Hits (bis zu 30k in einer
Stunde).
Ich hatte erst ein Posting bei /. vermutet, war aber wohl nicht ;-)
Aber sei doch stolz:
Der Server ächzt zwar kräftig, aber er hält!
Da geben andere mit größerer Hardware schon bei weniger auf! ;-)
30.000 Hits/Std gehen IMHO wohl schon an die Substanz des Prozessors, ist schon sehr brutal. (Muß ja immerhin auch noch gzippen!)
Aber ich werde mal schauen, vielleicht hast Du ja irgendwo unabsichtlich eine Bremse eingebaut.
Wie leicht hat man mal Loops verkehrtrum geschachtelt und so was in der Art ;-)
so short
Christoph Zurnieden
Hallo Christoph,
Dabei war ich in einer meiner letzten Mails noch so des
Lobes voll! Hätte ich besser nicht? ;-)
Nee, besser nicht. Lob hab ich nicht verdient.
Jaa, ich weiss. Ich denke schon die ganze Zeit nach,
wie man eine derartige Ueberlastung verhindern kann...Da das eine Art DDoS ist, wäre es sehr schwierig.
Deshalb denke ich ja auch schon die ganze Zeit nach ;)
Ist halt eine Lastspitze, muß man nehmen, wie sie kommen.
Tja, aber trotzdem gibt es IMHO genug zu optimieren. Ich habe
eben heute nochmal dran gebastelt und drei Sachen
zusammengebaut: erstens werden, wenn mehr als 20 Verbindungen
in der Queque sind, die neuen abgelehnt:
if(head.clients.clientnum > MAX_CLIENT_NUM) {
fo_log(LOG_STD,__FILE__,__LINE__,"rejecting connection\n");
writen(connfd,"507 Server has to many connections\n",35);
close(connfd);
pthread_mutex_unlock(&head.clients.lock);
}
Ausserdem hat der poll-Thread jetzt grundsaetzlich eine
Prioritaets-Stufe weniger. Zuletzt werden Postings jetzt
nicht mehr durch einzelne write()-Calls 'rausgeschickt,
sondern die Antwort wird im Speicher zusammengesetzt und dann
mit einem einzigen write()-Call 'rausgeschickt. Damit werden
eine *Menge* Systemcalls eingespart.
Finde es den Aufwand nicht wert, deswegen komplizierte und
wenig effiziente Software zu basteln
Ich schon :) Ist halt eine Herausforderung.
es scheint
so, als ob ein paar Unis und FHs (Uni Dortmund, FH
Dortmund, Uni Muenster, Uni Koeln) gerade Self
vorstellen. Auf jedenfall kommen von denen *sehr* viele
Hits (bis zu 30k in einer Stunde).Ich hatte erst ein Posting bei /. vermutet, war aber wohl
nicht ;-)
*g* Nee, das waere etwas *sehr* unwahrscheinlich.
Aber sei doch stolz:
Der Server ächzt zwar kräftig, aber er hält!
Naja... nicht wirklich.
Da geben andere mit größerer Hardware schon bei weniger
auf! ;-)
Ja, *das* stimmt :)
30.000 Hits/Std gehen IMHO wohl schon an die Substanz des
Prozessors, ist schon sehr brutal. (Muß ja immerhin auch
noch gzippen!)
Der Prozessor ruht sich aus:
load averages: 0.48, 0.48, 0.42
Aber ich werde mal schauen, vielleicht hast Du ja irgendwo
unabsichtlich eine Bremse eingebaut.
Ja, waere nett. Hab die Aenderungen gerade eingecheckt.
Gruesse,
CK
Hallo,
Dabei war ich in einer meiner letzten Mails noch so des
Lobes voll! Hätte ich besser nicht? ;-)Nee, besser nicht. Lob hab ich nicht verdient.
Ach, ob verdient oder nicht, hin und wieder ein Lob schadet nicht ;-)
Jaa, ich weiss. Ich denke schon die ganze Zeit nach,
wie man eine derartige Ueberlastung verhindern kann...Da das eine Art DDoS ist, wäre es sehr schwierig.
Deshalb denke ich ja auch schon die ganze Zeit nach ;)
Dummerweise sind das aber reguläre Anfragen, die kann man ja nicht einfach ignorieren.
Ist halt eine Lastspitze, muß man nehmen, wie sie kommen.
Tja, aber trotzdem gibt es IMHO genug zu optimieren. Ich habe
eben heute nochmal dran gebastelt und drei Sachen
zusammengebaut: erstens werden, wenn mehr als 20 Verbindungen
in der Queque sind, die neuen abgelehnt:if(head.clients.clientnum > MAX_CLIENT_NUM) {
fo_log(LOG_STD,__FILE__,__LINE__,"rejecting connection\n");
writen(connfd,"507 Server has to many connections\n",35);
close(connfd);
pthread_mutex_unlock(&head.clients.lock);
}
Ist aber sehr brutal.
Könnte glatt von mir stammen ;-)
Ausserdem hat der poll-Thread jetzt grundsaetzlich eine
Prioritaets-Stufe weniger. Zuletzt werden Postings jetzt
nicht mehr durch einzelne write()-Calls 'rausgeschickt,
sondern die Antwort wird im Speicher zusammengesetzt und dann
mit einem einzigen write()-Call 'rausgeschickt. Damit werden
eine *Menge* Systemcalls eingespart.
Sehr schön.
Aber sei doch stolz:
Der Server ächzt zwar kräftig, aber er hält!Naja... nicht wirklich.
_Jetzt_ hatte ich erstmalig einen Timeout.
30.000 Hits/Std gehen IMHO wohl schon an die Substanz des
Prozessors, ist schon sehr brutal. (Muß ja immerhin auch
noch gzippen!)Der Prozessor ruht sich aus:
load averages: 0.48, 0.48, 0.42
?
Auha.
Wo ist denn da jetzt der Flaschenhals?
Anbindung?
Unwahrscheinlich, sind wohl eher die Platten.
Mmh...
Wieviel Speicher ist denn zur Verfügung? Kann man was puffern? Forumshauptdatei komplett z.B.?
Die Individualisierung ist sehr aufwendig aber klein, die könnte man z.B. gut buffern.
Und das größte Problem, wie immer:
Auslagerungsdatei?
Wie sieht der Speicherbedarf aus? Wird viel ausgelagert?
Aber ich werde mal schauen, vielleicht hast Du ja irgendwo
unabsichtlich eine Bremse eingebaut.Ja, waere nett. Hab die Aenderungen gerade eingecheckt.
Ja, angekommen. Mal schauen.
BTT (Falls der Ursprungsposter überhaupt noch mitliest ,-):
PHP bietet auch, evt als externe Lib, eine soundex() Funktion an. Ist zwar nur englisch, aber könnte genutzt werden.
Aber sei gewarnt: ist nicht einfach!
so short
Christoph Zurnieden
Moin Christoph,
Deshalb denke ich ja auch schon die ganze Zeit nach ;)
Dummerweise sind das aber reguläre Anfragen, die kann man
ja nicht einfach ignorieren.
Korrekt.
if(head.clients.clientnum > MAX_CLIENT_NUM) {
fo_log(LOG_STD,__FILE__,__LINE__,"rejecting connection\n");
writen(connfd,"507 Server has to many connections\n",35);
close(connfd);
pthread_mutex_unlock(&head.clients.lock);
}Ist aber sehr brutal.
Ja, ich weiss. Aber was soll ich sonst tun?
Wo ist denn da jetzt der Flaschenhals?
Im Server.
Das Problem ist, dass der poll-Thread jedesmal, wenn er
getimesliced werden koennte (im select()) direkt wieder
zurueck kehrt mit einer neuen Verbindung. Da hat halt ein
Worker-Thread kaum Gelegenheit, zu arbeiten.
Unwahrscheinlich, sind wohl eher die Platten.
Noe. Der Flaschenhals ist der Server.
Wieviel Speicher ist denn zur Verfügung?
Ein Gig.
Kann man was puffern? Forumshauptdatei komplett z.B.?
Das wird schon getan :)
Und das größte Problem, wie immer:
Auslagerungsdatei?
Wie sieht der Speicherbedarf aus? Wird viel ausgelagert?
Mem: 309M Active, 399M Inact, 218M Wired, 34M Cache, 112M Buf, 45M Free
Swap: 500M Total, 3400K Used, 497M Free
Nicht wirklich.
Gruesse,
CK
Hallo Christian,
ich hätte da mal so eine Frage...
Das Problem ist, dass der poll-Thread jedesmal, wenn er
getimesliced werden koennte (im select()) direkt wieder
zurueck kehrt mit einer neuen Verbindung. Da hat halt ein
Worker-Thread kaum Gelegenheit, zu arbeiten.
Und die Threads unter FreeBSD arbeiten nicht mit präempetiven, sondern mit kooperativen Multitasking? Das ließe sich zumindest aus Deiner Aussage und dem Sourcecode herleiten.
Grüße,
Christian
Hallo Christian,
Das Problem ist, dass der poll-Thread jedesmal, wenn er
getimesliced werden koennte (im select()) direkt wieder
zurueck kehrt mit einer neuen Verbindung. Da hat halt
ein Worker-Thread kaum Gelegenheit, zu arbeiten.Und die Threads unter FreeBSD arbeiten nicht mit
präempetiven, sondern mit kooperativen Multitasking?
Das hat damit gar nichts zu tun. Da bei der Maschine nicht
beide Prozessoren im Betrieb sind, koennen halt nicht mehrere
Threads gleichzeitig arbeiten, sondern sie muessen
nacheinander durchgearbeitet werden. Wie genau das passiert,
definiert der Scheduler (Round-Robin wird im Moment
eingesetzt). Aber *wann* getimesliced wird, haengt von vielen
Faktoren ab. Leider eben nicht, wenn derart viele
Verbindungen in der Listen-Queque haengen (da kehrt der
Thread halt direkt aus dem poll wieder zurueck. Und da das
durch ein Signal passiert, ist das toedlich fuer den
Scheduler).
Gruesse,
CK
Hallo Christian,
Das hat damit gar nichts zu tun.
ok. ;)
(da kehrt der
Thread halt direkt aus dem poll wieder zurueck. Und da das
durch ein Signal passiert, ist das toedlich fuer den
Scheduler).
Ich dachte, Du verwendest select? Das ist über Signale implementiert?
Naja, die Methode, die Du in Deinem anderen Posting beschrieben hast, klingt auf jeden Fall vielversprechend. :)
Grüße,
Christian
Hallo,
if(head.clients.clientnum > MAX_CLIENT_NUM) {
fo_log(LOG_STD,__FILE__,__LINE__,"rejecting connection\n");
writen(connfd,"507 Server has to many connections\n",35);
close(connfd);
pthread_mutex_unlock(&head.clients.lock);
}Ist aber sehr brutal.
Ja, ich weiss. Aber was soll ich sonst tun?
Diese Frage hast Du Dir schon selber beantwortet.
Ich sollte abends öfters mal weggehen, was? ;-)
Noe. Der Flaschenhals ist der Server.
Das bringt mich auf die Frage:
Warum läuft nur ein Prozessor?
Außerdem möchte ich auf die Mehrdeutbarkeit von "Server" hinweisen.
Denn, wenn mich nicht alles täuscht, läuft das Dingen noch über den Apachen, oder? >;->
Wieviel Speicher ist denn zur Verfügung?
Ein Gig.
Knapp, aber laut Auslastung wohl ausreichend.
Kann man was puffern? Forumshauptdatei komplett z.B.?
Das wird schon getan :)
Ja, so kann ich das auch! ;-)
Nein, den kompletten, geparsten Baum via SHM o.ä., der Archiver ist dann derjenige, der alles auf Platte sichert.
Das kann dann auch öfters geschehen, ein festes Zeitlimit eingestellt werden.
Dann mußt Du nur darauf achten, den Server nicht wieder beim Benchmarking abzuschießen ;-)
Und das größte Problem, wie immer:
Auslagerungsdatei?
Wie sieht der Speicherbedarf aus? Wird viel ausgelagert?Mem: 309M Active, 399M Inact, 218M Wired, 34M Cache, 112M Buf, 45M Free
Swap: 500M Total, 3400K Used, 497M Free
Da würde ich sagen: schieb noch einen Riegel rein und schalte den Swap ganz ab, auch im Kernel ;-)
so short
Christoph Zurnieden
PS:
Änderungen noch nicht im CVS?
CZ
Hallo Christoph,
Noe. Der Flaschenhals ist der Server.
Das bringt mich auf die Frage:
Warum läuft nur ein Prozessor?
Hab ich bereits mehrmals ausgefuehrt (langsam faengts an zu
nerven ;): von dem Board, das wir benutzen, gibt es in der
Serie einige wenige Boards, die aus bisher nicht
identifizierten Gruenden nicht laufen. Peter Wemm vermutet
einen Bug im SMP-Code, aber auch ein Bios-Update hat daran
nichts geaendert. Naja, wie dem auch sei, mit FreeBSD 5 soll
das Problem (laut Peter Wemm) gegessen sein.
Außerdem möchte ich auf die Mehrdeutbarkeit von "Server"
hinweisen. Denn, wenn mich nicht alles täuscht, läuft das
Dingen noch über den Apachen, oder? >;->
Ja, korrekt :)
Kann man was puffern? Forumshauptdatei komplett z.B.?
Das wird schon getan :)
Ja, so kann ich das auch! ;-)
Nein, den kompletten, geparsten Baum via SHM o.ä., der
Archiver ist dann derjenige, der alles auf Platte sichert.
Ueber SHM habe ich auch schonmal nachgedacht. Dann haette ich
den Flaschenhals Server nicht mehr, da er dann hoechstens
noch Postings annehmen muesste. Hm... mal nachlesen, welche
Risiken das alles birgt.
Dann mußt Du nur darauf achten, den Server nicht wieder
beim Benchmarking abzuschießen ;-)
*g* Jaaa. Ich war halt muede. Und deshalb hab ich halt an ein
paar Stellen vergessen, ein if($pid) um das fork() zu machen.
Da würde ich sagen: schieb noch einen Riegel rein und
schalte den Swap ganz ab, auch im Kernel ;-)
Nene. Nachts laufen ein paar Sachen (Backup,
Logfile-Auswertung, etc), die recht aufwendig sind. Da wird
der Speicher gebraucht :)
PS:
Änderungen noch nicht im CVS?
Doch, eigentlich schon. Moment *guck* Oh, vergessen :) Jetzt
ists drin.
Gruesse,
CK
Hallo,
Noe. Der Flaschenhals ist der Server.
Das bringt mich auf die Frage:
Warum läuft nur ein Prozessor?Hab ich bereits mehrmals ausgefuehrt (langsam faengts an zu
nerven ;)
Das war ja auch eine rethorische Frage ;-)
Siehe auch:
http://bsd.slashdot.org/article.pl?sid=02/12/09/1313255&mode=thread&tid=122
sowie das Posting:
http://bsd.slashdot.org/comments.pl?sid=47325&cid=4843664 mit den weiterführenden Links.
Der gesamte Thread ist wenig ergötzlich, aber zumindest kam keiner mit einem massivem Bug an.
Aber gut, eine Betaversion auf einer Produktionsmaschine ist natürlich nicht so empfehlenswert, bevor Du jetzt meinst, das ich das damit vorgeschlagen habe ;-)
Aber das mit dem Board ist nicht weiter peinlich, ich hatte bei meiner neuen Kiste die Auswahl zwischen einigen Graphikkarten und bekam eine ATI Rage 128 empfohlen. Läuft auch nicht schlecht, nur mußte ich feststellen, das sich der r128 Treiber mit dem BTTV Treiber meiner TV-Karte beißt ;-)
Außerdem möchte ich auf die Mehrdeutbarkeit von "Server"
hinweisen. Denn, wenn mich nicht alles täuscht, läuft das
Dingen noch über den Apachen, oder? >;->Ja, korrekt :)
An dem Grinsemännchen dahinter ersehe ich, das Du das Problem bereits erkannt hast, ja?
Ueber SHM habe ich auch schonmal nachgedacht. Dann haette ich
den Flaschenhals Server nicht mehr, da er dann hoechstens
noch Postings annehmen muesste. Hm... mal nachlesen, welche
Risiken das alles birgt.
Die üblichen.
Eher ist es die Frage, ob der Aufwand im ansprechendem Verhältniss zum Ergebnis steht.
Dann mußt Du nur darauf achten, den Server nicht wieder
beim Benchmarking abzuschießen ;-)*g* Jaaa. Ich war halt muede. Und deshalb hab ich halt an ein
paar Stellen vergessen, ein if($pid) um das fork() zu machen.
Sowas sollte genauso automatisch gehen, wie ein
p=malloc(sizeof(s));
if(p==NULL) EXIT("malloc failed");
;->
Da würde ich sagen: schieb noch einen Riegel rein und
schalte den Swap ganz ab, auch im Kernel ;-)Nene. Nachts laufen ein paar Sachen (Backup,
Logfile-Auswertung, etc), die recht aufwendig sind. Da wird
der Speicher gebraucht :)
Soviel?
Da läuft doch irgendetwas krumm, oder?
Weder für's Backup, noch für's Logfile-Auswerten sollte es nicht mehr als jeweils ca 1 MB Speicher brauchen!
PS:
Änderungen noch nicht im CVS?Doch, eigentlich schon. Moment *guck* Oh, vergessen :) Jetzt
ists drin.
Ah, Danggeschön ;-)
BTT:
Habe mal mit soundex() rumgespielt, lohnt den Aufwand nicht.
so short
Christoph Zurnieden
Moin Christoph,
[...]
Der gesamte Thread ist wenig ergötzlich, aber zumindest
kam keiner mit einem massivem Bug an.
Jupp, das kenne ich schon :) Habs auch schon gesogen, bin nur
noch nicht zum ausprobieren gekommen.
Aber gut, eine Betaversion auf einer Produktionsmaschine
ist natürlich nicht so empfehlenswert, bevor Du jetzt
meinst, das ich das damit vorgeschlagen habe ;-)
Keine Angst, habe ich nicht vermutet *g*
Aber das mit dem Board ist nicht weiter peinlich,
Oh, ich habs nie peinlich gefunden. Ich kann ja nix dafuer,
dass wir ausgerechnet eines von *den* Boards gekriegt haben.
Außerdem möchte ich auf die Mehrdeutbarkeit von
"Server" hinweisen. Denn, wenn mich nicht alles
täuscht, läuft das Dingen noch über den Apachen,
oder? >;->Ja, korrekt :)
An dem Grinsemännchen dahinter ersehe ich, das Du das
Problem bereits erkannt hast, ja?
Oehm... nein? Worauf willst du hinaus?
Ich weiss, dass die CGI-Schnittstelle eine ordentliche Bremse
ist, aber in diesem Fall ist sie nicht das Problem, falls du
darauf hinaus wolltest.
[... SHM ...]
Die üblichen.
Eher ist es die Frage, ob der Aufwand im ansprechendem
Verhältniss zum Ergebnis steht.
Ich denke schon. Das wuerde den Weg fuer weitere
Optimierungen oeffnen (vielleicht sogar mal eine
Implementation des fo_view-Teils als Apache-Modul)
Da würde ich sagen: schieb noch einen Riegel rein und
schalte den Swap ganz ab, auch im Kernel ;-)Nene. Nachts laufen ein paar Sachen (Backup,
Logfile-Auswertung, etc), die recht aufwendig sind. Da
wird der Speicher gebraucht :)Soviel?
Nein. Na gut, ich gebs zu: ich hab Angst davor, Swapping
abzuschalten.
BTT:
Habe mal mit soundex() rumgespielt, lohnt den Aufwand
nicht.
ACK :)
Gruesse,
CK
Moin!
Aber das mit dem Board ist nicht weiter peinlich,
Oh, ich habs nie peinlich gefunden. Ich kann ja nix dafuer,
dass wir ausgerechnet eines von *den* Boards gekriegt haben.
;)
- Sven Rautenberg
Hallo Christoph,
if(head.clients.clientnum > MAX_CLIENT_NUM) {
fo_log(LOG_STD,__FILE__,__LINE__,"rejecting connection\n");
writen(connfd,"507 Server has to many connections\n",35);
close(connfd);
pthread_mutex_unlock(&head.clients.lock);
}Ist aber sehr brutal.
Das habe ich jetzt abgeaendert. Da die Art des Problems ein
schlecht moegliches Timeslicing ist, habe ich jetzt einfach
den oberen Code-Block umgeaendert in
if(head.clients.clientnum > MAX_CLIENT_NUM) {
fo_log(LOG_STD,__FILE__,__LINE__,"handling request directly...\n");
handle_request((void *)connfd);
pthread_mutex_unlock(&head.clients.lock);
}
Damit sind zwei Sachen gegeben: ich *garantiere* dadurch,
dass an bestimmten Stellen Timeslicing moeglich ist und
zweitens kommen fuer die Zeit keine neuen Verbindungen dazu.
Gruesse,
CK