Giter Site home page Giter Site logo

icapeg's People

Contributors

amanymahmoud144 avatar anondo avatar haitham911 avatar iamrz1 avatar khaledemaradev avatar mahmoudrabee avatar mahnouman avatar marwangalal746 avatar mkaram007 avatar mohameddenta avatar rahmayasser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

icapeg's Issues

Error: txt extension not recognized

testing with echo services
I tried to add "txt" in process_extensions array and value 10 in max_filesize then test 1k txt file, the file passed and it should not.
the txt file only processed when I add "*" to process_extensions

Transformers unit tests

In this pr I created 3 files in transformers directory which contains unit tests for vmray, metadefender and virustotal files

Issue: test method in req mode

I tried to test request mode with CONNECT method with this command
c-icap-client -i 127.0.0.1 -p 1344 -s echo -f ./input.pdf -o ./toutput -req http://www.example.com -method CONNECT -no204 -v

the return header is ICAP/1.0 204 No modifications needed and there is no file returned

Also when I used HEAD method the icap header was empty and empty file created

Note: Other methods works fine .

`

invalid memory address or nil pointer dereference

testing echo services on the default configuration browsing this url (by squid version 5.7)
https://www.google.com/search?client=firefox-b-d&q=amazon

2022/10/19 13:35:46 icap: panic serving 127.0.0.1:53036: runtime error: invalid memory address or nil pointer dereference
goroutine 13 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/root/icapeg/icapeg/icap/server.go:106 +0xdd
panic({0x877520, 0xc45790})
/usr/local/go/src/runtime/panic.go:884 +0x212
io.(*multiReader).Read(0xc00049f068, {0xc0001b1600, 0x200, 0x200})
/usr/local/go/src/io/multi.go:26 +0x95
bytes.(*Buffer).ReadFrom(0xc0001e5ec0, {0x828e89f40, 0xc0004a70d0})
/usr/local/go/src/bytes/buffer.go:202 +0x98
icapeg/api.(*ICAPRequest).preview(0xc0000b86e0?)
/root/icapeg/icapeg/api/icap-request.go:398 +0x217
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc00006acc0, 0xc0?)
/root/icapeg/icapeg/api/icap-request.go:215 +0x5ab
icapeg/api.(*ICAPRequest).RequestProcessing(0xc00006acc0)
/root/icapeg/icapeg/api/icap-request.go:159 +0x7d8
icapeg/api.ToICAPEGServe({0x9a8d38, 0xc0001e5dd0}, 0xc000490c60?)
/root/icapeg/icapeg/api/icap.go:21 +0x85
icapeg/icap.HandlerFunc.ServeICAP(0xc000095ed8?, {0x9a8d38?, 0xc0001e5dd0?}, 0xc00031b90e?)
/root/icapeg/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc0000140b8, {0x9a8d38, 0xc0001e5dd0}, 0xc00012a510)
/root/icapeg/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc0001ea9c0, 0x0?)
/root/icapeg/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/root/icapeg/icapeg/icap/server.go:207 +0x205
2022/10/19 13:35:46 icap: panic serving 127.0.0.1:5990: runtime error: invalid memory address or nil pointer dereference
goroutine 14 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/root/icapeg/icapeg/icap/server.go:106 +0xdd
panic({0x877520, 0xc45790})
/usr/local/go/src/runtime/panic.go:884 +0x212
io.(*multiReader).Read(0xc00049f0b0, {0xc0001b1a00, 0x200, 0x200})
/usr/local/go/src/io/multi.go:26 +0x95
bytes.(*Buffer).ReadFrom(0xc00025c1e0, {0x828e89f40, 0xc0004a7180})
/usr/local/go/src/bytes/buffer.go:202 +0x98
icapeg/api.(*ICAPRequest).preview(0xc0000b88f0?)
/root/icapeg/icapeg/api/icap-request.go:398 +0x217
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc00006ae40, 0xc0?)
/root/icapeg/icapeg/api/icap-request.go:215 +0x5ab
icapeg/api.(*ICAPRequest).RequestProcessing(0xc00006ae40)
/root/icapeg/icapeg/api/icap-request.go:159 +0x7d8
icapeg/api.ToICAPEGServe({0x9a8d38, 0xc00025c0f0}, 0xc000490c60?)
/root/icapeg/icapeg/api/icap.go:21 +0x85
icapeg/icap.HandlerFunc.ServeICAP(0xc000055ed8?, {0x9a8d38?, 0xc00025c0f0?}, 0xc00031bc9e?)
/root/icapeg/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc0000140b8, {0x9a8d38, 0xc00025c0f0}, 0xc00012a750)
/root/icapeg/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc0001eaa80, 0x0?)
/root/icapeg/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/root/icapeg/icapeg/icap/server.go:207 +0x205
https://www.google.com/search?client=firefox-b-d&q=amazon

Disable resp mode in echo servoce

I Disabled the resp mode of echo service in config.toml file:resp_mode=false
then tested icapeg with this command : c-icap-client -i 127.0.0.1 -p 1344 -s echo -f "./in.pdf" -o ./out.pdf -v
the output was empty icap header
the output should be :
405 - Method not allowed for service (e.g., RESPMOD requested for service that supports only REQMOD).

Clamav uploading files

In the case of putting [ pdf, doc, docx, etc. ] in reject extensions, Using icapeg in request mode with Clamav service, They uploaded normally to google drive.
They must be rejected.

Clamav with doc files

In the case of putting “doc” in reject extensions. try to download it with icapeg with Clamav service in response mode, It downloaded normally instead of a rejection

Error: Empty ICAP HEADERS

I tried to run the below command 10 times and I found that the output was different in each time

  • some outputs have an empty icap headers
  • other commands have correct icap header with 404 error code

The command:
c-icap-client -i 127.0.0.1 -p 1344 -s fakeService -f "./input.pdf" -o ./output -v

go report badge Error

when trying to get a report from https://goreportcard.com/ I got this error

There was an error processing your request: Could not analyze the repository: could not download repo: could not get latest module version from https://proxy.golang.org/icapeg/@latest: bad request: invalid escaped module path "icapeg": malformed module path "icapeg": missing dot in first path element

Test ICAPeg with OPNsense in response mode and preview size=0 ,by browsing this site " https://file-examples.com/index.php/sample-documents-download/sample-doc-download/" gives me this error

2022/10/31 09:54:59 icap: panic serving 127.0.0.1:2834: runtime error: invalid memory address or nil pointer dereference
goroutine 13 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/root/icapeg/icapeg/icap/server.go:106 +0xdd
panic({0x877520, 0xc45790})
/usr/local/go/src/runtime/panic.go:884 +0x212
io.(*multiReader).Read(0xc000013980, {0xc0001b1e00, 0x200, 0x200})
/usr/local/go/src/io/multi.go:26 +0x95
bytes.(*Buffer).ReadFrom(0xc000162a50, {0x828e88f18, 0xc0001969d0})
/usr/local/go/src/bytes/buffer.go:202 +0x98
icapeg/api.(*ICAPRequest).preview(0xc0000b8580?)
/root/icapeg/icapeg/api/icap-request.go:398 +0x217
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc00006b200, 0xc0?)
/root/icapeg/icapeg/api/icap-request.go:215 +0x5ab
icapeg/api.(*ICAPRequest).RequestProcessing(0xc00006b200)
/root/icapeg/icapeg/api/icap-request.go:159 +0x7d8
icapeg/api.ToICAPEGServe({0x9a8d38, 0xc000162960}, 0xc0000ab200?)
/root/icapeg/icapeg/api/icap.go:21 +0x85
icapeg/icap.HandlerFunc.ServeICAP(0xc000093ed8?, {0x9a8d38?, 0xc000162960?}, 0xc00047646e?)
/root/icapeg/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc0000140b8, {0x9a8d38, 0xc000162960}, 0xc00012a3f0)
/root/icapeg/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc000198680, 0x0?)
/root/icapeg/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/root/icapeg/icapeg/icap/server.go:207 +0x205

I test ICAPeg with echo service by squid version 5.7 browsing this url "https://www.google.com/search?client=firefox-b-d&q=lenovo"

2022/10/24 09:11:06 icap: panic serving 127.0.0.1:65183: runtime error: invalid memory address or nil pointer dereference
goroutine 12 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/root/icapeg/icapeg/icap/server.go:106 +0xdd
panic({0x877520, 0xc45790})
/usr/local/go/src/runtime/panic.go:884 +0x212
io.(*multiReader).Read(0xc000286c00, {0xc0001df600, 0x200, 0x200})
/usr/local/go/src/io/multi.go:26 +0x95
bytes.(*Buffer).ReadFrom(0xc000260570, {0x828e89740, 0xc0000a2f70})
/usr/local/go/src/bytes/buffer.go:202 +0x98
icapeg/api.(*ICAPRequest).preview(0xc0000b84d0?)
/root/icapeg/icapeg/api/icap-request.go:398 +0x217
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc00006aba0, 0xc0?)
/root/icapeg/icapeg/api/icap-request.go:215 +0x5ab
icapeg/api.(*ICAPRequest).RequestProcessing(0xc00006aba0)
/root/icapeg/icapeg/api/icap-request.go:159 +0x7d8
icapeg/api.ToICAPEGServe({0x9a8d38, 0xc000260480}, 0xc0003ebd40?)
/root/icapeg/icapeg/api/icap.go:21 +0x85
icapeg/icap.HandlerFunc.ServeICAP(0xc000093ed8?, {0x9a8d38?, 0xc000260480?}, 0xc00002954e?)
/root/icapeg/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc0000140b8, {0x9a8d38, 0xc000260480}, 0xc00012a240)
/root/icapeg/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc000450540, 0x0?)
/root/icapeg/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/root/icapeg/icapeg/icap/server.go:207 +0x205
2022/10/24 09:11:07 icap: panic serving 127.0.0.1:21578: runtime error: invalid memory address or nil pointer dereference
goroutine 13 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/root/icapeg/icapeg/icap/server.go:106 +0xdd
panic({0x877520, 0xc45790})
/usr/local/go/src/runtime/panic.go:884 +0x212
io.(*multiReader).Read(0xc000286c48, {0xc0001dfa00, 0x200, 0x200})
/usr/local/go/src/io/multi.go:26 +0x95
bytes.(*Buffer).ReadFrom(0xc000260870, {0x828e89740, 0xc0000a3020})
/usr/local/go/src/bytes/buffer.go:202 +0x98
icapeg/api.(*ICAPRequest).preview(0xc0000b8630?)
/root/icapeg/icapeg/api/icap-request.go:398 +0x217
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc00006ad20, 0xc0?)
/root/icapeg/icapeg/api/icap-request.go:215 +0x5ab
icapeg/api.(*ICAPRequest).RequestProcessing(0xc00006ad20)
/root/icapeg/icapeg/api/icap-request.go:159 +0x7d8
icapeg/api.ToICAPEGServe({0x9a8d38, 0xc000260780}, 0xc0003ebd40?)
/root/icapeg/icapeg/api/icap.go:21 +0x85
icapeg/icap.HandlerFunc.ServeICAP(0xc000055ed8?, {0x9a8d38?, 0xc000260780?}, 0xc00002987e?)
/root/icapeg/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc0000140b8, {0x9a8d38, 0xc000260780}, 0xc00012a480)
/root/icapeg/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc0001e4b00, 0x0?)
/root/icapeg/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/root/icapeg/icapeg/icap/server.go:207 +0x205

Upload files

In the case of putting [ pdf, doc, docx, etc. ] in reject extensions, Using icapeg in request mode with clhashlookup service, They uploaded normally to google drive.
They must be rejected.

Error: Try squid with icapeg

I tried to connect squid with icapeg
icapeg running in docker container
squid is running in docker container
icapeg from restructure branch with original config.toml
squid version 5
in squid :

  • I Added these lines to squid.conf file

icap_enable on
adaptation_send_username on
adaptation_send_client_ip on
icap_service srv_resp respmod_precache 0 icap://127.0.0.1:1344/echo
#icap_service srv_req reqmod_precache 0 icap://localhost:1344/echo
adaptation_access srv_resp allow all
#adaptation_access srv_req allow all
icap_service_failure_limit -1
icap_preview_enable off

I tested the proxy with curl command

curl -I --proxy "http://localhost:5002" http://www.example.com
result from squid :
HTTP/1.1 500 Internal Server Error
Server: squid/5.4.1
Mime-Version: 1.0
Date: Tue, 28 Jun 2022 14:25:43 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 3141
X-Squid-Error: ERR_ICAP_FAILURE 0
Vary: Accept-Language
Content-Language: en
X-Cache: MISS from 193a33666dbf
Via: 1.1 193a33666dbf (squid/5.4.1)
Connection: keep-alive

result of icapeg logs :

2022/06/28 14:15:41 icap: panic serving 172.18.0.4:37520: runtime error: invalid memory address or nil pointer dereference
goroutine 10 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/home/icapeg/icap/server.go:106 +0xdd
panic({0x804be0, 0xb73ec0})
/usr/local/go/src/runtime/panic.go:838 +0x207
compress/gzip.(*Reader).Read(0x0?, {0xc000149400?, 0x0?, 0x0?})
/usr/local/go/src/compress/gzip/gunzip.go:247 +0x2e
io.ReadAll({0x914100, 0x0})
/usr/local/go/src/io/io.go:645 +0xfe
io/ioutil.ReadAll(...)
/usr/local/go/src/io/ioutil/ioutil.go:27
icapeg/service/services-utilities/general-functions.(*GeneralFunc).DecompressGzipBody(0x9142e0?, 0xc00010abd0?)
/home/icapeg/service/services-utilities/general-functions/general-functions.go:125 +0x35
icapeg/service/services/echo.(*Echo).Processing(0xc0002540c0, 0xc5?)
/home/icapeg/service/services/echo/echo.go:67 +0x6a5
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc0000648a0, 0x1e?)
/home/icapeg/api/icap-request.go:146 +0x2b9
icapeg/api.(*ICAPRequest).RequestProcessing(0xc0000648a0)
/home/icapeg/api/icap-request.go:110 +0xbe
icapeg/api.ToICAPEGServe({0x9172a8?, 0xc0002522d0?}, 0xc00049efc0?)
/home/icapeg/api/icap.go:20 +0x48
icapeg/icap.HandlerFunc.ServeICAP(0xc000193ed8?, {0x9172a8?, 0xc0002522d0?}, 0xc00010abea?)
/home/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc000010058, {0x9172a8, 0xc0002522d0}, 0xc000100120)
/home/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc000067400, 0x0?)
/home/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/home/icapeg/icap/server.go:207 +0x205
2022/06/28 14:15:59 icap: panic serving 172.18.0.4:37522: runtime error: invalid memory address or nil pointer dereference
goroutine 52 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/home/icapeg/icap/server.go:106 +0xdd
panic({0x804be0, 0xb73ec0})
/usr/local/go/src/runtime/panic.go:838 +0x207
compress/gzip.(*Reader).Read(0x0?, {0xc00009a200?, 0x0?, 0x0?})
/usr/local/go/src/compress/gzip/gunzip.go:247 +0x2e
io.ReadAll({0x914100, 0x0})
/usr/local/go/src/io/io.go:645 +0xfe
io/ioutil.ReadAll(...)
/usr/local/go/src/io/ioutil/ioutil.go:27
icapeg/service/services-utilities/general-functions.(*GeneralFunc).DecompressGzipBody(0x9142e0?, 0xc00010a240?)
/home/icapeg/service/services-utilities/general-functions/general-functions.go:125 +0x35
icapeg/service/services/echo.(*Echo).Processing(0xc0002540c0, 0xc5?)
/home/icapeg/service/services/echo/echo.go:67 +0x6a5
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc0000686c0, 0x1e?)
/home/icapeg/api/icap-request.go:146 +0x2b9
icapeg/api.(*ICAPRequest).RequestProcessing(0xc0000686c0)
/home/icapeg/api/icap-request.go:110 +0xbe
icapeg/api.ToICAPEGServe({0x9172a8?, 0xc0004821b0?}, 0xc00049efc0?)
/home/icapeg/api/icap.go:20 +0x48
icapeg/icap.HandlerFunc.ServeICAP(0xc00004eed8?, {0x9172a8?, 0xc0004821b0?}, 0xc00010a25a?)
/home/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc000010058, {0x9172a8, 0xc0004821b0}, 0xc00016e120)
/home/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc000066000, 0x0?)
/home/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/home/icapeg/icap/server.go:207 +0x205
2022/06/28 14:17:14 ICAP server gracefully shut down
2022/06/28 14:17:29 starting the ICAP server
2022/06/28 14:17:29 ICAP server is running on localhost: 1344
2022/06/28 14:21:43 icap: panic serving 172.18.0.4:37528: runtime error: invalid memory address or nil pointer dereference
goroutine 11 [running]:
runtime/debug.Stack()
/usr/local/go/src/runtime/debug/stack.go:24 +0x65
icapeg/icap.(*conn).serve.func1()
/home/icapeg/icap/server.go:106 +0xdd
panic({0x804be0, 0xb73ec0})
/usr/local/go/src/runtime/panic.go:838 +0x207
compress/gzip.(*Reader).Read(0x0?, {0xc000234200?, 0x0?, 0x0?})
/usr/local/go/src/compress/gzip/gunzip.go:247 +0x2e
io.ReadAll({0x914100, 0x0})
/usr/local/go/src/io/io.go:645 +0xfe
io/ioutil.ReadAll(...)
/usr/local/go/src/io/ioutil/ioutil.go:27
icapeg/service/services-utilities/general-functions.(*GeneralFunc).DecompressGzipBody(0x9142e0?, 0xc00010a270?)
/home/icapeg/service/services-utilities/general-functions/general-functions.go:125 +0x35
icapeg/service/services/echo.(*Echo).Processing(0xc00021c0c0, 0xc5?)
/home/icapeg/service/services/echo/echo.go:67 +0x6a5
icapeg/api.(*ICAPRequest).RespAndReqMods(0xc0005861e0, 0x1e?)
/home/icapeg/api/icap-request.go:146 +0x2b9
icapeg/api.(*ICAPRequest).RequestProcessing(0xc0005861e0)
/home/icapeg/api/icap-request.go:110 +0xbe
icapeg/api.ToICAPEGServe({0x9172a8?, 0xc0003dc330?}, 0xc0004b8fc0?)
/home/icapeg/api/icap.go:20 +0x48
icapeg/icap.HandlerFunc.ServeICAP(0xc00004ded8?, {0x9172a8?, 0xc0003dc330?}, 0xc00010a28a?)
/home/icapeg/icap/server.go:39 +0x2f
icapeg/icap.(*ServeMux).ServeICAP(0xc000010058, {0x9172a8, 0xc0003dc330}, 0xc00016e240)
/home/icapeg/icap/mux.go:94 +0x448
icapeg/icap.(*conn).serve(0xc000066000, 0x0?)
/home/icapeg/icap/server.go:127 +0x7f
created by icapeg/icap.(*Server).Serve
/home/icapeg/icap/server.go:207 +0x205

How ICAPeg will inform our ICAP client of the AV scanning results of an infected file

When the AV Scanning results of a posted file, e.g ZIP or PDF with ClamAV is that this file is not safe, that is, infected, how does the ICAP response from ICAPeg look like and how our ICAP client can interpret the ICAP response that this uploaded file is infected?

2023-02-22T15:36:16.203Z info general-functions/general-functions.go:49 extracting the body of HTTP message
2023-02-22T15:36:16.204Z info general-functions/general-functions.go:262 getting the file name
2023-02-22T15:36:16.204Z info general-functions/general-functions.go:442 getting the mime extension of the HTTP message body
2023-02-22T15:36:16.204Z debug general-functions/general-functions.go:462 HTTP message body mime extension is zip
2023-02-22T15:36:16.204Z info general-functions/general-functions.go:71 checking the extension (reject or bypass or process)
2023-02-22T15:36:16.204Z debug general-functions/general-functions.go:75 extension is process
2023-02-22T15:36:16.204Z debug clamav/clamav.go:84 sending the HTTP msg body to the ClamAV through antivirus socket
2023-02-22T15:36:21.205Z debug clamav/clamav.go:111 clamavFile is not safe
2023-02-22T15:36:21.207Z debug api/icap-request.go:189 adding the headers which the service wants to add them in the ICAP response
2023-02-22T15:36:21.207Z debug api/icap-request.go:198 checking if shadow service mode is enabled to add logs instead of returning another
2023-02-22T15:36:21.207Z debug api/icap-request.go:237 clamav returned ICAP response with status code 200

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.