Websrv hibák Windows alatt (javítva)

Fórumok

Sziasztok!

Van egy programom, amit most kedvem szottyant windowson futtatni, és XMLRPC-vel csatlakozna egy szerverre. Ám a windows nekiállt engem azzal szórakoztatni, hogy minden hostot letagadott, míg végül kipróbáltam localhost-tal, és az eredmény:

operation: xmlrpcclientIni
description: gethostbyname failed
args:{STRING length=9 oref=5d2c20 "localhost"}
subsystem: XMLRPC
called from cgierror(99)
called from _blk_main_0(0)
called from xmlrpcclientini(75)
called from _blk_xmlrpcclientregister_0(0)
called from xmlrpcclientnew(54)
called from main(22)

Tényleg ennyit ér a windows, vagy valami elkerülte a figyelmemet? Mondanom sem kell, fullos net van alatta, de ha nem lenne, a localhostot tán akkor is illene feloldani. Benne is van amúgy a hosts file-ban, megnéztem azt is. Valakinek valami ötlet, mielőtt valami csúnyát mondok?

w

Hozzászólások

Nem amiatt van, hogy string a "localhost", kipróbáltam binary-val, pont ugyanaz lett az eredmény. Asszem, megüt a guta :D

w

Ha a socketdemo könyvtárban lévö gethost példa programot nem bapp_w32c vel, hanem bapp_w32_-vel buildeled, akkor
ugyanezt a hibát kapod (forditva a websrv/cgi-bin/cgi.exe bapp_w32c-vel linkeled, es csak ugy elinditod, latni fogod
hogy egyik esetben mukodik a gethostbyname, a masik esetben nem)
Linux alatt ezt a különbséget nem tapasztalod.A sejtes ilyenkor windows-on mindig az, hogy nincs
sikeres WSAStartup. Hogy erről bizonyságot szerezzünk,
bemásoljuk az scknames.cpp modult pl a websrv/cgi-bin-be , és berakjuk ezt,

......

