{"id":19078124,"url":"https://github.com/hendriks73/coxy","last_synced_at":"2025-04-30T04:41:41.583Z","repository":{"id":17249236,"uuid":"20018552","full_name":"hendriks73/coxy","owner":"hendriks73","description":"Coxy - a simple caching proxy for Discogs","archived":false,"fork":false,"pushed_at":"2016-01-09T09:26:42.000Z","size":40,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-18T20:49:19.769Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hendriks73.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-05-21T11:20:09.000Z","updated_at":"2024-04-23T08:37:00.000Z","dependencies_parsed_at":"2022-07-26T14:32:02.392Z","dependency_job_id":null,"html_url":"https://github.com/hendriks73/coxy","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendriks73%2Fcoxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendriks73%2Fcoxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendriks73%2Fcoxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendriks73%2Fcoxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hendriks73","download_url":"https://codeload.github.com/hendriks73/coxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251644826,"owners_count":21620630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T02:05:49.214Z","updated_at":"2025-04-30T04:41:41.566Z","avatar_url":"https://github.com/hendriks73.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Coxy - a simple caching proxy for Discogs\n\n[![Build Status](https://travis-ci.org/hendriks73/coxy.svg?branch=master)](https://travis-ci.org/hendriks73/coxy)\n\nCoxy lets you pipe your image requests through a proxy server which\nissues OAuth authorized requests to the actual Discogs server, if\nthe requested file is not already in its cache.\n\n## Plain Installation\n\nYou can find pre-built binaries in the beaTunes [Maven](http://maven.apache.org) repository at\n[https://www.beatunes.com/repo/maven2/com/tagtraum/coxy/](https://www.beatunes.com/repo/maven2/com/tagtraum/coxy/)\n\nInstall the `war` file in a servlet container of your choice.\nThen make sure to set the following system properties (the ones you specify\nas `-Dkey=value` for the `java` command):\n\n* `cache.base` - this is the folder where the cached files are store.\nObviously is must be writable by the servlet container process.\n* `resolver` - determines how files are stored in the filesystem. Valid values are either `straight` or `discogs`.\n* `http.agent` - the user agent to send to Discogs, e.g. `coolapp/2.0`\n* `target.base` - the base part of the target server URL, e.g. `https://api.discogs.com` (no trailing slash!)\n\nMake sure that the directory `cache.base` exists and is readable and writable\nby your servlet container.\n\nIf you are planning on caching more than a couple of thousand files,\nyou *will* want to store those files not in one directory, but a hierarchy of\nmultiple nested ones. Otherwise filesystem performance will suffer.\nFor Discogs images you should therefore use the `discogs` resolver, in order\nto translate a filename like `[signature]/discogs-images/R-1074891-1267544771.jpeg.jpg`\nto something like `/images/R/10/74/R-1074891/R-1074891-1267544771.jpeg`.\n\n*Hint: If used in conjunction with NGINX, it makes\nsense to use a `cache.base`-path that ends with `coxy`, the name of this coxy's\nservlet context. E.g.: `/var/www/coxy`.\nThis makes it easier to configure NGINX in a way that allows it to easily\nserve the static images.*\n\nYou should now be able to send requests to your server, which will be forwarded\nto your target server.\n\nE.g. if configured correctly for Discogs, a request like\n`http://localhost:8080/coxy/[signature]/discogs-images/R-944131-1175701834.jpeg.jpg`\nshould be forwarded to `https://api-img.discogs.com/[signature]/discogs-images/R-944131-1175701834.jpeg.jpg`,\nthe response then stored in the file system under the folder specified by\n`cache.base` and ultimately returned to the user. The next request for the\nsame entity should be served directly from your file system.\n\n## Installation with NGINX\n\nInstall the `war` just like you did above.\nThen install NGINX and configure it to serve files directly from your `cache.base`.\nThis ensures that all files you have already fetched from your target server\nare served efficiently without executing any fancy logic.\nOnly when a file is not in the cache yet, we need to forward the request to\nthe servlet engine.\n\nHere's an example for an appropriate NGINX configuration:\n\n    server {\n\n        listen       80;\n        server_name  localhost;\n        root   /whatever/your/root/is;\n\n        location /coxy {\n            # enable this rewrite rule, if you are using the discogs resolver\n            # see com.tagtraum.coxy.DiscogsImageCacheResolver\n            rewrite \"^/coxy/.*/discogs-(images/)((.)-([^-]{0,2})([^-]{0,2})[^-]*)(.*)(\\.[^\\.]*)$\" /coxy/$1/$3/$4/$5/$2/$2$6 break;\n\n            # if cache.base == /your/cache/base/coxy, root must be:\n            root   /your/cache/base;\n            # i.e., you must then omit \"coxy\", as it is appended by\n            # default as part of the location\n\n            # redirect 404 File Not Found errors to servlet container\n            error_page  404              = @servlet_container;\n            # make sure we tell browsers to cache images for a year\n            expires 365d;\n        }\n\n        # redirect server error pages to the static page /50x.html\n        error_page  404              /404.html;\n        error_page  500 502 503 504  /50x.html;\n        location = /50x.html {\n            root   /usr/share/nginx/html;\n        }\n\n\n        location @servlet_container {\n            # append $request_uri, so that we send the original URI, that hasn't been rewritten\n            proxy_pass http://127.0.0.1:8080$request_uri;\n            proxy_set_header X-Real-IP $remote_addr;\n            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n            proxy_set_header Host $http_host;\n        }\n\n    }\n\nNote that for this to work, the servlet container must listen for HTTP request\non the configured port (in the example, that's port 8080 on localhost).\n\nOf course we could also simply use NGINX built-in proxy cache. However, then the files\nwouldn't be stored in the directory structure controlled by us, leading to possible\nduplication.\n\n## Disclaimer\n\nCoxy comes with absolutely no warranty.\n\n## Convert flat image directory to DiscogsImageCacheResolver\n\nRun these commands from the directory that contains the images (note, these are not perfect...):\n \n    ls --color=none *.jpeg | sed -e 's@\\(\\(.\\)-\\([^-]\\{2\\}\\)\\([^-]\\{2\\}\\)[^-]*\\)\\(.*\\)@mkdir -p \\2/\\3/\\4/\\1@' | sh\n    ls --color=none *.jpeg | sed -e 's@\\(\\(.\\)-\\([^-]\\{2\\}\\)\\([^-]\\{2\\}\\)[^-]*\\)\\(.*\\)@mv \u0026 \\2/\\3/\\4/\\1/\\1\\5@' | sh\n\nYou might want to check what is actually being done with the `| sh` first (dry-run).\n\n## Create list with flat image names\n \n    ls -LR /var/www/coxy/images | grep -e \"\\.jpeg\" -e \"\\.png\" -e \"\\.gif\" -e \"\\.bmp\" -e \"\\.jpg\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhendriks73%2Fcoxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhendriks73%2Fcoxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhendriks73%2Fcoxy/lists"}