can parse http now
git-svn-id: file:///raid/svn-personal/tewi/trunk@16 8739d7e6-ffea-ec47-b151-bdff447c6205
This commit is contained in:
parent
44d467e9f0
commit
ddcd7e3817
|
@ -6,6 +6,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
char* cm_strcat(const char* a, const char* b);
|
char* cm_strcat(const char* a, const char* b);
|
||||||
|
char* cm_strcat3(const char* a, const char* b, const char* c);
|
||||||
char* cm_strdup(const char* str);
|
char* cm_strdup(const char* str);
|
||||||
char* cm_trimstart(const char* str);
|
char* cm_trimstart(const char* str);
|
||||||
char* cm_trimend(const char* str);
|
char* cm_trimend(const char* str);
|
||||||
|
|
|
@ -13,6 +13,13 @@ char* cm_strcat(const char* a, const char* b) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* cm_strcat3(const char* a, const char* b, const char* c) {
|
||||||
|
char* tmp = cm_strcat(a, b);
|
||||||
|
char* str = cm_strcat(tmp, c);
|
||||||
|
free(tmp);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
|
char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
|
||||||
|
|
||||||
char* cm_trimstart(const char* str) {
|
char* cm_trimstart(const char* str) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ include $(PWD)/Platform/$(PLATFORM).mk
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
.SUFFIXES: .c .o
|
.SUFFIXES: .c .o
|
||||||
|
|
||||||
OBJS = version.o main.o config.o server.o ssl.o
|
OBJS = version.o main.o config.o server.o ssl.o http.o
|
||||||
|
|
||||||
all: tewi$(EXEC)
|
all: tewi$(EXEC)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#define SOURCE
|
||||||
|
|
||||||
#include "tw_config.h"
|
#include "tw_config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
243
Server/http.c
Normal file
243
Server/http.c
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#define SOURCE
|
||||||
|
|
||||||
|
#include "tw_http.h"
|
||||||
|
|
||||||
|
#include "tw_server.h"
|
||||||
|
|
||||||
|
#include <cm_log.h>
|
||||||
|
#include <cm_string.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
void tw_free_request(struct tw_http_request* req) {
|
||||||
|
if(req->method != NULL) free(req->method);
|
||||||
|
if(req->path != NULL) free(req->path);
|
||||||
|
if(req->headers != NULL) {
|
||||||
|
int i;
|
||||||
|
for(i = 0; req->headers[i] != NULL; i++) free(req->headers[i]);
|
||||||
|
free(req->headers);
|
||||||
|
}
|
||||||
|
if(req->body != NULL) free(req->body);
|
||||||
|
if(req->version != NULL) free(req->version);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tw_http_parse(SSL* ssl, int sock, struct tw_http_request* req) {
|
||||||
|
char buffer[512];
|
||||||
|
char cbuf[2];
|
||||||
|
int phase = 0;
|
||||||
|
fd_set fds;
|
||||||
|
|
||||||
|
bool bad = false;
|
||||||
|
|
||||||
|
cbuf[1] = 0;
|
||||||
|
|
||||||
|
req->method = NULL;
|
||||||
|
req->path = NULL;
|
||||||
|
req->headers = NULL;
|
||||||
|
req->body = NULL;
|
||||||
|
req->version = NULL;
|
||||||
|
|
||||||
|
char* header = malloc(1);
|
||||||
|
header[0] = 0;
|
||||||
|
int nl = 0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(sock, &fds);
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = 5;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
int n = select(FD_SETSIZE, &fds, NULL, NULL, &tv);
|
||||||
|
if(n == 0) break;
|
||||||
|
int len = tw_read(ssl, sock, buffer, 512);
|
||||||
|
if(len <= 0) break;
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < len; i++) {
|
||||||
|
char c = buffer[i];
|
||||||
|
if(phase == 0) {
|
||||||
|
if(c == ' ') {
|
||||||
|
if(req->method == NULL) {
|
||||||
|
tw_free_request(req);
|
||||||
|
bad = true;
|
||||||
|
goto getout;
|
||||||
|
} else {
|
||||||
|
phase++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(req->method == NULL) {
|
||||||
|
req->method = malloc(1);
|
||||||
|
req->method[0] = 0;
|
||||||
|
}
|
||||||
|
cbuf[0] = c;
|
||||||
|
char* tmp = req->method;
|
||||||
|
req->method = cm_strcat(tmp, cbuf);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
} else if(phase == 1) {
|
||||||
|
if(c == ' ') {
|
||||||
|
if(req->path == NULL) {
|
||||||
|
tw_free_request(req);
|
||||||
|
bad = true;
|
||||||
|
goto getout;
|
||||||
|
} else {
|
||||||
|
phase++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(req->path == NULL) {
|
||||||
|
req->path = malloc(1);
|
||||||
|
req->path[0] = 0;
|
||||||
|
}
|
||||||
|
cbuf[0] = c;
|
||||||
|
char* tmp = req->path;
|
||||||
|
req->path = cm_strcat(tmp, cbuf);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
} else if(phase == 2) {
|
||||||
|
if(c == '\n') {
|
||||||
|
if(req->version == NULL) {
|
||||||
|
tw_free_request(req);
|
||||||
|
bad = true;
|
||||||
|
goto getout;
|
||||||
|
} else {
|
||||||
|
/* We have Method, Path, Version now */
|
||||||
|
|
||||||
|
if(strcmp(req->version, "HTTP/1.1") != 0 && strcmp(req->version, "HTTP/1.0") != 0) {
|
||||||
|
cm_log("HTTP", "Bad HTTP Version");
|
||||||
|
bad = true;
|
||||||
|
goto getout;
|
||||||
|
}
|
||||||
|
|
||||||
|
int j;
|
||||||
|
char* p = malloc(1);
|
||||||
|
p[0] = 0;
|
||||||
|
for(j = 0; req->path[j] != 0; j++) {
|
||||||
|
if(req->path[j] == '/') {
|
||||||
|
cbuf[0] = '/';
|
||||||
|
for(; req->path[j] != 0 && req->path[j] == '/'; j++)
|
||||||
|
;
|
||||||
|
j--;
|
||||||
|
} else {
|
||||||
|
cbuf[0] = req->path[j];
|
||||||
|
}
|
||||||
|
char* tmp = p;
|
||||||
|
p = cm_strcat(tmp, cbuf);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
free(req->path);
|
||||||
|
req->path = p;
|
||||||
|
|
||||||
|
int incr = 0;
|
||||||
|
p = malloc(1);
|
||||||
|
p[0] = 0;
|
||||||
|
for(j = 0;; j++) {
|
||||||
|
if(req->path[j] == '/' || req->path[j] == 0) {
|
||||||
|
char oldc = req->path[j];
|
||||||
|
cbuf[0] = oldc;
|
||||||
|
req->path[j] = 0;
|
||||||
|
|
||||||
|
char* pth = req->path + incr;
|
||||||
|
|
||||||
|
if(strcmp(pth, "..") == 0) {
|
||||||
|
int k;
|
||||||
|
if(p[strlen(p) - 1] == '/') p[strlen(p) - 1] = 0;
|
||||||
|
for(k = strlen(p) - 1; k >= 0; k--) {
|
||||||
|
if(p[k] == '/') {
|
||||||
|
p[k + 1] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(strlen(p) == 0) {
|
||||||
|
free(p);
|
||||||
|
p = cm_strdup("/");
|
||||||
|
}
|
||||||
|
} else if(strcmp(pth, ".") == 0) {
|
||||||
|
} else {
|
||||||
|
char* tmp = p;
|
||||||
|
p = cm_strcat3(tmp, pth, cbuf);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
incr = j + 1;
|
||||||
|
if(oldc == 0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(req->path);
|
||||||
|
req->path = p;
|
||||||
|
|
||||||
|
cm_log("HTTP", "Request: %s %s %s", req->method, req->path, req->version);
|
||||||
|
|
||||||
|
phase++;
|
||||||
|
}
|
||||||
|
} else if(c != '\r') {
|
||||||
|
if(req->version == NULL) {
|
||||||
|
req->version = malloc(1);
|
||||||
|
req->version[0] = 0;
|
||||||
|
}
|
||||||
|
cbuf[0] = c;
|
||||||
|
char* tmp = req->version;
|
||||||
|
req->version = cm_strcat(tmp, cbuf);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
} else if(phase == 3) {
|
||||||
|
if(c == '\n') {
|
||||||
|
nl++;
|
||||||
|
if(nl == 2) {
|
||||||
|
phase++;
|
||||||
|
goto getout;
|
||||||
|
} else {
|
||||||
|
if(req->headers == NULL) {
|
||||||
|
req->headers = malloc(sizeof(*req->headers));
|
||||||
|
req->headers[0] = NULL;
|
||||||
|
}
|
||||||
|
int j;
|
||||||
|
for(j = 0; header[j] != 0; j++) {
|
||||||
|
if(header[j] == ':') {
|
||||||
|
header[j] = 0;
|
||||||
|
j++;
|
||||||
|
for(; header[j] != 0 && (header[j] == ' ' || header[j] == '\t'); j++)
|
||||||
|
;
|
||||||
|
char* kv = header;
|
||||||
|
char* vv = header + j;
|
||||||
|
|
||||||
|
char** old = req->headers;
|
||||||
|
int k;
|
||||||
|
for(k = 0; old[k] != NULL; k++)
|
||||||
|
;
|
||||||
|
req->headers = malloc(sizeof(*req->headers) * (k + 3));
|
||||||
|
for(k = 0; old[k] != NULL; k++) req->headers[k] = old[k];
|
||||||
|
req->headers[k] = cm_strdup(kv);
|
||||||
|
req->headers[k + 1] = cm_strdup(vv);
|
||||||
|
req->headers[k + 2] = NULL;
|
||||||
|
free(old);
|
||||||
|
|
||||||
|
cm_log("HTTP", "Header: %s: %s", kv, vv);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(header);
|
||||||
|
header = malloc(1);
|
||||||
|
header[0] = 0;
|
||||||
|
}
|
||||||
|
} else if(c != '\r') {
|
||||||
|
nl = 0;
|
||||||
|
cbuf[0] = c;
|
||||||
|
char* tmp = header;
|
||||||
|
header = cm_strcat(tmp, cbuf);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getout:
|
||||||
|
free(header);
|
||||||
|
if(bad) {
|
||||||
|
tw_free_request(req);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#define SOURCE
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
|
|
||||||
|
@ -49,5 +52,8 @@ int main(int argc, char** argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
cm_log("Daemon", "Ready");
|
cm_log("Daemon", "Ready");
|
||||||
|
#ifndef __MINGW32__
|
||||||
|
signal(SIGCHLD, SIG_IGN);
|
||||||
|
#endif
|
||||||
tw_server_loop();
|
tw_server_loop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#define SOURCE
|
||||||
|
|
||||||
#include "tw_server.h"
|
#include "tw_server.h"
|
||||||
|
|
||||||
#include "tw_ssl.h"
|
#include "tw_ssl.h"
|
||||||
#include "tw_config.h"
|
#include "tw_config.h"
|
||||||
|
#include "tw_http.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -112,6 +115,22 @@ int tw_server_init(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t tw_read(SSL* ssl, int s, void* data, size_t len) {
|
||||||
|
if(ssl == NULL) {
|
||||||
|
return recv(s, data, len, 0);
|
||||||
|
} else {
|
||||||
|
return SSL_read(ssl, data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t tw_write(SSL* ssl, int s, void* data, size_t len) {
|
||||||
|
if(ssl == NULL) {
|
||||||
|
return send(s, data, len, 0);
|
||||||
|
} else {
|
||||||
|
return SSL_write(ssl, data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
struct pass_entry {
|
struct pass_entry {
|
||||||
int sock;
|
int sock;
|
||||||
|
@ -139,8 +158,10 @@ void tw_server_pass(int sock, bool ssl, int port) {
|
||||||
if(SSL_accept(s) <= 0) goto cleanup;
|
if(SSL_accept(s) <= 0) goto cleanup;
|
||||||
sslworks = true;
|
sslworks = true;
|
||||||
}
|
}
|
||||||
|
struct tw_http_request req;
|
||||||
|
int ret = tw_http_parse(s, sock, &req);
|
||||||
cleanup:
|
cleanup:
|
||||||
if(sslworks){
|
if(sslworks) {
|
||||||
SSL_shutdown(s);
|
SSL_shutdown(s);
|
||||||
}
|
}
|
||||||
SSL_free(s);
|
SSL_free(s);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#define SOURCE
|
||||||
|
|
||||||
#include "tw_ssl.h"
|
#include "tw_ssl.h"
|
||||||
|
|
||||||
#include "tw_config.h"
|
#include "tw_config.h"
|
||||||
|
|
25
Server/tw_http.h
Normal file
25
Server/tw_http.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef __TW_HTTP_H__
|
||||||
|
#define __TW_HTTP_H__
|
||||||
|
|
||||||
|
struct tw_http_request {
|
||||||
|
char* method;
|
||||||
|
char* path;
|
||||||
|
char* version;
|
||||||
|
char** headers;
|
||||||
|
char* body;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tw_http_response {
|
||||||
|
char** headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tw_http_tool {};
|
||||||
|
|
||||||
|
#ifdef SOURCE
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
int tw_http_parse(SSL* ssl, int sock, struct tw_http_request* req);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,7 +3,11 @@
|
||||||
#ifndef __TW_SERVER_H__
|
#ifndef __TW_SERVER_H__
|
||||||
#define __TW_SERVER_H__
|
#define __TW_SERVER_H__
|
||||||
|
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
int tw_server_init(void);
|
int tw_server_init(void);
|
||||||
void tw_server_loop(void);
|
void tw_server_loop(void);
|
||||||
|
size_t tw_read(SSL* ssl, int s, void* data, size_t len);
|
||||||
|
size_t tw_write(SSL* ssl, int s, void* data, size_t len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#define SOURCE
|
||||||
|
|
||||||
#include "tw_version.h"
|
#include "tw_version.h"
|
||||||
|
|
||||||
const char* tw_version = "0.00";
|
const char* tw_version = "0.00";
|
||||||
|
|
Loading…
Reference in New Issue
Block a user