if( he==NULL )
{ printf("wsa error:%d", WSAGetLastError(void));

akkor tényleg látjuk, hogy nem inicializálódik:

WSANOTINITIALISED 10093

Successful WSAStartup not yet performed.

Either the application has not called WSAStartup or WSAStartup failed. The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.

Ha most megkeressük a WSA inicializálást, akkor látjuk, hogy az az sckutils.cpp-ben van:

static int wsa_status=wsastartup();

Mivel ez egészen pontosan igy néz ki:

#ifdef WIN32 //automatic initialization
static int wsastartup()
{
WSADATA Data;
return WSAStartup(MAKEWORD(1,1),&Data);}
static int wsa_status=wsastartup();

....
Két lehetséges ok van, vagy nem látja a WIN32 definet, amelynek ellentmond az, hogy bapp_w32c-vel
működik, vagy linkelési okokból a modul nem töltödik be, és igy a statikus adattag nem inicializálódik.
Ha most az sckutils-t is bemásolod, és igy build-elsz, latni fogod hogy minden mukszik.

Szia Zoli!

Sajnos a probléma nem oldódott meg. Amit írtál, teljesen igaz, és a CGI-s programom is úgy kezdte, hogy csinált egy socketet, sőt be is másoltam az sckutils-t, meg az scknames-t is átírtam hibakód-visszaadósra, és a Windows büszkén jelenti, hogy WSAHOST_NOT_FOUND az eredménye a localhost lookup-jának - de csak akkor, ha websrv alól indítom CGI-ben. Sem önmagában az exe, sem Apache alatt CGI-ként futtatva nem hozza ezt az eredményt.
Köszi a segítséget, ha van még ötleted, szívesen látnám!

w

Összeszereltem a Windowst.
Előállítottam a hibát.
A hiba a websrv-től nem függ, tehát ez a program


function main()
    ? gethostbyname("localhost")

NIL-t ír ki.

Én is rájöttem, hogy a wsastartup hiányzik, workaround:


function main()
    socket() //felesleges, de behúzza a wsastartup-ot
    ? gethostbyname("localhost")

ez kiírja 127.0.0.1.

Majd csinálok valamit, hogy ez normáliasabban működjön.

--
CCC3

Itt írtam, hogy a probléma csak akkor jelentkezik, ha CGI-ben vagyok. És a workaround sem működik ennek megfelelően. Itt írtam, hogy a hibakód effektíve a WSAHOST_NOT_FOUND, tehát halálos komolysággal állítja, hogy nem tudja feloldani. A websrv-ben használt child() függvény lenne a ludas?

w

Hmm, ugyanakkor a

function main()

? gethostbyname("localhost")

return NIL

program az helyesen kiírja, hogy 127.0.0.1. Hmmm.

w

Egy másik tipp, hogyan lehet ilyen:

? gethostbyname("localhost")

kiírja, tehát normál programokban működik a resolver.

A hiba azonban egy CGI programban adódik, a CGI programok pedig a webszervertől öröklik a környezetüket. Hátha nem jó ez a környezet? Meg kéne nézni.

--
CCC3

Ha jól értem, az a baj, hogy a websrv által indított CGI programban nem működik a gethostbyname() vagyis a resolver. Windowsom most nincs, csak Linuxon próbáltam ki, természetesen működik.

Azért gondoltam, hogy érdemes a PATH-t ellenőrizni, mert hátha nincs meg neki egy DLL, ami éppen a feloldáshoz kellene.

--
CCC3

nem kell erőlködni vele, az m$ window$ (direkt kisbetűvel) egy nagy fos, mindenki tudja, nem értem, mit csodálkozol, csak a pénzre hajtanak, de egy kicsit is stabilan működő oprendszert nem bírnak kiadni, 5 percenként kép képernyő, stb., stb., mindannyian jól, ismerjük a jelenséget, biztosan nem kell bemutatni neked sem

Annyira talán nem lehet rossz a vindóz, hiszen használják éppen elegen. Sajnos nem tudom, hogyan kell konfigurálni a resolvert, de gyanítom, hogy a Linuxhoz hasonlóan.

Linuxon az /etc/host.conf-ban van megadva, hogy a resolver hogyan csinálja a névfeloldást. Tipikusan először a hosts filét nézi, utána probálkozik a névszerverekkel:

order hosts, bind

A /etc/hosts egy kis táblázat, amiben néhány közeli ismerős gép címe-neve szokott lenni. A névszerverek ip címét a /etc/resolv.conf-ba kell beírni.

Windowson a hosts fájl helye valami ilyesmi: windir\drivers\etc\hosts. Nem tudom, hogy van-e megfelelője a resolv.conf-nak.

Az esetedben nyilván rossz a resolver konfigurálása. Ha pl. nincs host.conf, resolv.conf (vagy rossz), vagy nincs hosts, vagy nem érhető el a névszerver, akkor semmilyen gépnévhez nem lehet ip címet szerezni.

Ilyenkor még mindig működik, ha direktbe beírod az ip címet, pl. 127.0.0.1

Van egy régről függőben maradt probléma: többeknek nem sikerült elindítani a karakteres CCC terminált. Szerintem annak is valami ilyesmi gyökere van, azaz nincs normálisan konfigurálva a resolver. Sajnos nem tudok konkrétabban segíteni, mert azóta sincs Windowsom.

--
CCC3

Üdv. Néktek:)

Nemtom lehet, hogy "zőcséget" írok (ne kövezzetek meg érte), de a localhost feloldáshoz nincs valami köze az alábbi tapasztalatnak?

Készítettem egy "autorun"-os CD-t amelyen van egy index.html és ezt indítja W32 alatt a rajtalévő autorun.exe

Az index.html-ben vannak hivatkozások .mp3 fájlokra (különféle előadások) amelyeket ugyebár a HTML fájlban lévő címsor egyik címére klikkelve lehet(ne) lejátszani.
Ám mégsem lehet.
A kérdés az, hogy miért, ugyanis a háttérként megadott gif-et sem tölti be a böngésző és a logo.gif-et sem jeleníti meg.
A címsor egyik címére klikkelve az Opera böngésző megnyit egy hibaablakot (1 új ablak) és azt írja, hogy a:
file://localhost/mp3files/filename.mp3 fájlt nem találhatót stb. stb. stb.

