Crypt-MatrixSSL
view release on metacpan or search on metacpan
matrixssl-1-8-6-open/examples/httpsReflector.c view on Meta::CPAN
}
if ((rc = sslAccept(&cp, fd, keys, NULL, flags)) != 0) {
socketShutdown(fd);
continue;
}
flags = 0;
acceptAgain = 0;
}
/*
Read response
< 0 return indicates an error.
0 return indicates an EOF or CLOSE_NOTIFY in this situation
> 0 indicates that some bytes were read. Keep reading until we see
the /r/n/r/n from the GET request. We don't actually parse the request,
we just echo it back.
*/
c = buf;
readMore:
if ((rc = sslRead(cp, c, sizeof(buf) - (int)(c - buf), &status)) > 0) {
c += rc;
if (c - buf < 4 || memcmp(c - 4, "\r\n\r\n", 4) != 0) {
goto readMore;
}
} else {
if (rc < 0) {
fprintf(stdout, "sslRead error. dropping connection.\n");
}
if (rc < 0 || status == SSLSOCKET_EOF ||
status == SSLSOCKET_CLOSE_NOTIFY) {
socketShutdown(cp->fd);
sslFreeConnection(&cp);
acceptAgain = 1;
continue;
}
goto readMore;
}
/*
Done reading. If the incoming data starts with the quitString,
quit the application after this request
*/
if (memcmp(buf, quitString, min(c - buf,
(int)strlen(quitString))) == 0) {
quit++;
fprintf(stdout, "Q");
}
/*
If the incoming data starts with the againString,
we are getting a pipeline request on the same session. Don't
close and wait for new connection in this case.
*/
if (memcmp(buf, againString,
min(c - buf, (int)strlen(againString))) == 0) {
again++;
fprintf(stdout, "A");
} else {
fprintf(stdout, "R");
again = 0;
}
/*
Copy the canned response header and decoded data from socket as the
response (reflector)
*/
responseHdrLen = (int)strlen(responseHdr);
bytes = responseHdrLen + (int)(c - buf);
response = malloc(bytes);
memcpy(response, responseHdr, responseHdrLen);
memcpy(response + responseHdrLen, buf, c - buf);
/*
Send response.
< 0 return indicates an error.
0 return indicates not all data was sent and we must retry
> 0 indicates that all requested bytes were sent
*/
writeMore:
rc = sslWrite(cp, response, bytes, &status);
if (rc < 0) {
free(response);
fprintf(stdout, "Internal sslWrite error\n");
socketShutdown(cp->fd);
sslFreeConnection(&cp);
continue;
} else if (rc == 0) {
goto writeMore;
}
free(response);
/*
If we saw an /again request, loop up and process another pipelined
HTTP request. The /again request is supported in the httpsClient
example code.
*/
if (again) {
continue;
}
/*
Send a closure alert for clean shutdown of remote SSL connection
This is for good form, some implementations just close the socket
*/
sslWriteClosureAlert(cp);
/*
Close the socket and wait for next connection (new session)
*/
socketShutdown(cp->fd);
sslFreeConnection(&cp);
acceptAgain = 1;
}
/*
Close listening socket, free remaining items
*/
if (cp && cp->ssl) {
socketShutdown(cp->fd);
sslFreeConnection(&cp);
}
socketShutdown(listenfd);
matrixSslFreeKeys(keys);
matrixSslClose();
WSACleanup();
promptAndExit:
fprintf(stdout, "\n\nPress return to exit...\n");
getchar();
( run in 0.443 second using v1.01-cache-2.11-cpan-e93a5daba3e )