static void redirect_to_ssl(struct mg_connection *conn, const struct mg_request_info *request_info) { const char *p, *host = mg_get_header(conn, "Host"); // u_int16_t port = ntop->get_HTTPserver()->get_port(); if(host != NULL && (p = strchr(host, ':')) != NULL) { mg_printf(conn, "HTTP/1.1 302 Found\r\n" "Location: https://%.*s:%u/%s\r\n\r\n", (int) (p - host), host, ntop->getPrefs()->get_https_port(), request_info->uri); } else { mg_printf(conn, "%s", "HTTP/1.1 500 Error\r\n\r\nHost: header is not set"); } }
static int ev_handler(struct mg_connection *conn, enum mg_event ev) { std::string uri; const char* secret = NULL; const char* requested_with = NULL; int retval = MG_FALSE; switch (ev) { case MG_REQUEST: boinc_resolve_filename_s(conn->uri+1, uri); mg_send_file( conn, uri.c_str(), "Access-Control-Allow-Origin: *\r\n" ); return MG_MORE; case MG_AUTH: retval = MG_FALSE; if (!webserver_debugging) { secret = mg_get_header(conn, "Secret"); if (secret) { if (0 == strcmp(secret, webserver_secret)) { retval = MG_TRUE; } } requested_with = mg_get_header(conn, "X-Requested-With"); if (requested_with) { retval = MG_TRUE; } } else { retval = MG_TRUE; } return retval; default: return MG_FALSE; } }
// Get session object for the connection. Caller must hold the lock. static struct session *get_session(const struct mg_connection *conn) { int i; const char *cookie = mg_get_header(conn, "Cookie"); char session_id[33]; time_t now = time(NULL); mg_get_cookie(cookie, "session", session_id, sizeof(session_id)); for (i = 0; i < MAX_SESSIONS; i++) { if (sessions[i].expire != 0 && sessions[i].expire > now && strcmp(sessions[i].session_id, session_id) == 0) { break; } } return i == MAX_SESSIONS ? NULL : &sessions[i]; }
void atlas::http::detail::basic_function::serve( uri_parameters_type match, mg_connection *conn, uri_callback_type success, uri_callback_type failure ) const { const char *token = mg_get_header(conn, "Authorization"); bool authorised = false; try { authorised = m_auth_function((token == nullptr) ? "" : token, match); } catch(const std::exception& e) { log::error("atlas::http::detail::basic_function::serve") << "error checking authentication token: " << e.what(); http::error(403, "checking authentication", conn); success(); } if(authorised) { try { m_serve(conn, match, success, failure); } catch(const http::exception& e) { log::error("atlas::http::detail::basic_function::serve") << "error in http handler returned to client: " << e.what(); http::error(e.code(), e.what(), conn); success(); } catch(const std::exception& e) { log::error("atlas::http::detail::basic_function::serve") << "error in http handler: " << e.what(); http::error(500, "unknown error", conn); success(); } } else { http::error(403, "unauthorised", conn); success(); } }
static int event_handler(struct mg_connection *conn, enum mg_event ev) { if(ev == MG_REQUEST) { if(conn->is_websocket) { ws_handler(conn, FLAG_WS_DATA); return MG_TRUE; } else { int ret = web_handler(conn); if(ret < 0) { const char* srvfilepath = strlen(conn->uri) <= 1 ? "index.html" : conn->uri; if(srvfilepath[0] == '/') srvfilepath++; mg_send_file(conn, srvfilepath, NULL); return MG_MORE; } return MG_TRUE; } } else if(ev == MG_WS_CONNECT) { conn->connection_param = malloc(25); const char* key = mg_get_header(conn, "Sec-WebSocket-Key"); strncpy(conn->connection_param, key, 24); char *p = (char*)(conn->connection_param); p[24] = '\0'; ws_handler(conn, FLAG_WS_OPEN); return MG_TRUE; } else if(ev == MG_CLOSE) { if(conn->is_websocket) { ws_handler(conn, FLAG_WS_CLOSE); } free(conn->connection_param); return MG_TRUE; } else if(ev == MG_AUTH) { return MG_TRUE; } return MG_FALSE; }
static void test_post(struct mg_connection *conn, const struct mg_request_info *ri) { const char *cl; char *buf; int len; mg_printf(conn, "%s", standard_reply); if (strcmp(ri->request_method, "POST") == 0 && (cl = mg_get_header(conn, "Content-Length")) != NULL) { len = atoi(cl); if ((buf = malloc(len)) != NULL) { mg_write(conn, buf, len); free(buf); } } }
static void test_get_header(struct mg_connection *conn, const struct mg_request_info *ri) { const char *value; int i; mg_printf(conn, "%s", standard_reply); printf("HTTP headers: %d\n", ri->num_headers); for (i = 0; i < ri->num_headers; i++) { printf("[%s]: [%s]\n", ri->http_headers[i].name, ri->http_headers[i].value); } value = mg_get_header(conn, "Host"); if (value != NULL) { mg_printf(conn, "Value: [%s]", value); } }
static int api_callback(struct mg_connection *conn) { struct mg_request_info *ri = mg_get_request_info(conn); char post_data[100] = ""; ASSERT(ri->user_data == (void *) 123); ASSERT(ri->num_headers == 2); ASSERT(strcmp(mg_get_header(conn, "host"), "blah.com") == 0); ASSERT(mg_read(conn, post_data, sizeof(post_data)) == 3); ASSERT(memcmp(post_data, "b=1", 3) == 0); ASSERT(ri->query_string != NULL); ASSERT(ri->remote_ip > 0); ASSERT(ri->remote_port > 0); ASSERT(strcmp(ri->http_version, "1.0") == 0); mg_printf(conn, "HTTP/1.0 200 OK\r\n\r\n"); return 1; }
/* get json_data value form post data. */ char * get_post_data(struct mg_connection *conn) { char *buff = NULL; size_t buf_len; const char *cl; cl = mg_get_header(conn, "Content-Length"); if ((!strcmp(conn->request_method, "POST") || (!strcmp(conn->request_method, "PUT"))&& cl != NULL)) { buf_len = atoi(cl)+1; buff = malloc(buf_len); memset(buff,0,buf_len); memcpy(buff,conn->content,conn->content_len); } return buff; /*should free outside*/ }
Request::Request(struct mg_connection *connection_, const struct mg_request_info *request_) : connection(connection_), request(request_) { url = string(request->uri); method = string(request->request_method); // Downloading POST data ostringstream postData; if (mg_get_header(connection, "Content-Type") != NULL) { int n; char post[1024]; while (n = mg_read(connection, post, sizeof(post))) { postData.write(post, n); } } data = postData.str(); }
//////////////////////////////////////////////////////////////// ///Function to send a simple text ajax rely void Executive::ajaxReply(struct mg_connection *conn, const struct mg_request_info *request_info) { try{ const char * clength; char h1[] = "Content-Length"; clength = mg_get_header(conn,h1); //get length of post data int clen = atoi(clength); char *pdata = (char *)malloc(clen+clen/8+1); int datalen = mg_read(conn,pdata,clen); //read post data pdata[clen] = '\0'; printf("\nUser data: %s",pdata); mg_printf(conn, "%s\r\n%s", ajax_reply_start,pdata); free(pdata); } catch(std::exception ex) { std::cout << "\n " << ex.what() << "\n\n"; } }
static void login_page(struct mg_connection *conn, const struct mg_request_info *ri, void *data) { char *name, *pass, uri[100]; const char *cookie; name = mg_get_var(conn, "name"); pass = mg_get_var(conn, "pass"); cookie = mg_get_header(conn, "Cookie"); /* * Here user name and password must be checked against some * database - this is step 2 from the algorithm described above. * This is an example, so hardcode name and password to be * admin/admin, and if this is so, set "allow=yes" cookie and * redirect back to the page where we have been redirected to login. */ if (name != NULL && pass != NULL && strcmp(name, "admin") == 0 && strcmp(pass, "admin") == 0) { if (cookie == NULL || sscanf(cookie, "uri=%99s", uri) != 1) (void) strcpy(uri, "/"); /* Set allow=yes cookie, which is expected by authorize() */ mg_printf(conn, "HTTP/1.1 301 Moved Permanently\r\n" "Location: %s\r\n" "Set-Cookie: allow=yes;\r\n\r\n", uri); } else { /* Print login page */ mg_printf(conn, "HTTP/1.1 200 OK\r\n" "content-Type: text/html\r\n\r\n" "Please login (enter admin/admin to pass)<br>" "<form method=post>" "Name: <input type=text name=name></input><br/>" "Password: <input type=password name=pass></input><br/>" "<input type=submit value=Login></input>" "</form>"); } if (name != NULL) mg_free(name); if (pass != NULL) mg_free(pass); }
int CookieHandler(struct mg_connection *conn, void *cbdata) { /* Handler may access the request info using mg_get_request_info */ const struct mg_request_info *req_info = mg_get_request_info(conn); const char *cookie = mg_get_header(conn, "Cookie"); char first_str[64], count_str[64]; int count; (void)mg_get_cookie(cookie, "first", first_str, sizeof(first_str)); (void)mg_get_cookie(cookie, "count", count_str, sizeof(count_str)); mg_printf(conn, "HTTP/1.1 200 OK\r\nConnection: close\r\n"); if (first_str[0] == 0) { time_t t = time(0); struct tm *ptm = localtime(&t); mg_printf(conn, "Set-Cookie: first=%04i-%02i-%02iT%02i:%02i:%02i\r\n", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); } count = (count_str[0] == 0) ? 0 : atoi(count_str); mg_printf(conn, "Set-Cookie: count=%i\r\n", count + 1); mg_printf(conn, "Content-Type: text/html\r\n\r\n"); mg_printf(conn, "<html><body>"); mg_printf(conn, "<h2>This is the CookieHandler.</h2>"); mg_printf(conn, "<p>The actual uri is %s</p>", req_info->local_uri); if (first_str[0] == 0) { mg_printf(conn, "<p>This is the first time, you opened this page</p>"); } else { mg_printf(conn, "<p>You opened this page %i times before.</p>", count); mg_printf(conn, "<p>You first opened this page on %s.</p>", first_str); } mg_printf(conn, "</body></html>\n"); return 1; }
static char *field(struct mg_connection *conn, char *fieldname) { char buf[BUFSIZ], *p, *h; int ret; snprintf(buf, sizeof(buf), "X-Limit-%s", fieldname); if ((h = (char *)mg_get_header(conn, buf)) != NULL) { p = strdup(h); lowercase(p); return (p); } if ((ret = mg_get_var(conn, fieldname, buf, sizeof(buf))) > 0) { p = strdup(buf); lowercase(p); return (p); } return (NULL); }
static void test_get_var(struct mg_connection *conn) { char *var, *buf; size_t buf_len; const char *cl; int var_len; const struct mg_request_info *ri = mg_get_request_info(conn); int is_form_enc = 0; send_standard_reply_head(conn); buf_len = 0; var = buf = NULL; cl = mg_get_header(conn, "Content-Length"); mg_printf(conn, "cl: %p\n", cl); if ((!strcmp(ri->request_method, "POST") || !strcmp(ri->request_method, "PUT")) && cl != NULL) { buf_len = atoi(cl); buf = malloc(buf_len); /* Read in two pieces, to test continuation */ if (buf_len > 2) { mg_read(conn, buf, 2); mg_read(conn, buf + 2, buf_len - 2); } else { mg_read(conn, buf, buf_len); } is_form_enc = 1; } else { MG_ASSERT(ri->query_string != NULL); // query_string ~ "" when no query string was specified in the request buf_len = strlen(ri->query_string); buf = malloc(buf_len + 1); strcpy(buf, ri->query_string); is_form_enc = 1; } var = malloc(buf_len + 1); var_len = mg_get_var(buf, buf_len, "my_var", var, buf_len + 1, is_form_enc); mg_printf(conn, "Value: [%s]\n", var); mg_printf(conn, "Value size: [%d]\n", var_len); free(buf); free(var); }
//////////////////////////////////////////////////////////////// ///Function to send sniffed file list to the client void Executive::listReply(struct mg_connection *conn, const struct mg_request_info *request_info) { try{ int is_jsonp; char text[100]; const char * json; std::stringstream ss; std::string msg; mg_printf(conn, "%s\r\n", json_reply_start); //prints the json message starting headers const char * clength; char h1[] = "Content-Length"; clength = mg_get_header(conn,h1); //get the length of post data int clen = atoi(clength); char *pdata = (char *)malloc(clen+clen/8+1); int datalen = mg_read(conn,pdata,clen); //read post data pdata[clen] = '\0'; mg_get_var(pdata, strlen(pdata == NULL ? "" : pdata), "text", text, sizeof(text)); std::string path(text); is_jsonp = handle_jsonp(pdata,conn, request_info); //find the callback function srand((size_t)time(NULL)); ss<<"["; fsniffer2.Clear(); fsniffer2.sniffFiles(path); std::set<std::string> filelist = fsniffer2.getFiles(); //get sniffed files for (std::set<std::string>::iterator it=filelist.begin(); it != filelist.end(); it++) { std::string tempstr = HTMLEncode(*it); //html encode filepaths ss<<"{item: \""<<tempstr<<"\"},"; } ss<<"]"; msg = ss.str(); json = msg.c_str(); mg_printf(conn, "%s", json); //print json array to the connection if (is_jsonp) { mg_printf(conn, "%s", ")"); //print closing bracket for the function } // fsniffer2.saveFiles(); //save sniffed files } catch(std::exception ex){std::cout << "\n " << ex.what() << "\n\n";} }
static void authorize(struct mg_connection *conn, const struct mg_request_info *ri, void *data) { const char *cookie, *domain; cookie = mg_get_header(conn, "Cookie"); if (!strcmp(ri->uri, "/login")) { /* Always authorize accesses to the login page */ mg_authorize(conn); } else if (cookie != NULL && strstr(cookie, "allow=yes") != NULL) { /* Valid cookie is present, authorize */ mg_authorize(conn); } else { /* Not authorized. Redirect to the login page */ mg_printf(conn, "HTTP/1.1 301 Moved Permanently\r\n" "Set-Cookie: uri=%s;\r\n" "Location: /login\r\n\r\n", ri->uri); } }
//////////////////////////////////////////////////////////////// ///Function to send sniffed process list void Executive::procReply(struct mg_connection *conn, const struct mg_request_info *request_info) { try{ int is_jsonp; const char * json; std::stringstream ss; std::string msg; mg_printf(conn, "%s\r\n", json_reply_start); //prints the json message starting headers const char * clength; char h1[] = "Content-Length"; clength = mg_get_header(conn,h1); //get the length of post data int clen = atoi(clength); char *pdata = (char *)malloc(clen+clen/8+1); int datalen = mg_read(conn,pdata,clen); //read post data pdata[clen] = '\0'; /*mg_get_var(pdata, strlen(pdata == NULL ? "" : pdata), "text", text, sizeof(text)); std::string path(text);*/ is_jsonp = handle_jsonp(pdata,conn, request_info); //find the callback function srand((size_t)time(NULL)); ss<<"["; prsniffer.Clear(); prsniffer.sniffProcesses(); std::map<std::string,int> filelist = prsniffer.getProcesses(); //get process list for (std::map<std::string,int>::iterator it=filelist.begin(); it != filelist.end(); it++) { std::string tempstr = HTMLEncode((*it).first); ss<<"{item: \""<<tempstr<<" ("<<(*it).second<<")\"},"; //store process name and count } ss<<"]"; msg = ss.str(); json = msg.c_str(); mg_printf(conn, "%s", json); //print json array to the connection if (is_jsonp) { mg_printf(conn, "%s", ")"); //print closing bracket for the function } //prsniffer.saveProcesses(); }catch(std::exception ex){std::cout << "\n " << ex.what() << "\n\n";} }
static int api_cb(struct mg_event *event) { struct mg_request_info *ri = event->request_info; char post_data[100] = ""; if (event->type == MG_REQUEST_BEGIN) { ASSERT(event->user_data == (void *) 123); ASSERT(ri->num_headers == 2); ASSERT(strcmp(mg_get_header(event->conn, "host"), "blah.com") == 0); ASSERT(mg_read(event->conn, post_data, sizeof(post_data)) == 3); ASSERT(memcmp(post_data, "b=1", 3) == 0); ASSERT(ri->query_string != NULL); ASSERT(strcmp(ri->query_string, api_uri + 2) == 0); ASSERT(ri->remote_ip > 0); ASSERT(ri->remote_port > 0); ASSERT(strcmp(ri->http_version, "1.0") == 0); mg_printf(event->conn, "HTTP/1.0 200 OK\r\n\r\n"); return 1; } return 0; }
static void mg_keep_alive(struct mg_connection* conn, const struct mg_request_info* ri) { const char *cl; char *buf; int len; mg_printf(conn, "%s", standard_reply); if (strcmp(ri->request_method, "POST") == 0 && (cl = mg_get_header(conn, "Content-Length")) != NULL) { len = atoi(cl); if ((buf = MEM_ALLOC(len+1)) != NULL) { mg_read(conn, buf, len); buf[len] = '\0'; uint id; sscanf(buf, "%u", &id); MEM_FREE(buf); // Invoke keep_alive _invoke("keep_alive_cb", id, NULL); } } }
static void *callback(enum mg_event event, struct mg_connection *conn) { const struct mg_request_info *request_info = mg_get_request_info(conn); char* readBuffer = NULL; int postSize = 0; HttpServer* _this = (HttpServer*) request_info->user_data; if (event == MG_NEW_REQUEST) { if (strcmp(request_info->request_method, "GET") == 0) { //Mark the request as unprocessed. return NULL; } else if (strcmp(request_info->request_method, "POST") == 0) { //get size of postData sscanf(mg_get_header(conn, "Content-Length"), "%d", &postSize); readBuffer = (char*) malloc(sizeof(char) * (postSize + 1)); mg_read(conn, readBuffer, postSize); _this->OnRequest(readBuffer, conn); free(readBuffer); //Mark the request as processed by our handler. return (void*) ""; } else { return NULL; } } else { return NULL; } }
static void mg_leave(struct mg_connection* conn, const struct mg_request_info* ri) { const char *cl; char *buf; int len; if (strcmp(ri->request_method, "POST") == 0 && (cl = mg_get_header(conn, "Content-Length")) != NULL) { len = atoi(cl); if ((buf = MEM_ALLOC(len+1)) != NULL) { mg_read(conn, buf, len); buf[len] = '\0'; uint id; sscanf(buf, "%u", &id); MEM_FREE(buf); if(aatree_size(&clients)) { aatree_remove(&clients, id); // Invoke leave_cb _invoke("leave_cb", id, NULL); mg_printf(conn, "%s", standard_reply); return; } else { goto error; } } } else if(strcmp(ri->request_method, "OPTIONS") == 0) { mg_printf(conn, "%s", standard_reply); return; } error: mg_error(conn, ri); }
static void test_get_var(struct mg_connection *conn, const struct mg_request_info *ri) { char *var, *buf; size_t buf_len; const char *cl; int var_len; mg_printf(conn, "%s", standard_reply); buf_len = 0; var = buf = NULL; cl = mg_get_header(conn, "Content-Length"); mg_printf(conn, "cl: %p\n", cl); if ((!strcmp(ri->request_method, "POST") || !strcmp(ri->request_method, "PUT")) && cl != NULL) { buf_len = atoi(cl); buf = malloc(buf_len); /* Read in two pieces, to test continuation */ if (buf_len > 2) { mg_read(conn, buf, 2); mg_read(conn, buf + 2, buf_len - 2); } else { mg_read(conn, buf, buf_len); } } else if (ri->query_string != NULL) { buf_len = strlen(ri->query_string); buf = malloc(buf_len + 1); strcpy(buf, ri->query_string); } var = malloc(buf_len + 1); var_len = mg_get_var(buf, buf_len, "my_var", var, buf_len + 1); mg_printf(conn, "Value: [%s]\n", var); mg_printf(conn, "Value size: [%d]\n", var_len); free(buf); free(var); }
int event_handler(struct mg_event *event){ struct mg_request_info *request_info = event->request_info; struct mg_connection *conn = event->conn; regex_t regex; int rc; const char *override_method; if (event->type != MG_REQUEST_BEGIN) return 0; override_method = mg_get_header(conn, HTTP_METHOD_HEADER); printf("\x1B[0;32m[%s]\x1B[0m %s\n", override_method ? override_method : request_info->request_method, request_info->uri ); rc = regcomp(®ex, TODO_UPDATE_REGEX, 0); if(strcmp(request_info->uri, TODO_LIST_URL) == 0 && strcmp(request_info->request_method, "GET") == 0){ todos_index(conn); }else if(strcmp(request_info->uri, TODO_CREATE_URL) == 0 && strcmp(request_info->request_method, "POST") == 0){ todos_create(conn); }else if(regexec(®ex, request_info->uri, 0, NULL, 0) == 0){ int todo_id = atoi(&request_info->uri[7]); if(strcmp(override_method, "PUT") == 0){ todos_update(conn, todo_id); }else if(strcmp(override_method, "DELETE") == 0){ todos_delete(conn, todo_id); } } regfree(®ex); return 0; }
/* * This callback function is attached to the "/" and "/abc.html" URIs, * thus is acting as "index.html" file. It shows a bunch of links * to other URIs, and allows to change the value of program's * internal variable. The pointer to that variable is passed to the * callback function as arg->user_data. */ static void show_index(struct mg_connection *conn, const struct mg_request_info *request_info, void *user_data) { char *value; const char *host; /* Change the value of integer variable */ value = mg_get_var(conn, "name1"); if (value != NULL) { * (int *) user_data = atoi(value); free(value); /* * Suggested by Luke Dunstan. When POST is used, * send 303 code to force the browser to re-request the * page using GET method. This prevents the possibility of * the user accidentally resubmitting the form when using * Refresh or Back commands in the browser. */ if (!strcmp(request_info->request_method, "POST")) { (void) mg_printf(conn, "HTTP/1.1 303 See Other\r\n" "Location: %s\r\n\r\n", request_info->uri); return; } } mg_printf(conn, "%s", "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n" "<html><body><h1>Welcome to embedded example of Mongoose"); #if 0 mg_printf(conn, " v. %s </h1><ul>", mg_version()); mg_printf(conn, "<li><code>REQUEST_METHOD: %s " "REQUEST_URI: \"%s\" QUERY_STRING: \"%s\"" " REMOTE_ADDR: %lx REMOTE_USER: \"(null)\"</code><hr>", request_info->request_method, request_info->uri, request_info->query_string ? request_info->query_string : "(null)", request_info->remote_ip); mg_printf(conn, "<li>Internal int variable value: <b>%d</b>", * (int *) user_data); mg_printf(conn, "%s", "<form method=\"GET\">Enter new value: " "<input type=\"text\" name=\"name1\"/>" "<input type=\"submit\" value=\"set new value using GET method\"></form>"); mg_printf(conn, "%s", "<form method=\"POST\">Enter new value: " "<input type=\"text\" name=\"name1\"/>" "<input type=\"submit\" " "value=\"set new value using POST method\"></form>"); mg_printf(conn, "%s", "<li><a href=\"/Makefile\">Regular file (Makefile)</a><hr>" "<li><a href=\"/ssi_test.shtml\">SSI file " "(ssi_test.shtml)</a><hr>" "<li><a href=\"/users/joe/\">Wildcard URI example</a><hr>" "<li><a href=\"/not-existent/\">Custom 404 handler</a><hr>"); host = mg_get_header(conn, "Host"); mg_printf(conn, "<li>'Host' header value: [%s]<hr>", host ? host : "NOT SET"); #endif mg_printf(conn, "<li>Upload file example. " "<form method=\"post\" enctype=\"multipart/form-data\" " "action=\"/post\"><input type=\"file\" name=\"file\">" "<input type=\"submit\"></form>"); mg_printf(conn, "%s", "</body></html>"); }
static void test_mg_download(void) { char *p1, *p2, ebuf[100]; int len1, len2, port = atoi(HTTPS_PORT); struct mg_connection *conn; struct mg_context *ctx; ASSERT((ctx = mg_start(&CALLBACKS, NULL, OPTIONS)) != NULL); ASSERT(mg_download(NULL, port, 0, ebuf, sizeof(ebuf), "%s", "") == NULL); ASSERT(mg_download("localhost", 0, 0, ebuf, sizeof(ebuf), "%s", "") == NULL); ASSERT(mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s", "") == NULL); // Fetch nonexistent file, should see 404 ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s", "GET /gimbec HTTP/1.0\r\n\r\n")) != NULL); ASSERT(strcmp(conn->request_info.uri, "404") == 0); mg_close_connection(conn); ASSERT((conn = mg_download("google.com", 443, 1, ebuf, sizeof(ebuf), "%s", "GET / HTTP/1.0\r\n\r\n")) != NULL); mg_close_connection(conn); // Fetch civetweb.c, should succeed ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s", "GET /civetweb.c HTTP/1.0\r\n\r\n")) != NULL); ASSERT(!strcmp(conn->request_info.uri, "200")); ASSERT((p1 = read_conn(conn, &len1)) != NULL); ASSERT((p2 = read_file("civetweb.c", &len2)) != NULL); ASSERT(len1 == len2); ASSERT(memcmp(p1, p2, len1) == 0); free(p1), free(p2); mg_close_connection(conn); // Fetch in-memory file, should succeed. ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s", "GET /blah HTTP/1.1\r\n\r\n")) != NULL); ASSERT((p1 = read_conn(conn, &len1)) != NULL); ASSERT(len1 == (int) strlen(inmemory_file_data)); ASSERT(memcmp(p1, inmemory_file_data, len1) == 0); free(p1); mg_close_connection(conn); // Fetch in-memory data with no Content-Length, should succeed. ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s", "GET /data HTTP/1.1\r\n\r\n")) != NULL); ASSERT((p1 = read_conn(conn, &len1)) != NULL); ASSERT(len1 == (int) strlen(fetch_data)); ASSERT(memcmp(p1, fetch_data, len1) == 0); free(p1); mg_close_connection(conn); // Test SSL redirect, IP address ASSERT((conn = mg_download("localhost", atoi(HTTP_PORT), 0, ebuf, sizeof(ebuf), "%s", "GET /foo HTTP/1.1\r\n\r\n")) != NULL); ASSERT(strcmp(conn->request_info.uri, "302") == 0); ASSERT(strcmp(mg_get_header(conn, "Location"), "https://127.0.0.1:" HTTPS_PORT "/foo") == 0); mg_close_connection(conn); // Test SSL redirect, Host: ASSERT((conn = mg_download("localhost", atoi(HTTP_PORT), 0, ebuf, sizeof(ebuf), "%s", "GET /foo HTTP/1.1\r\nHost: a.b:77\n\n")) != NULL); ASSERT(strcmp(conn->request_info.uri, "302") == 0); ASSERT(strcmp(mg_get_header(conn, "Location"), "https://a.b:" HTTPS_PORT "/foo") == 0); mg_close_connection(conn); mg_stop(ctx); }
void *TMongSrv::HandleRequest(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) { // Since this is a static request handler, find out for which // server instance this is for. The URL should tell that. TChA UrlStr = "http://"; const char *Host = mg_get_header(conn, "Host"); UrlStr += Host != NULL ? Host : "localhost"; UrlStr += request_info->uri; if (request_info->query_string != NULL) { UrlStr += "?"; UrlStr += request_info->query_string; } void *processed = (void *) "yes"; TStr UrlS = UrlStr; PUrl Url = TUrl::New(UrlS); if (!Url->IsOk(usHttp)) { TNotify::OnNotify(TNotify::StdNotify, ntErr, TStr("Invalid URI: ") + UrlStr); return NULL; } PMongSrv& Server = TMongSrv::Get(Url); if (request_info->log_message != NULL) { TNotify::OnNotify(Server->GetNotify(), ntErr, TStr(request_info->log_message)); return NULL; } THttpRqMethod Method = hrmUndef; if (strncmp(request_info->request_method, "POST", 4) == 0) { Method = hrmPost; } else if (strncmp(request_info->request_method, "GET", 3) == 0) { Method = hrmGet; } else if (strncmp(request_info->request_method, "HEAD", 4) == 0) { Method = hrmHead; } else { return NULL; } TStr ContentType = mg_get_header(conn, THttp::ContTypeFldNm.CStr()); const char *ContentLenStr = mg_get_header(conn, "Content-Length"); PHttpRq Rq; if (Method == hrmPost) { int ContentLength = atoi(ContentLenStr); char *Body = new char[ContentLength]; mg_read(conn, Body, ContentLength); Rq = THttpRq::New(Method, Url, ContentType, TMem(Body, ContentLength)); delete[] Body; } else { Rq = THttpRq::New(Method, Url, ContentType, TMem()); } int ClientId = Server->NewClient(conn, request_info); try { Server->OnHttpRq(ClientId, Rq); Server->DropClient(ClientId); return processed; } catch (PExcept& Exception) { TNotify::OnNotify(Server->GetNotify(), ntErr, Exception->GetStr()); Server->DropClient(ClientId); return NULL; } }
const char* CivetServer::getHeader(struct mg_connection *conn, const std::string &headerName) { return mg_get_header(conn, headerName.c_str()); }
FILE *mg_upload(struct mg_connection *conn, const char *destination_dir, char *path, int path_len) { const char *content_type_header, *boundary_start; char *buf, fname[1024], boundary[100], *s, *p; int bl, n, i, j, headers_len, boundary_len, eof, buf_len, to_read, len = 0; FILE *fp; // Request looks like this: // // POST /upload HTTP/1.1 // Host: 127.0.0.1:8080 // Content-Length: 244894 // Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryRVr // // ------WebKitFormBoundaryRVr // Content-Disposition: form-data; name="file"; filename="accum.png" // Content-Type: image/png // // <89>PNG // <PNG DATA> // ------WebKitFormBoundaryRVr // Extract boundary string from the Content-Type header if ((content_type_header = mg_get_header(conn, "Content-Type")) == NULL || (boundary_start = mg_strcasestr(content_type_header, "boundary=")) == NULL || (sscanf(boundary_start, "boundary=\"%99[^\"]\"", boundary) == 0 && sscanf(boundary_start, "boundary=%99s", boundary) == 0) || boundary[0] == '\0') { return NULL; } boundary_len = strlen(boundary); bl = boundary_len + 4; // \r\n--<boundary> // buf // conn->buf |<--------- buf_len ------>| // |=================|==========|===============| // |<--request_len-->|<--len--->| | // |<-----------data_len------->| conn->buf + conn->buf_size buf = conn->buf + conn->request_len; buf_len = conn->buf_size - conn->request_len; len = conn->data_len - conn->request_len; for (;;) { // Pull in headers assert(len >= 0 && len <= buf_len); to_read = buf_len - len; if (to_read > left_to_read(conn)) { to_read = (int) left_to_read(conn); } while (len < buf_len && (n = pull(NULL, conn, buf + len, to_read)) > 0) { len += n; } if ((headers_len = get_request_len(buf, len)) <= 0) { break; } // Fetch file name. fname[0] = '\0'; for (i = j = 0; i < headers_len; i++) { if (buf[i] == '\r' && buf[i + 1] == '\n') { buf[i] = buf[i + 1] = '\0'; // TODO(lsm): don't expect filename to be the 3rd field, // parse the header properly instead. sscanf(&buf[j], "Content-Disposition: %*s %*s filename=\"%1023[^\"]", fname); j = i + 2; } } // Give up if the headers are not what we expect if (fname[0] == '\0') { break; } // Move data to the beginning of the buffer assert(len >= headers_len); memmove(buf, &buf[headers_len], len - headers_len); len -= headers_len; conn->data_len = conn->request_len + len; // We open the file with exclusive lock held. This guarantee us // there is no other thread can save into the same file simultaneously. fp = NULL; // Construct destination file name. Do not allow paths to have slashes. s = fname; if ((p = strrchr(fname, '/')) != NULL && p > s) s = p; if ((p = strrchr(fname, '\\')) != NULL && p > s) s = p; // Open file in binary mode. TODO: set an exclusive lock. snprintf(path, path_len, "%s/%s", destination_dir, s); if ((fp = fopen(path, "wb")) == NULL) { break; } // Read POST data, write into file until boundary is found. eof = n = 0; do { len += n; for (i = 0; i < len - bl; i++) { if (!memcmp(&buf[i], "\r\n--", 4) && !memcmp(&buf[i + 4], boundary, boundary_len)) { // Found boundary, that's the end of file data. fwrite(buf, 1, i, fp); eof = 1; memmove(buf, &buf[i + bl], len - (i + bl)); len -= i + bl; break; } } if (!eof && len > bl) { fwrite(buf, 1, len - bl, fp); memmove(buf, &buf[len - bl], bl); len = bl; } to_read = buf_len - len; if (to_read > left_to_read(conn)) { to_read = (int) left_to_read(conn); } } while (!eof && (n = pull(NULL, conn, buf + len, to_read)) > 0); conn->data_len = conn->request_len + len; if (eof) { rewind(fp); return fp; } else { fclose(fp); } } return NULL; }
static void *callback__(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) { if (event == MG_NEW_REQUEST) { bool is_zs; { char*s=request_info->uri; int i=0; for(;*s;s++,i++); s=request_info->uri; is_zs=(i>=4&&s[i-4]=='.'&&s[i-3]=='w'&&s[i-2]=='z'&&s[i-1]=='s'); } if(is_zs){ void* qu=qu_new_(shangji_); char out[8]=""; int err; const char* ret=""; for(;;){ { char* echo_def=new char[echo_def_fmt_.size()+32]; sprintf(echo_def,echo_def_fmt_.c_str(),sprintf,mg_printf,conn,out); err=var_new_(jsq_,qu,kw_echo_.c_str(),echo_def,true,vartype_def_,false); delete echo_def; if(err) break; } if((err=var_new_(jsq_,qu,"ip",inet_ntoa(conn->client.rsa.u.sin.sin_addr),true,vartype_var_,false))) break; { const char *cl=mg_get_header(conn, "Content-Length"); if(cl){ size_t cl1=atoi(cl); const char* ct=mg_get_header(conn, "Content-Type"); std::string boundary; if(ct){ const char* ct1="multipart/form-data; boundary="; for(;;ct++,ct1++){ if(!*ct1){ boundary=ct; break; } if(*ct!=*ct1) break; } } if(boundary.empty()){ char* postdata=new char[cl1+1]; postdata[mg_read(conn, postdata, cl1)]=0; qu_var_new_form_url__(qu,postdata,1,&err); delete postdata; if(err) break; }else{ std::string buf2; { char*buf=new char[128]; for(;;){ int siz=mg_read(conn, buf, 128); if(siz<=0) break; for(int i=0;i<siz;i++) buf2.append(1,buf[i]); } delete buf; } size_t pos1=0; std::string sp="\r\n\r\n"; for(;;){ size_t pos2=buf2.find(boundary,pos1); if(pos2==std::string::npos) break; if(pos1>0){ std::string value,name,filename,s,s2; size_t posp=buf2.find(sp,pos1); bool is2=false; for(size_t i=pos1;i<posp+2/*\r\n*/;i++){ char c=buf2[i]; //printf("%c",c); if(c=='\n'||c==';'){ //printf("<%s=%s>",s.c_str(),s2.c_str()); if(is2){ if(s=="name") name=s2; else if(s=="filename") filename=s2; is2=false; } s.clear(); continue; } if(c=='='||c==':'){ is2=true; s2.clear(); continue; } if((c>=0&&c<=' ')||c=='"') continue; if(is2) s2+=c; else s+=c; } //printf("|\n"); size_t i_b=posp+sp.length(), i_e=pos2-4/*\r\n--*/; if(i_b<i_e){ /*for(size_t i=i_b;i<i_e;i++){ char c=buf2[i]; if(c>=' '&&c<='~') printf("%c",c); else if(c=='\n') printf("</\n"); else printf(" %i ",c); }*/ if(filename.empty()){ value=buf2.substr(i_b,i_e-i_b); }else{ filename=uploadir_+filename; value=filename; FILE *fp; if ((fp = fopen(filename.c_str(), "wb+")) == NULL){ }else{ fwrite(buf2.c_str()+i_b, 1, i_e-i_b, fp); if (ferror(fp)){ } (void) fclose(fp); } } } //printf("|%u-%u-%u/%s=%s;\n|\n|\n",pos1,posp,pos2,name.c_str(),value.c_str()); if((err=var_new_(jsq_,qu,name.c_str(),value.c_str(),false,vartype_var_,false))) break; } pos1=pos2+boundary.size()+2/*\r\n*/; } if(err) break; } } } /*for(int i=0;i<request_info->num_headers;i++){ printf("%s\t%s\n",request_info->http_headers[i].name,request_info->http_headers[i].value); }*/ std::string script=mg_get_option(ctx_, "document_root"); script+=request_info->uri; char* qs=request_info->query_string; if(qs){ qu_var_new_form_url__(qu,qs,1,&err); if(err) break; } ret=cb_(jsq_,qu,&err,script.c_str(),true,0); qu_delete_(qu); break; } //printf("out%s\n",out); switch(err){ case jieshiqi_err_go_+keyword_end_: case jieshiqi_err_go_+keyword_exit_: break; default: if(err){ if(!out[0]) mg_printf(conn, "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n\r\n"); if(err>=jieshiqi_err_){ err-=jieshiqi_err_; //mg_printf(conn, "%s", ret); mg_printf(conn, "%s%s", l4_err_(jsq_),l4_errinfo_(jsq_,err)); l4_err_clear_(jsq_); }else mg_printf(conn, "%s err%d", ret,err); } break; } return (void*)""; } } return NULL; }