|
|
@ -6,6 +6,9 @@ |
|
|
#include <ctype.h> |
|
|
#include <ctype.h> |
|
|
#include <time.h> |
|
|
#include <time.h> |
|
|
#include <errno.h> |
|
|
#include <errno.h> |
|
|
|
|
|
#include <fcntl.h> |
|
|
|
|
|
#include <sys/types.h> |
|
|
|
|
|
#include <sys/stat.h> |
|
|
|
|
|
|
|
|
#include "server.h" |
|
|
#include "server.h" |
|
|
#include "socket.h" |
|
|
#include "socket.h" |
|
|
@ -114,16 +117,78 @@ serverRun(Server this) |
|
|
* @TODO: for now simply remove request and send not found. |
|
|
* @TODO: for now simply remove request and send not found. |
|
|
* Make this sane. |
|
|
* Make this sane. |
|
|
*/ |
|
|
*/ |
|
|
HttpMessage response = (HttpMessage)httpResponse404(); |
|
|
|
|
|
|
|
|
HttpRequest request = (HttpRequest)(reqq->msgs[j]); |
|
|
|
|
|
HttpMessage response = NULL; |
|
|
|
|
|
|
|
|
|
|
|
if (0 == strcmp("GET", request->method) && |
|
|
|
|
|
0 == strcmp("/me/", request->uri)) { |
|
|
|
|
|
const char foo[] = |
|
|
|
|
|
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" |
|
|
|
|
|
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" |
|
|
|
|
|
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" |
|
|
|
|
|
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" |
|
|
|
|
|
"<head><title>200 - OK</title></head>" |
|
|
|
|
|
"<body><h1>200 - OK</h1>" |
|
|
|
|
|
"<img src=\"http://localhost:11212/image/\" /></body>" |
|
|
|
|
|
"</html>"; |
|
|
|
|
|
char buffer[200]; |
|
|
|
|
|
time_t t; |
|
|
|
|
|
struct tm * tmp; |
|
|
|
|
|
|
|
|
|
|
|
response = (HttpMessage)new(HttpResponse, "HTTP/1.1", 200, "OK"); |
|
|
|
|
|
|
|
|
|
|
|
httpHeaderAdd(&(response->header), |
|
|
|
|
|
new(HttpHeader, "Content-Type", "text/html")); |
|
|
|
|
|
httpHeaderAdd(&(response->header), |
|
|
|
|
|
new(HttpHeader, "Server", "testserver")); |
|
|
|
|
|
|
|
|
|
|
|
response->type = HTTP_MESSAGE_BUFFERED; |
|
|
|
|
|
response->nbody = sizeof(foo) - 1; |
|
|
|
|
|
response->body = calloc(1, sizeof(foo)); |
|
|
|
|
|
strcpy(response->body, foo); |
|
|
|
|
|
|
|
|
|
|
|
sprintf(buffer, "%d", response->nbody); |
|
|
|
|
|
httpHeaderAdd(&(response->header), |
|
|
|
|
|
new(HttpHeader, "Content-Length", buffer)); |
|
|
|
|
|
|
|
|
|
|
|
t = time(NULL); |
|
|
|
|
|
tmp = localtime(&t); |
|
|
|
|
|
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); |
|
|
|
|
|
httpHeaderAdd(&(response->header), |
|
|
|
|
|
new(HttpHeader, "Date", buffer)); |
|
|
|
|
|
} |
|
|
|
|
|
else if (0 == strcmp("GET", request->method) && |
|
|
|
|
|
0 == strcmp("/image/", request->uri)) { |
|
|
|
|
|
char buffer[200]; |
|
|
|
|
|
time_t t; |
|
|
|
|
|
struct tm * tmp; |
|
|
|
|
|
|
|
|
|
|
|
response = (HttpMessage)new( |
|
|
|
|
|
HttpResponse, "HTTP/1.1", 200, "OK"); |
|
|
|
|
|
|
|
|
|
|
|
httpHeaderAdd(&(response->header), |
|
|
|
|
|
new(HttpHeader, "Content-Type", "image/jpeg")); |
|
|
|
|
|
httpHeaderAdd(&(response->header), |
|
|
|
|
|
new(HttpHeader, "Server", "testserver")); |
|
|
|
|
|
|
|
|
|
|
|
response->type = HTTP_MESSAGE_PIPED; |
|
|
|
|
|
|
|
|
|
|
|
t = time(NULL); |
|
|
|
|
|
tmp = localtime(&t); |
|
|
|
|
|
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %Z", tmp); |
|
|
|
|
|
httpHeaderAdd(&(response->header), |
|
|
|
|
|
new(HttpHeader, "Date", buffer)); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
response = (HttpMessage)httpResponse404(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (httpRequestHasKeepAlive((HttpRequest)reqq->msgs[j])) { |
|
|
|
|
|
(this->conns)[fd].keep_alive = 1; |
|
|
|
|
|
|
|
|
if (httpMessageHasKeepAlive(reqq->msgs[j])) { |
|
|
httpHeaderAdd( |
|
|
httpHeaderAdd( |
|
|
&(response->header), |
|
|
&(response->header), |
|
|
new(HttpHeader, "Connection", "Keep-Alive")); |
|
|
new(HttpHeader, "Connection", "Keep-Alive")); |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
(this->conns)[fd].keep_alive = 0; |
|
|
|
|
|
httpHeaderAdd( |
|
|
httpHeaderAdd( |
|
|
&(response->header), |
|
|
&(response->header), |
|
|
new(HttpHeader, "Connection", "Close")); |
|
|
new(HttpHeader, "Connection", "Close")); |
|
|
@ -145,18 +210,32 @@ serverRun(Server this) |
|
|
* handle writes |
|
|
* handle writes |
|
|
*/ |
|
|
*/ |
|
|
if (0 != ((this->fds)[i].revents & POLLOUT) && 0 < nwrites) { |
|
|
if (0 != ((this->fds)[i].revents & POLLOUT) && 0 < nwrites) { |
|
|
int size; |
|
|
|
|
|
|
|
|
HttpResponseWriter writer = |
|
|
|
|
|
(HttpResponseWriter)(this->conns)[fd].writer; |
|
|
|
|
|
HttpMessage message; |
|
|
|
|
|
|
|
|
events--; |
|
|
events--; |
|
|
nwrites--; |
|
|
nwrites--; |
|
|
|
|
|
|
|
|
size = streamWriterWrite((this->conns)[fd].writer, fd); |
|
|
|
|
|
|
|
|
message = (HttpMessage)streamWriterWrite(writer, fd); |
|
|
|
|
|
|
|
|
if ((this->conns)[fd].keep_alive) { |
|
|
|
|
|
(this->fds)[i].events &= ~POLLOUT; |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
serverCloseConn(this, i); |
|
|
|
|
|
|
|
|
while (NULL != message) { |
|
|
|
|
|
if (writer->state == HTTP_RESPONSE_NO) { |
|
|
|
|
|
if (httpMessageHasKeepAlive(message)) { |
|
|
|
|
|
delete(&message); |
|
|
|
|
|
if (0 == writer->response_queue->nmsgs) { |
|
|
|
|
|
(this->fds)[i].events &= ~POLLOUT; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
delete(&message); |
|
|
|
|
|
serverCloseConn(this, i); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
message = (HttpMessage)streamWriterWrite(writer, fd); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|