Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
obj
obj/*.o
monyhar-greasy
26 changes: 26 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
CFLAGS= -I. -g3 -O3 -Wall -Wextra -Wno-unused-variable -D _GNU_SOURCE
LIBS=
SRC=$(wildcard *.c)
HDR=$(wildcard *.h)
OBJS=$(patsubst %.c, obj/%.o, $(SRC))

.PHONY: all clean

all: clean obj monyhar-greasy format

format:
$(foreach n, $(SRC), clang-format -style=google -i $(n); )
$(foreach n, $(HDR), clang-format -style=google -i $(n); )

monyhar-greasy: $(OBJS)
$(CC) $(CFLAGS) $^ -o $@ $(LIBS)

clean:
$(RM) -r obj monyhar-greasy

obj/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<

obj:
mkdir -p obj

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# monyhar-lite
梦弘浏览器 自主研发版本 - 完全自主研发,打破国外垄断,比 Chrome 快 600%。缺少上网功能
# monyhar-greasy
梦弘浏览器 油腻加重版本 - 完全自主研发,打破国外垄断,比 monyhar-lite 慢 600%。有史前上网功能
561 changes: 561 additions & 0 deletions dbg.h

Large diffs are not rendered by default.

75 changes: 75 additions & 0 deletions log.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* This file is originally part of the SLOWProxy
* (https://github.com/nicholascw/SLOWProxy).
*
* Copyright (C) 2020-2021 Nicholas Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "log.h"

static loglevel_t setted_lvl = ERR;
static const char *colors[] = {"\x1b[0;32m", "\x1b[1;36m", "\x1b[1;30m",
"\x1b[1;33m", "\x1b[1;31m", "\x1b[0m"};

void slow_print_log(loglevel_t lvl, const char *func_name,
const char *err_string, const char *src_name,
const unsigned int lineno) {
if (lvl < setted_lvl || setted_lvl == 5) return;
char str_lvl[25];
switch (lvl) {
case DBG:
snprintf(str_lvl, sizeof(str_lvl), "%s[Debug]%s", colors[DBG], colors[5]);
break;
case INFO:
snprintf(str_lvl, sizeof(str_lvl), "%s[Info]%s", colors[INFO], colors[5]);
break;
case WARN:
snprintf(str_lvl, sizeof(str_lvl), "%s[Warn]%s", colors[WARN], colors[5]);
break;
case ERR:
snprintf(str_lvl, sizeof(str_lvl), "%s[Error]%s", colors[ERR], colors[5]);
break;
default:
snprintf(str_lvl, sizeof(str_lvl), "%s[Panic]%s", colors[ERR], colors[5]);
}

time_t t = time(NULL);
struct tm curr_tm;
if (!localtime_r(&t, &curr_tm)) perror("localtime_r()");
char str_time[30];
str_time[29] = '\0';
if (!strftime((char *)&str_time, sizeof(str_time), "%FT%T%z", &curr_tm))
fprintf(stderr, "strftime() failed.\n");
//[Debug] 2020-07-08 03:27:36 CDT
(setted_lvl != DBG)
? fprintf(stderr, "%s\t%s%s%s: %s(): %s\n", str_lvl, colors[0], str_time,
colors[5], func_name, err_string)
: fprintf(stderr, "%s\t%s%s%s: %s:%d: %s(): %s\n", str_lvl, colors[0],
str_time, colors[5], src_name, lineno, func_name, err_string);
}

void slow_perror_log(const char *func_name, const char *src_name,
const unsigned int lineno) {
/*char str_errno[128];
str_errno[127] = '\0';
if(strerror_r(errno, str_errno, 127)!=0) perror("slow_perror_log()");
else slow_print_log(ERR, func_name, str_errno, src_name, lineno);*/
slow_print_log(ERR, func_name, strerror(errno), src_name, lineno);
}

loglevel_t slow_loglevel(loglevel_t level) {
if (level != INVALID) setted_lvl = level;
return setted_lvl;
}
60 changes: 60 additions & 0 deletions log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "dbg.h" // https://github.com/eerimoq/dbg-macro

static char slow_snprintf_buf[1024];

#define __FNAME__ \
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#define L_DEBUG(STR) \
(slow_print_log(DBG, __FUNCTION__, (STR), (__FNAME__), __LINE__));
#define L_INFO(STR) \
(slow_print_log(INFO, __FUNCTION__, (STR), (__FNAME__), __LINE__));
#define L_WARN(STR) \
(slow_print_log(WARN, __FUNCTION__, (STR), (__FNAME__), __LINE__));
#define L_ERR(STR) \
(slow_print_log(ERR, __FUNCTION__, (STR), (__FNAME__), __LINE__));
#define L_PERROR() (slow_perror_log(__FUNCTION__, (__FNAME__), __LINE__));

#define L_DEBUGF(FMT, ...) \
do { \
snprintf(slow_snprintf_buf, 1024, (FMT), __VA_ARGS__); \
L_DEBUG(slow_snprintf_buf); \
} while (0);
#define L_INFOF(FMT, ...) \
do { \
snprintf(slow_snprintf_buf, 1024, (FMT), __VA_ARGS__); \
L_INFO(slow_snprintf_buf); \
} while (0);
#define L_WARNF(FMT, ...) \
do { \
snprintf(slow_snprintf_buf, 1024, (FMT), __VA_ARGS__); \
L_WARN(slow_snprintf_buf); \
} while (0);
#define L_ERRF(FMT, ...) \
do { \
snprintf(slow_snprintf_buf, 1024, (FMT), __VA_ARGS__); \
L_ERR(slow_snprintf_buf); \
} while (0);