Ez van egy eXPert rendszeren. Viszont a másik eXPert rendszer meg szépenmmegjeleníti mind a háttér gif-et, mind a logo.gif-et és az mp3-at is lejátsza a winamp. Tehát a CD jól működik.
Linux alatt is lejátszható és "mindent" mutat az Opera/Mozilla/Konqueror böngésző. Csak egyetlen eXPert rend$zer nem hajlandó "jól kezelni" a CD-t.

Persze lehet, hogy semmi köze a localhost feloldáshoz, de ez ugrott be róla.

Sorry

ROTFLMAO :-DDD
Az autorun.inf-nek nem inkább direktben kéne megnyittatni a HTML-t a shell-el? Lehet, hogy újat mondok, de a böngészők meg tudják nyitni a html fileokat webserver nélkül is (ill. HTML-ben is lehet úgy linkelni, hogy file://warezkonyvtar/warez1.mp3).
It doesn't matter if you like my song as long as you can hear me sing

Bocsánat, ez rossz helyen van...
Kipróbáltam mind a kettőt (bapp_w32_ vel linkelve a socket demo gethost-jat , illetve a cgi-s környezetet), jól működik.
Visszatérve a cgi-s környezetre (utólag az ember mindig könnyen okos..), tök logikus a systemroot, mivel a socket kezelést a windows-on a winsock.dll biztosítja.
A rendszer a Loadlibrary() eljárással tölti be a dll-t, amely először az applikáció könyvtárában, ha ott nem találja a systemroot (esetleg windir ??)
, végül a sima path alatt keresi.

Hogy mennyi esze van egyeseknek - vagy pihent agya...

Tessen kedves utánanézni a file:// protokoll működésének, és utána dumálni, oks?

Csak a gyengébbek kedvéért (meg ma ilyen engedékeny vagyok):

A file:// egy lokális protokoll, nem használ gépneveket, ami utána áll, az mappanévként kerül feloldásra. Azaz a file://localhost/mp3files/filename.mp3 URL az a gyökértől (figyelem, nem a CD gyökerétől, hanem a rendszer gyökerétől) számított /localhost/mp3files/filename.mp3 fájlt keresi meg.
Tehát, ha valaki yól akar linkelni, akkor relatív címzést alkalmaz a HTML-eken belül, mert így a böngésző mindig az aktuális környezetre képezi le a fájlnevet.

Megvalósítástól függően a file:// protokoll képes 3 /-t is alkalmazni (file:///), ezt azért teszi, mert a standard URI-k {name}:// alakúak, ehhez jön még a gyökér '/' jelzése. Ez a szabványos, és ajánlott.

Bocs, ez rossz helyre ment.

Itt egyáltalán nem volt szó file:// protokollról. IP névfeloldásról volt szó. Ennek kapcsán 2 hibára is fény derült:

1) Egyes esetekben a websrv nem hívta meg a WSAStartup-ot.

2) A CGI részére tovább kell adni a SYSTEMROOT változót, ezt a websrv nem tette meg.

Mindkét hiba a winsock rendszer működésképtelenségét okozza. Mindkét dolog Windows specialitás, feature, hiba(?) ..., de inkább fogjuk fel természeti adottságnak.

--
CCC3

Akkor mégis az első sejtésem volt a jó: A CGI program környezete rossz, nevezetesen tovább kell adni a SYSTEMROOT változót is. Ne kérdezd miért, úgy jöttem rá, hogy egyenként adogattam neki a változókat, és ennél kezdett működni.

Most ez fenn van az svn-ben, nézd meg a 846. sort, és szólj vissza, hogy mi a helyzet.

--
CCC3

Kipróbáltam mind a kettőt (bapp_w32_ vel linkelve a socket demo gethost-jat , illetve a cgi-s környezetet), jól működik.
Visszatérve a cgi-s környezetre (utólag az ember mindig könnyen okos..), tök logikus a systemroot, mivel a socket kezelést a windows-on a winsock.dll biztosítja.
A rendszer a Loadlibrary() eljárással tölti be a dll-t, amely először az applikáció könyvtárában, ha ott nem találja a systemroot (esetleg windir ??)
, végül a sima path alatt keresi.

