{"id":452,"date":"2016-12-06T23:14:28","date_gmt":"2016-12-06T21:14:28","guid":{"rendered":"https:\/\/moijari.com\/?p=452"},"modified":"2019-11-22T01:54:03","modified_gmt":"2019-11-21T23:54:03","slug":"http-ja-https-palvelimen-paaohjelma","status":"publish","type":"post","link":"https:\/\/moijari.com\/?p=452","title":{"rendered":"HTTP ja HTTPS palvelimen p\u00e4\u00e4ohjelma"},"content":{"rendered":"<p>Kirjoitin uuden version terttu palvelimen p\u00e4\u00e4ohjelmasta. Nyt se pystyy vastaamaan my\u00f6s https viesteihin. Kokeiluversiossa ohjelma antaa satunnaislukuja, ja sit\u00e4 voi ajaa n\u00e4ist\u00e4 linkeist\u00e4 <a href=\"https:\/\/moijari.com:5001\">https:\/\/moijari.com:5001 <\/a>ja <a href=\"https:\/\/moijari.com:5001\">https:\/\/moijari.com:5001<\/a>.<\/p>\n<p>En viel\u00e4 ostanut certifikaattia moijari.com:ille, joten moijari.com nettiosoitteelle pit\u00e4\u00e4 luoda poikkeus, jos haluaa sit\u00e4 k\u00e4ytt\u00e4\u00e4 https:ll\u00e4.<\/p>\n<p>Ohjelman alussa ovat c tyyliset includelauseet, joilla luodaan erilaisia muuttujia, rakenteita ja funktioiden mallikutsuja:<\/p>\n<pre>#include &lt;stdio.h&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;errno.h&gt;\r\n#include &lt;openssl\/ssl.h&gt;\r\n#include &lt;sys\/types.h&gt;\r\n#include &lt;sys\/socket.h&gt;\r\n#include &lt;signal.h&gt;\r\n\r\n\/* See: http:\/\/h41379.www4.hpe.com\/doc\/83final\/ba554_90007\/ch04s03.html *\/\r\n\r\n#include &lt;netdb.h&gt;<\/pre>\n<p>Aiemmissa t\u00e4rkein on ehk\u00e4 tuo &lt;openssl\/ssl.h&gt;, joka k\u00e4yt\u00e4nn\u00f6ss\u00e4 kuvaa n\u00e4m\u00e4 t\u00e4m\u00e4n ohjelman SSL alkuiset rutiinit. See kappaleessa on itseasiassa nettisivu, jota k\u00e4ytin apuna rakennuksessa.<\/p>\n<pre>#define DEFAULT_PORT \"5001\"\r\n#define backlog 5\r\n\r\nint s,news;\r\nchar *cert_file = \"cert.pem\";\r\nchar *privatekey_file = \"key.pem\";\r\n\r\nchar htmlin[32768], html1[32768], html2[32768], *html;\r\n\r\nint usehttps=1;\r\nint usehttpthruhttps=0;<\/pre>\n<p>T\u00e4ss\u00e4 t\u00e4rkeimm\u00e4t ehk\u00e4 porttinumero, tiedostot, joista https avaimet ja sertifikaatti luetaan ja puskurit asiakkaan viestin lukuun ja kirjoitukseen (in=luku, 1 ja 2 kirjoitus).<\/p>\n<p>P\u00e4\u00e4ohjelman alussa m\u00e4\u00e4ritell\u00e4\u00e4n p\u00e4\u00e4ohjelman tarvitsemia muuttujia, ja kutsutaan https liittym\u00e4n &#8220;alustamiseen&#8221; liittyvi\u00e4 asioita.<\/p>\n<pre>void main(int argc,char *argv[])\r\n{\r\n\u00a0 int c, listenfd, status, bytes, addr_size,\r\n      len, callid;\r\n\u00a0 unsigned char timebuf[128];\r\n\r\n\u00a0 time_t now;\r\n\r\n\u00a0 SSL_METHOD *method=NULL;\r\n\u00a0 SSL_CTX *ctx=NULL;\r\n\u00a0 SSL *ssl;\r\n\u00a0 X509 *peer_cert;\r\n\r\n\u00a0 struct sockaddr sa_serv;\r\n\u00a0 struct sockaddr_in sa_cli;\r\n\u00a0 struct addrinfo hints;\r\n\u00a0 struct addrinfo *res;\r\n\r\n\u00a0 char buffer[32768],*p;\r\n\u00a0 callid=0;\r\n\r\n\u00a0 signal(SIGPIPE,SIG_IGN);\r\n\r\n\u00a0 procname=argv[0];\r\n#ifdef OLD1\r\n\u00a0 if(usehttps) {\r\n\u00a0\u00a0\u00a0 myport=HTTPS_PORT;\r\n\u00a0 } else {\r\n\u00a0\u00a0\u00a0 myport=DEFAULT_PORT;\r\n\u00a0 }\r\n#else\r\n\u00a0 myport=DEFAULT_PORT;<\/pre>\n<p>Alun kokonaislukumuuttujat (int) ovat perinteist\u00e4 liittym\u00e4\u00e4 varten. Perinteisess\u00e4 liittym\u00e4ss\u00e4 http tiedon siirto tehd\u00e4\u00e4n socket, bind, listen, accept, read- ja write kutsujen avulla. https tiedon siirto tehd\u00e4\u00e4n SSL alkuisten kutsujen avulla. edelleen struct komennolla m\u00e4\u00e4ritellyt muistialueet ovat perinteisi\u00e4 funktioita varten. signal() funktiolla ohitetaan ilmeisesti writen katketessa l\u00e4hetetty PIPe signaali. Procnameen talletetaan ohjelman nimi komentorivin ensimm\u00e4isest\u00e4 sanasta. Ohjelman nime\u00e4 k\u00e4ytet\u00e4\u00e4n virheilmoituksissa. Oletusportti on aina DEFAULT_PORT, jonka arvo on t\u00e4ll\u00e4 hetkell\u00e4 5001. J\u00e4rjestelm\u00e4funktioista saa kuvauksen komennolla $ man [komento], esimerkiksi $ man SSL_read tai $ man read.<\/p>\n<p>Seuraavassa p\u00e4tk\u00e4ss\u00e4 ovat ensimm\u00e4iset SSL-rutiinit, n\u00e4it\u00e4 ajetaan vain yhden kerran ohjelman suorituksen alussa. usehttps flagill\u00e4 m\u00e4\u00e4ritell\u00e4\u00e4n k\u00e4ytet\u00e4\u00e4nk\u00f6 ohjelmassa HTTPS:\u00e4\u00e4. Eli t\u00e4ss\u00e4 tapauksessa jos https on k\u00e4yt\u00f6ss\u00e4 kutsutaan SSL-funktiot SSL_library_init(),\u00a0 OpenSSL_add_ssl_algorithms(), SSL_load_error_strings(), SSLv23_server_method(), SSL_CTX_new(), SSL_CTX_use_certificate_file(), SSL_CTX_use_PrivateKey_file(), SSL_CTX_load_verify_locations.<\/p>\n<pre>\u00a0\u00a0 if(usehttps) {\r\n\r\n\u00a0\u00a0\u00a0 SSL_library_init();\r\n\r\n\u00a0\u00a0\u00a0 OpenSSL_add_ssl_algorithms();\r\n\r\n\u00a0\u00a0\u00a0 SSL_load_error_strings();\r\n\r\n\u00a0\u00a0\u00a0 if((method=(SSL_METHOD *)    \r\n      SSLv23_server_method())==NULL) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSLv3_server_method()\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 if((ctx=SSL_CTX_new(method))==NULL) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_CTX_new()\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 if(SSL_CTX_use_certificate_file(ctx,\r\n      cert_file, SSL_FILETYPE_PEM)&lt;=0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 if(SSL_CTX_use_PrivateKey_file(ctx,\r\n      privatekey_file, SSL_FILETYPE_PEM)&lt;=0) \\\r\n    {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_CTX_use_certificate()\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0 }\r\n\r\n    if(!SSL_CTX_load_verify_locations(ctx, \r\n      cert_file, NULL)) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_CTX_verify_locations()\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0 }<\/pre>\n<p>T\u00f6ss\u00f6 ensimm\u00e4iset perinteiset kutsut: n\u00e4it\u00e4 kutsutaan kanssa vain kerran: getaddrinfo, socket(),\u00a0 bind(),\u00a0 listen().<\/p>\n<pre>  memset(&amp;hints, 0, sizeof(hints);\r\n\u00a0 hints.ai_family = AF_UNSPEC;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0 hints.ai_socktype = SOCK_STREAM;\r\n\u00a0 hints.ai_flags = AI_PASSIVE;\r\n\r\n\u00a0 if ((status = getaddrinfo(NULL, myport, &amp;hints, &amp;res)) != 0) {\r\n\u00a0\u00a0\u00a0 fprintf(stderr, \"\\n%s: getaddrinfo error: %s\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 procname,gai_strerror(status));\r\n\u00a0\u00a0\u00a0 fprintf(stderr, \", error code %d\\n\", status);\r\n\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0 }\r\n\r\n\u00a0 if((s = socket(res-&gt;ai_family, res-&gt;ai_socktype, res-&gt;ai_protocol))==-1) {\r\n\u00a0\u00a0\u00a0 fprintf(stderr, \"%s: socket(), error: %d\\n\", procname, errno);\r\n\u00a0\u00a0\u00a0 perror(\"socket\");\r\n\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0 }\r\n\r\n\u00a0 if(bind(s, res-&gt;ai_addr, res-&gt;ai_addrlen)==-1) {\r\n\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot bind(), error: %d\\n\", procname, errno);\r\n\u00a0\u00a0\u00a0 perror(\"bind\");\r\n\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0 }\r\n\r\n\u00a0 freeaddrinfo(res);\r\n\r\n\u00a0 if((listenfd=listen(s,backlog))==-1) {\r\n\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot listen()\\n\", procname);\r\n\u00a0\u00a0\u00a0 perror(\"listen\");\r\n\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0 }<\/pre>\n<p>Seuraava on ns p\u00e4\u00e4luuppi, joka suoritetaan aina kun veppilomakkeelle kirjoitetaan tietoja ja painetaan nappulaa. T\u00e4ytetyt tiedot ovat read (tai SSL_read kutsulla luetussa htmlin muuttujassa ja l\u00e4hetett\u00e4v\u00e4 tieto kootaan htmlin:in perusteella html1 ja html 2 tauluihin. L\u00e4hetett\u00e4v\u00e4\u00e4 tietoa varten on kaksi taulua, koska taulu 1 sis\u00e4lt\u00e4\u00e4 rivin, jossa on taulun 2 merkkien lukum\u00e4\u00e4r\u00e4.<\/p>\n<p>Jokaisella weppitapahtumalla k\u00e4yd\u00e4\u00e4n l\u00e4pi accept(), SSL_new(), SSL_set_fd, SSL_accept(),<\/p>\n<pre>\u00a0for(;;) {\r\n\u00a0\u00a0\u00a0 usehttpthruhttps=0;\r\n\u00a0\u00a0\u00a0 addr_size=sizeof(sa_cli);\r\n\u00a0\u00a0\u00a0 news=accept(s, (struct sockaddr *)&amp;sa_cli, &amp;addr_size);\r\n\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\"\\nConnection from %x, port %d\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sa_cli.sin_addr.s_addr,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sa_cli.sin_port);\r\n\u00a0\u00a0\u00a0 if(usehttps) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if((ssl=SSL_new(ctx))==NULL) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_new()\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if(SSL_set_fd(ssl,news)!=1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_set_fd()\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if((status=SSL_accept(ssl))&lt;0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(status==-1 &amp;&amp; SSL_get_error(ssl,status)==1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\"\\nUsing http thru https\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 usehttpthruhttps=1;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_accept(), status: %d, SSL error: %d\",\u00a0 procname, status, SSL_get_error(ssl,status));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 if(usehttps &amp;&amp; usehttpthruhttps==0) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 peer_cert=SSL_get_peer_certificate(ssl);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if(peer_cert==NULL) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\", No peer certificate\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stdout);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\r\n<\/pre>\n<p>T\u00e4ss\u00e4 on ajateltu, ett\u00e4 jos SSL_accept kaatuu virheeseen 1, yhteys ei ole HTTPS yhteys vaan http yhteys. HTTP yhteyden merkiksi laitetaan muuttujaan usehttpthruhttps 1.<\/p>\n<p>Sitten onkin readin vuoro.<\/p>\n<pre>\u00a0\u00a0 memset(htmlin,0,sizeof(htmlin));\r\n\r\n\u00a0\u00a0 if(usehttps &amp;&amp; usehttpthruhttps==0) {\r\n\u00a0\u00a0\u00a0\u00a0 if((status=SSL_read(ssl, htmlin,\r\n       sizeof(htmlin)))&lt;1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_read(), status: %d, SSL_error: %d\", pr\\\r\nocname, status, SSL_get_error(ssl,status));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0 htmlin[bytes]='\\0';\r\n\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\"\\nreceived %d chars, \\\"%s\\\"\\n\", status, htmlin);\r\n\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0 if((bytes=read(news, htmlin, sizeof(htmlin)\r\n      ) )==-1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot read()\\n\",procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 perror(\"bind\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 htmlin[bytes]='\\0';\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\"\\nreceived %d chars,\\\"%s\\\"\\n\", bytes, htmlin);\r\n\u00a0  }<\/pre>\n<p>Eli k\u00e4ytet\u00e4\u00e4n SSL_read:id tai read:ia sen mukaan, onko kyseess\u00e4 https vai http yhteys. htmlin kentt\u00e4\u00e4n tulee asiakkaan kentt\u00e4muutokset ja nappula ja write:en tai SSL write:en muodostetaan html tai bootstrap tai vastaava lauseita.<\/p>\n<p>Ja viel\u00e4 lopuksi sivunmuodostus (ja write lauseet):<\/p>\n<pre>\u00a0\u00a0\u00a0 html=html1;\r\n\u00a0\u00a0\u00a0 html[0]='\\0';\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"HTTP\/1.0 200 OK\\r\\n\");\r\n\u00a0\u00a0\u00a0 html_printf(\"Location: \\r\\n\");\r\n\u00a0\u00a0\u00a0 html_printf(\"Server: %s\\r\\n\", programname);\r\n\u00a0\u00a0\u00a0 now = time(NULL);\r\n\u00a0\u00a0\u00a0 strftime(timebuf, sizeof(timebuf), HTMLTIMEFORMAT, gmtime(&amp;now));\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"Date: %s\\r\\n\", timebuf);\r\n\r\n\u00a0\u00a0\u00a0 html=html2;\r\n\u00a0\u00a0\u00a0 html[0]='\\0';\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"\\n&lt;!DOCTYPE html&gt;\\r\\n\");\r\n\u00a0\u00a0\u00a0 html_printf(\"&lt;html lang=\\\"fi\\\"&gt;\");\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"&lt;head&gt;\");\r\n\u00a0\u00a0\u00a0 html_printf(\"&lt;\/head&gt;\");\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"&lt;body&gt;\");\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"&lt;h1&gt;Hello, world!&lt;\/h1&gt;\");\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"&lt;\/body&gt;\");\r\n\r\n\u00a0\u00a0\u00a0 html_printf(\"&lt;\/html&gt;\");\r\n\r\n \u00a0\u00a0 len=strlen(html2);\r\n\u00a0\u00a0\u00a0 html=html1;\r\n\u00a0\u00a0\u00a0 html_printf(\"Content-Length: %d\",len\r\n\u00a0\u00a0\u00a0 html_printf(\"\\r\\n\\r\\n\");\r\n\r\n<\/pre>\n<p>Eli puskuriin 1 laitetaan protokolla, palvelin, kellonaika ja p\u00e4iv\u00e4m\u00e4\u00e4r\u00e4. Kakkospuskuriin laitetaan html lauseita sis\u00e4lt\u00e4v\u00e4 sivu (html_printf() on muuten aiemmassa postissa). Ykk\u00f6spuskuriin laitetaan kakkospuskurin pituuden sis\u00e4lt\u00e4v\u00e4 rivi ja seuraavassa write lauseet ykk\u00f6s ja kakkospuskurille.<\/p>\n<pre>\u00a0\u00a0 if(usehttps &amp;&amp; usehttpthruhttps==0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if((status=SSL_write(ssl, html1, strlen(html1)))&lt;1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_write(), status: %d, SSL error: %d\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 procname, status, SSL_get_error(ssl,status));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if((status=SSL_write(ssl, html2, strlen(html2)))&lt;1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot SSL_write(), status: %d, SSL error: %d\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 procname, status, SSL_get_error(ssl,status));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 } else {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if((bytes=write(news, html1, strlen(html1)))==-1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot write()\\n\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 perror(\"write\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 if((bytes=write(news, html2, strlen(html2)))==-1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot write()\\n\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 perror(\"write\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }<\/pre>\n<p>Kirjoitetaan ykk\u00f6s ja kakkospuskurit joko SSL_write:ll\u00e4 tai writell\u00e4().<\/p>\n<p>Ja lopetetaan t\u00e4m\u00e4 input output askel vapauttamalla tuo ssl ctx alue ja suljetaan kierroksen alussa acceptilta saatu news tiedosto.<\/p>\n<pre>\u00a0\u00a0\u00a0 if(usehttps &amp;&amp; usehttpthruhttps==0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stdout,\"\\nSSL connection using %s\", SSL_get_cipher(ssl));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 SSL_free(ssl);\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 if(close(news)==-1) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fprintf(stderr,\"\\n%s: cannot close()\\n\", procname);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 perror(\"close\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 fflush(stderr);\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 fprintf(stdout,\"\\ncallid: %d\\n\", callid++);\r\n\u00a0\u00a0\u00a0 fflush(stdout);\r\n  } \/* takaisin for(;;) luupin alkuun *\/<\/pre>\n<p>Jos meill\u00e4 on t\u00e4st\u00e4 for(;;) luupista lopetusmahdollisuus, lopetuksessa viel\u00e4 vapautetaan SSL_CTX_free komennolla ctx muuttuja.<\/p>\n<pre>SSL_CTX_free(ctx);<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Kirjoitin uuden version terttu palvelimen p\u00e4\u00e4ohjelmasta. Nyt se pystyy vastaamaan my\u00f6s https viesteihin. Kokeiluversiossa ohjelma antaa satunnaislukuja, ja sit\u00e4 voi ajaa n\u00e4ist\u00e4 linkeist\u00e4 https:\/\/moijari.com:5001 ja https:\/\/moijari.com:5001. En viel\u00e4 ostanut certifikaattia moijari.com:ille, joten moijari.com nettiosoitteelle pit\u00e4\u00e4 luoda poikkeus, jos haluaa sit\u00e4 k\u00e4ytt\u00e4\u00e4 https:ll\u00e4. Ohjelman alussa ovat c tyyliset includelauseet, joilla luodaan erilaisia muuttujia, rakenteita ja funktioiden&hellip; <a class=\"more-link\" href=\"https:\/\/moijari.com\/?p=452\">Continue reading <span class=\"screen-reader-text\">HTTP ja HTTPS palvelimen p\u00e4\u00e4ohjelma<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[6,5],"tags":[],"_links":{"self":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/452"}],"collection":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=452"}],"version-history":[{"count":12,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/452\/revisions"}],"predecessor-version":[{"id":1498,"href":"https:\/\/moijari.com\/index.php?rest_route=\/wp\/v2\/posts\/452\/revisions\/1498"}],"wp:attachment":[{"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moijari.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}