typedef enum {
DBG = 1,
INFO = 2,
WARN = 3,
ERR = 4,
SHUT = 5,
INVALID = -1
} loglevel_t;

void slow_print_log(loglevel_t lvl, const char *func_name,
const char *err_string, const char *src_name,
const unsigned int lineno);

void slow_perror_log(const char *func_name, const char *src_name,
const unsigned int lineno);

loglevel_t slow_loglevel(loglevel_t level);
100 changes: 95 additions & 5 deletions main.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,99 @@
#include <stdio.h>

int surf_internet() {
return 0;
}
#include "log.h"
#include "parser.h"
#include "stream.h"

int main(int argc, char *argv[]) {
s_uri uri_parsed;
memset(&uri_parsed, 0, sizeof(s_uri));
if (argc < 2) {
L_ERRF("Usage: %s [OPTIONS] URL\n", argv[0]);
return 0;
}
if (argc > 2) {
// where we'll parse options
for (int i = 1; i < argc - 1; i++) {
if (strstr(argv[i], "-v") == argv[i]) slow_loglevel(DBG);
}
}

if (parse_uri(argv[argc - 1], &uri_parsed)) {
L_ERRF("Fatal error when parsing URL: %s", argv[argc - 1]);
return 1;
}

if (strcmp(uri_parsed.proto, "http")) {
L_ERRF("Unsupported protocol: %s", uri_parsed.proto);
exit(1);
}

struct addrinfo hints, *servinfo, *p;
int rv;
char s[INET6_ADDRSTRLEN];

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

int main() {
return surf_internet();
if ((rv = getaddrinfo(uri_parsed.hostname, uri_parsed.port, &hints,
&servinfo)) != 0) {
L_ERRF("getaddrinfo: %s", gai_strerror(rv));
return 1;
}
int sockfd;
// loop through all the results and connect to the first we can
for (p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
L_PERROR();
continue;
}

if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
L_PERROR();
continue;
}

break;
}

if (p == NULL) {
L_ERR("failed to connect.\n");
return 2;
}

inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s,
sizeof s);
L_DEBUGF("connecting to %s (%s:%s)...", uri_parsed.hostname, s,
uri_parsed.port);

freeaddrinfo(servinfo); // all done with this structure

char *buf = calloc(MAXDATASIZE, 1);
if (!buf) {
L_PERROR();
exit(1);
}
snprintf(buf, MAXDATASIZE,
"GET %s HTTP/1.1\r\n"
"Host: %s:%s\r\n"
"Connection: close\r\n"
"Accept: */*\r\n"
"User-Agent: monyhar-greasy/0.1 (like curl/7.72.0)\r\n\r\n",
uri_parsed.path, uri_parsed.hostname, uri_parsed.port);
if (sendall(sockfd, buf, strlen(buf)) < 0) {
L_ERR("Error occured when sending HTTP Request.");
exit(1);
}
free(buf);
buf = NULL;
ssize_t content_size = recv_to_fd(sockfd, STDOUT_FILENO);
if (content_size > 0) {
L_INFOF("Successfully received %ld byte(s) of payload. Bye.", content_size);
} else if (content_size < 0) {
L_ERR("Error when handling HTTP Response.");
}
close(sockfd);
return 0;
}
50 changes: 50 additions & 0 deletions parser.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include "parser.h"

#include <ctype.h>
#include <string.h>
#define larger(X, Y) (X > Y ? X : Y)
#define smaller(X, Y) (X < Y ? X : Y)

int parse_uri(char *str, s_uri *res) {
char *pos = strstr(str, "://");
// assumes http by if protocol header not found
res->proto =
pos ? strndup(str, smaller((pos - str), PROTO_MAXLEN)) : strdup("http");
pos = pos ? pos + 3 : str;
for (int i = strlen(res->proto) - 1; i >= 0; i--) {
res->proto[i] = tolower(res->proto[i]);
}
int host_len;
if ((host_len = strchr(pos, ':') - pos) < HOSTNAME_MAXLEN && host_len > 0) {
res->hostname = strndup(pos, smaller(host_len, HOSTNAME_MAXLEN));
pos += host_len + 1;
char *port_ends_at;
if ((port_ends_at = strchr(pos, '/'))) {
if (port_ends_at - pos < 10) {
res->port = strndup(pos, port_ends_at - pos);
} else {
L_ERR("Invalid port: too long.");
}
} else {
if (strlen(pos) < 10) {
res->port = strndup(pos, 9);
} else {
L_ERR("Invalid URL");
}
}
} else {
res->port = strchr(res->proto, 's') ? strdup("443") : strdup("80");
if ((host_len = strchr(pos, '/') - pos) < HOSTNAME_MAXLEN && host_len > 0) {
res->hostname = strndup(pos, host_len);
} else if ((host_len = strlen(pos)) < HOSTNAME_MAXLEN) {
res->hostname = strndup(pos, host_len);
} else {
L_ERR("Invalid URL");
return 1;
}
}

res->path =
strchr(pos, '/') ? strndup(strchr(pos, '/'), URL_MAXLEN) : strdup("/");
return 0;
}
13 changes: 13 additions & 0 deletions parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "log.h"
#define PROTO_MAXLEN 10
#define URL_MAXLEN 6144
#define HOSTNAME_MAXLEN 255

typedef struct {
char *proto;
char *hostname;
char *port;
char *path;
} s_uri;

int parse_uri(char *str, s_uri *res);
Loading