Kérdés, hogy milyen környezetet kell adni a CGI-knek. Most úgy van, hogy csak azokat a változókat kapja meg a CGI, amiket a websrv explicite beállít. És lám, egyszercsak kiderül, hogy valami hiányzik. Így a CGI-k (általános) paraméterezésére sem lehet a környezetet használni.

A másik lehetőség, hogy a websrv minden változót továbbad a CGI-nek. Akkor a websrv indítása előtt beállított környezettel paraméterezni lehetne a CGI-ket. Nem látom viszont, hogy az Apacheot így használnák.

--
CCC3

Csak emlékeztből irtam a keresési sorrendre vonatkozó megjegyzésemet. A pontos info itt található:
http://msdn2.microsoft.com/en-us/library/ms682586.aspx
Látható, hogy elég szofisztikált, és sok paramétertől függ.
Egyébként sok dll valójában com objektumot implementál, és a rendszer egy IUnknown-ból származtatott interface-en keresztül használja a funkciókat.
Ezek speciális dll-ek, és com objektumként regisztrálni kell őket a regsvr32-vel, mert a com objektumok hívása esetén a dll betöltését a com végzi el
a registry bejegyzések alapján. Konkrét tapasztalataim vannak, hogy milyen stochasztikus hibákhoz vezet ha nem regisztrálok le egy ilyen dll-t.
Időnként betölti, időnként nem, és egy csapásra megszűnik minden anomalia a regsvr32 után....

Nem állítom, hogy a winsock.dll ilyen. Mindazonáltal nálam szerepel mind a windows, mind a windows\system32 a path -ban, továbbá mind a két helyen
megvan ugyanaz a winsock.dll (nem én raktam mind két helyre , ugye mondanom sem kell...). Nos a tények makacs dolgok, és ezek a következők:

1. kiveszem a child folyamat environtmentjéből a systemroot-t, és berakom a path változót: gethostname jól működik, gethostbyname elhasal
2. visszarakom a systemroot-t , mindkettő jól műkodik .
De szerintem nem ez a lényeg. A lényeg az, hogy a socket-ek kezelése a unix-on kernel szinten történik, mig a windowson "shared libbel", amit dll-nek
hivnak.

Igazából nincs sok jelentősége az eredeti probléma szempontjából, de érdekelnek az architecturális dolgok. Unixon a teljes file managementst a kernel
végzi , és azok a funkciók amelyeket meghívunk, system call kategóriába tartoznak abban az értelemben, hogy azok kernel szinten hajtódnak végre.
A socketek a speciális filehez tartoznak. Ezért az a socket(),accept().. stb system call hívások. Én igy tudom. Ez nem igaz ?

Nagyon köszönöm a segítséget, a probléma meg van oldva! Valóban a SYSTEMROOT kellett neki, Zoli, Neked volt igazad :) Csak sikerült megtanítani a Windows-t a localhost feloldására... :D

w

Átírtam, de azért magamban azt gondolom, hogy nahát. Minimum illett volna egy hibaüzenetet kapnom, hogy nincs meg a winsock.dll, vagy hogy nem valódi névfeloldás adja a sikertelen eredményt, hanem egy kamu. Tényleg, ki adott nekem sikertelen névfeloldást, ha nem tudta a progi felrántani azt a DLL-t, ami a névfeloldásért felelős?

w

Régről ismert hiba, hogy nem jön rendes hibaüzenet, amikor nincs meg egy DLL. Azért gondoltam először arra, hogy a PATH nem jó. De szerintem itt nem DLL hiányzott neki, hanem nem tudta, hol keresse a ...\drivers\etc\hosts-ot. Ha már kitalálták a nagyszerű registryt, akkor a systemroot-ot is tárolhatnák benne. De nem érdemes feszegetni, így van és kész, most működik.

Gondolkodom azon, hogy a websrv továbbadja-e az _egész_ környezetet.

--
CCC3