📄 http.c
字号:
/* * The olsr.org Optimized Link-State Routing daemon (olsrd) * * Copyright (c) 2004, Thomas Lopatic (thomas@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of olsr.org, olsrd nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: http.c,v 1.7 2007/09/17 21:57:06 bernd67 Exp $ */#include "link.h"#include "plugin.h"#include "lib.h"#include "os_unix.h"#include "http.h"#include "glua.h"#include "glua_ext.h"#include <string.h>#include <stdarg.h>// #define TAS_BLOCK#define DEF_CONFIG_ROOT_DIR "/etc/tas"#define DEF_CONFIG_WORK_DIR "/var/run/tas"#define DEF_CONFIG_PORT 1979#define DEF_CONFIG_ADDR "127.0.0.1"#define DEF_CONFIG_INDEX_FILE "index.html"#define DEF_CONFIG_USER NULL#define DEF_CONFIG_PASSWORD NULL#define DEF_CONFIG_SESS_TIME 600#define DEF_CONFIG_PUB_DIR "pub"#define DEF_CONFIG_QUANTUM 30#define DEF_CONFIG_MESS_TIME 60#define DEF_CONFIG_MESS_LIMIT 100static struct ipAddr confAddr;static int confPort;static char *confRootDir;static char *confWorkDir;static char *confIndexFile;static char *confUser;static char *confPassword;static int confSessTime;static char *confPubDir;static int confQuantum;static int confMessTime;static int confMessLimit;static struct{ unsigned int sessId; unsigned char key[16];} cookieStruct;#define MAX_CONN 5static int numConn;static struct connInfo *conn[MAX_CONN];struct sessInfo{ unsigned int id; void *data; struct timeStamp time;};#define MAX_SESS 10static int numSess;static struct sessInfo *sess[MAX_SESS];static struct extMap{ char *ext; char *type; int state;}extMap[] ={ { ".png", "image/png", STATE_FILE }, { ".gif", "image/gif", STATE_FILE }, { ".jpg", "image/jpg", STATE_FILE }, { ".lsp", "text/html; charset=iso-8859-1", STATE_LSP }, { ".html", "text/html; charset=iso-8859-1", STATE_FILE }, { ".htm", "text/html; charset=iso-8859-1", STATE_FILE }, { NULL, NULL, 0 }};struct tasMessage{ struct tasMessage *next; struct timeStamp time; char *service; char *string; char *from;};static struct tasMessage *firstTasMsg, *lastTasMsg;static int numTasMsg;static void rc4(unsigned char *buff, int len, unsigned char *key, int keyLen){ int i, m, n; unsigned char state[256]; unsigned char aux; for (i = 0; i < 256; i++) state[i] = (unsigned char)i; m = 0; n = 0; for (i = 0; i < 256; i++) { m = (m + key[n] + state[i]) & 255; aux = state[i]; state[i] = state[m]; state[m] = aux; n = (n + 1) % keyLen; } m = 0; n = 0; for (i = 0; i < len; i++) { n = (n + 1) & 255; m = (m + state[n]) & 255; aux = state[n]; state[n] = state[m]; state[m] = aux; buff[i] ^= state[(state[m] + state[n]) & 255]; }}static int mapHexDigit(int digit){ if (digit >= 'A' && digit <= 'F') return digit + 10 - 'A'; if (digit >= 'a' && digit <= 'f') return digit + 10 - 'a'; if (digit >= '0' && digit <= '9') return digit - '0'; return -1;}static int addHexDigit(int *val, int digit){ digit = mapHexDigit(digit); if (digit < 0) return -1; *val = (*val << 4) | digit; return 0;}static void encHexString(char *hexString, unsigned char *hex, int len){ static char *map = "0123456789ABCDEF"; while (len-- > 0) { *hexString++ = map[*hex >> 4]; *hexString++ = map[*hex++ & 15]; } *hexString = 0;}static int decHexString(unsigned char *hex, char *hexString, int len){ int val; while (len-- > 0) { val = 0; if (addHexDigit(&val, *hexString++) < 0 || addHexDigit(&val, *hexString++) < 0) return -1; *hex++ = (unsigned char)val; } return 0;}static int decBase64(unsigned char *out, char *in){ static int map[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; int state; unsigned int val; int digit; val = 0; state = 0; while (*in != 0 && *in != '=') { digit = map[(unsigned char)*in++]; if (digit < 0) return -1; val = (val << 6) | digit; if (state == 1) *out++ = (unsigned char)(val >> 4); else if (state == 2) *out++ = (unsigned char)(val >> 2); else if (state == 3) *out++ = (unsigned char)val; state = (state + 1) & 3; } return 0;}static void initInOutBuff(struct inOutBuff *buff){ buff->off = 0; buff->len = 0; buff->cont = 0; buff->first = NULL; buff->last = NULL;}static struct connInfo *newConnInfo(struct fileId *sockId, struct ipAddr *addr){ struct connInfo *info = allocMem(sizeof (struct connInfo)); info->sockId = sockId; info->addr = addr; info->state = STATE_REQUEST; initInOutBuff(&info->read); initInOutBuff(&info->write[0]); initInOutBuff(&info->write[1]); initInOutBuff(&info->write[2]); info->which = 0; info->flags = FLAG_READ | FLAG_WRITE; info->buff = NULL; info->buffUsed = 0; info->buffTotal = 0; info->firstHead = NULL; info->lastHead = NULL; info->verb = NULL; info->host = NULL; info->path = NULL; info->para = NULL; info->proto = NULL; info->contType = "text/html; charset=iso-8859-1"; info->contLen = -1; info->newSess = NULL; info->authUser = NULL; info->authPass = NULL; return info;}static void freeInOutBuff(struct inOutBuff *buff){ struct chunk *walker, *next; for (walker = buff->first; walker != NULL; walker = next) { next = walker->next; freeMem(walker); }}static void freeWorkBuff(struct workBuff *buff){ struct workBuff *next; while (buff != NULL) { next = buff->next; freeMem(buff); buff = next; }}static void freeConnInfo(struct connInfo *info){ freeMem(info->sockId); freeMem(info->addr); freeInOutBuff(&info->read); freeInOutBuff(&info->write[0]); freeInOutBuff(&info->write[1]); freeInOutBuff(&info->write[2]); freeWorkBuff(info->buff); freeMem(info);}static struct sessInfo *newSessInfo(void){ static unsigned int sessId = 0; struct sessInfo *info; info = allocMem(sizeof (struct sessInfo)); info->id = sessId++; info->data = NULL; os_now(&info->time); debug(DEBUG_SESSION, "new session, id = %u\n", info->id); return info;}void *allocBuff(struct connInfo *info, int len){ struct workBuff *buff; unsigned char *res; debug(DEBUG_CONNECTION, "%d bytes of buffer space requested\n", len); if (info->buff != NULL) debug(DEBUG_CONNECTION, "existing buffer, size = %d bytes, used = %d bytes, remaining = %d bytes\n", info->buffTotal, info->buffUsed, info->buffTotal - info->buffUsed); else debug(DEBUG_CONNECTION, "no existing buffer\n"); if (info->buff == NULL || len > info->buffTotal - info->buffUsed) { info->buffTotal = (len > BUFF_SIZE) ? len : BUFF_SIZE; info->buffUsed = 0; debug(DEBUG_CONNECTION, "new buffer of %d bytes\n", info->buffTotal); buff = allocMem(sizeof (struct workBuff) + info->buffTotal); buff->data = (unsigned char *)(buff + 1); buff->next = info->buff; info->buff = buff; } res = info->buff->data + info->buffUsed; info->buffUsed += len; debug(DEBUG_CONNECTION, "used = %d bytes, remaining = %d bytes\n", info->buffUsed, info->buffTotal - info->buffUsed); return res;}void httpInit(void){ parseIpAddr(&confAddr, DEF_CONFIG_ADDR); confPort = DEF_CONFIG_PORT; confRootDir = DEF_CONFIG_ROOT_DIR; confWorkDir = DEF_CONFIG_WORK_DIR; confIndexFile = DEF_CONFIG_INDEX_FILE; confUser = DEF_CONFIG_USER; confPassword = DEF_CONFIG_PASSWORD; confSessTime = DEF_CONFIG_SESS_TIME; confPubDir = DEF_CONFIG_PUB_DIR; confQuantum = DEF_CONFIG_QUANTUM; confMessTime = DEF_CONFIG_MESS_TIME; confMessLimit = DEF_CONFIG_MESS_LIMIT; getRandomBytes(cookieStruct.key, 16);}int httpSetAddress(const char *addrStr, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ if (parseIpAddr(&confAddr, addrStr) < 0) { error("invalid IP address: %s\n", addrStr); return -1; } return 0;}int httpSetPort(const char *portStr, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ unsigned int port; if (stringToInt(&port, portStr) < 0) { error("invalid port number: %s\n", portStr); return -1; } if (port > 65535) { error("invalid port number: %u\n", port); return -1; } confPort = port; return 0;}int httpSetRootDir(const char *rootDir, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ if (checkAbsPath(rootDir) < 0) { error("root directory (%s) requires an absolute path\n", rootDir); return -1; } confRootDir = myStrdup(rootDir); return 0;}int httpSetWorkDir(const char *workDir, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ if (checkAbsPath(workDir) < 0) { error("work directory (%s) requires an absolute path\n", workDir); return -1; } confWorkDir = myStrdup(workDir); return 0;}int httpSetIndexFile(const char *indexFile, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ confIndexFile = myStrdup(indexFile); return 0;}int httpSetUser(const char *user, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ confUser = myStrdup(user); return 0;}int httpSetPassword(const char *password, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ confPassword = myStrdup(password); return 0;}int httpSetSessTime(const char *timeStr, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ unsigned int time; if (stringToInt(&time, timeStr) < 0) { error("invalid timeout: %s\n", timeStr); return -1; } if (time > 86400) { error("invalid timeout: %u\n", time); return -1; } confSessTime = time; return 0;}int httpSetPubDir(const char *pubDir, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ confPubDir = myStrdup(pubDir); return 0;}int httpSetQuantum(const char *quantumStr, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ unsigned int quantum; if (stringToInt(&quantum, quantumStr) < 0) { error("invalid quantum: %s\n", quantumStr); return -1; } if (quantum > 100) { error("invalid quantum: %u\n", quantum); return -1; } confQuantum = quantum; return 0;}int httpSetMessTime(const char *timeStr, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ unsigned int time; if (stringToInt(&time, timeStr) < 0) { error("invalid timeout: %s\n", timeStr); return -1; } if (time > 365 * 86400) { error("invalid timeout: %u\n", time); return -1; } confMessTime = time; return 0;}int httpSetMessLimit(const char *limitStr, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused))){ unsigned int limit; if (stringToInt(&limit, limitStr) < 0) { error("invalid limit: %s\n", limitStr); return -1; } if (limit > 1000000) { error("invalid limit: %u\n", limit); return -1; } confMessLimit = limit; return 0;}int httpSetup(void){ int i; if (createMainSocket(&confAddr, confPort) < 0) { error("cannot create main socket\n"); return -1; } numConn = 0; for (i = 0; i < MAX_CONN; i++) conn[i] = NULL; numSess = 0; for (i = 0; i < MAX_SESS; i++) sess[i] = NULL; firstTasMsg = NULL; lastTasMsg = NULL; numTasMsg = 0; return 0;}static int readConn(struct connInfo *info){ struct inOutBuff *read = &info->read; int readLen; struct chunk *chunk; for (;;) { if (read->last == NULL || read->len == CHUNK_SIZE) { chunk = allocMem(sizeof (struct chunk)); chunk->next = NULL; if (read->last != NULL) read->last->next = chunk;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -