Full Code of wantedly/nginx-image-server for AI

master 72b059f7bd47 cached
22 files
27.8 KB
8.3k tokens
3 symbols
1 requests
Download .txt
Repository: wantedly/nginx-image-server
Branch: master
Commit: 72b059f7bd47
Files: 22
Total size: 27.8 KB

Directory structure:
gitextract_dwuep06d/

├── .dockerignore
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE
├── README.md
├── coreos/
│   ├── Vagrantfile
│   ├── config.rb
│   └── user-data.yml.erb
├── files/
│   ├── mime.types
│   ├── nginx.conf
│   └── validator.pm
├── script/
│   ├── bootstrap
│   ├── build
│   ├── run
│   ├── run-infrataster
│   ├── run-locust
│   └── test
├── test/
│   ├── feature/
│   │   └── spec/
│   │       ├── nginx_image_server_spec.rb
│   │       └── spec_helper.rb
│   └── performance/
│       └── locustfile.py
└── wercker.yml

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
*
!Dockerfile
!files/*


================================================
FILE: .gitignore
================================================
.env
.DS_Store
locustfile.pyc
user-data
.vagrant


================================================
FILE: .travis.yml
================================================
sudo: required
services:
- docker
script:
- docker -v
- docker build -t quay.io/wantedly/nginx-image-server .
- script/run -d
- script/run-infrataster
notifications:
  slack:
    secure: C5l4fgeuirkGPI4BYZP1onHY1FbYbth5UuGRZzmJ/6OBMdwV4HdHl7Gbt92NiD+7EhtWOh1qtqgFPakoVZjrrva3vS/cR1drvh80qQbF/OjZRsR68p0kjJDEn5uJf66iP0DBkFRWYliE0CILXha6T/5xxOQthuoI7OWfrI8SQi0=


================================================
FILE: Dockerfile
================================================
FROM ubuntu:14.04

ENV NGINX_VERSION 1.10.0
ENV NGX_SMALL_LIGHT_VERSION 0.9.1
ENV IMAGEMAGICK_VERSION 6.8.6-8

# Install dependency packages
RUN apt-get update && \
    apt-get install -y \
      binutils-doc \
      bison \
      flex \
      g++ \
      gettext \
      libpcre3 \
      libpcre3-dev \
      libssl-dev \
      libperl-dev \
      make && \
    rm -rf /var/lib/apt/lists/*

# Build ImageMagick with WebP support
RUN mkdir -p /tmp/imagemagick && \
    cd /tmp/imagemagick && \
    echo "\ndeb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted" >> /etc/apt/sources.list && \
    apt-get update && \
    apt-get build-dep -y imagemagick && \
    apt-get install -y libwebp-dev devscripts checkinstall && \
    curl -L https://launchpad.net/imagemagick/main/${IMAGEMAGICK_VERSION}/+download/ImageMagick-${IMAGEMAGICK_VERSION}.tar.gz > \
      ImageMagick-${IMAGEMAGICK_VERSION}.tar.gz && \
    tar zxf ImageMagick-${IMAGEMAGICK_VERSION}.tar.gz && \
    cd ImageMagick-${IMAGEMAGICK_VERSION} && \
    ./configure \
      --prefix=/usr \
      --sysconfdir=/etc \
      --libdir=/usr/lib/x86_64-linux-gnu \
      --enable-shared \
      --with-modules \
      --disable-openmp \
      --with-webp=yes \
      LDFLAGS=-L/usr/local/lib \
      CPPFLAGS=-I/usr/local/include && \
    make && \
    checkinstall -y && \
    rm -rf /tmp/imagemagick && \
    rm -rf /var/lib/apt/lists/*

# Fetch and unarchive nginx source
RUN curl -L http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz > /tmp/nginx-${NGINX_VERSION}.tar.gz && \
    cd /tmp && \
    tar zxf nginx-${NGINX_VERSION}.tar.gz

# Fetch and unarchive ngx_small_light module
RUN curl -L https://github.com/cubicdaiya/ngx_small_light/archive/v${NGX_SMALL_LIGHT_VERSION}.tar.gz > /tmp/ngx_small_light-${NGX_SMALL_LIGHT_VERSION}.tar.gz && \
    cd /tmp && \
    tar zxf ngx_small_light-${NGX_SMALL_LIGHT_VERSION}.tar.gz && \
    cd /tmp/ngx_small_light-${NGX_SMALL_LIGHT_VERSION} && \
    ./setup

# Compile nginx
RUN cd /tmp/nginx-${NGINX_VERSION} && \
    ./configure \
      --prefix=/opt/nginx \
      --conf-path=/etc/nginx/nginx.conf \
      --sbin-path=/opt/nginx/sbin/nginx \
      --with-http_stub_status_module \
      --with-http_perl_module \
      --with-pcre \
      --add-module=/tmp/ngx_small_light-${NGX_SMALL_LIGHT_VERSION} && \
    make && \
    make install && \
    rm -rf /tmp/*

RUN mkdir -p /etc/nginx && \
    mkdir -p /opt/nginx/perl/lib && \
    mkdir -p /var/run && \
    mkdir -p /etc/nginx/conf.d && \
    mkdir -p /var/www/nginx/cache && \
    mkdir -p /var/www/nginx/images && \
    mkdir -p /var/www/nginx/tmp

# Add config files
COPY files/nginx.conf   /etc/nginx/nginx.conf
COPY files/mime.types   /etc/nginx/mime.types
COPY files/validator.pm /opt/nginx/perl/lib/validator.pm

EXPOSE 80 8090

CMD ["/opt/nginx/sbin/nginx"]


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2014-2016 Wantedly, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Nginx Image Server
[![Docker Repository on Quay.io](https://quay.io/repository/wantedly/nginx-image-server/status "Docker Repository on Quay.io")](https://quay.io/repository/wantedly/nginx-image-server)
[![Build Status](https://travis-ci.org/wantedly/nginx-image-server.svg)](https://travis-ci.org/wantedly/nginx-image-server)

Docker Image for [Nginx](http://nginx.org/) server for image processing with [ngx_small_light](https://github.com/cubicdaiya/ngx_small_light).
It supports resizing/cropping/formatting (`png`, `webp`...etc) of images stored in local storages or AWS S3.

Please see https://github.com/cubicdaiya/ngx_small_light for more information about image processing.

## SUPPORTED TAGS

* `latest`
  * Nginx 1.10.0
  * ngx_small_light 0.9.1
  * ImageMagick 6.8.6-8 (Q16) with WebP support

## HOW TO USE

```bash
# Get the docker image
$ docker pull quay.io/wantedly/nginx-image-server

# Fetch an example image to try image-processing local image
$ curl -L https://raw.githubusercontent.com/wantedly/nginx-image-server/master/examples/example.jpg > \
    /tmp/example.jpg

# Start the image server
$ docker run \
    --rm \
    -it \
    --name nginx-image-server \
    -p 80:80 \
    -p 8090:8090 \
    -v /tmp/example.jpg:/var/www/nginx/images/example.jpg \
    -e "SERVER_NAME=image.example.com" \
    -e "S3_HOST=<YOUR-BUCKET-NAME>.s3.amazonaws.com" \
    quay.io/wantedly/nginx-image-server:latest
```

Then you can try image-processing by accessing

* **Images in S3**: `http://<YOUR-SERVER.com>/small_light(dh=400,da=l,ds=s)/<PATH-TO-IMAGE-IN-S3>`
* **Images in Local**: `http://<YOUR-SERVER.com>/local/small_light(dh=400,da=l,ds=s)/images/example.jpg`

And `http://<YOUR-SERVER.com>:8090/status` retruns the nginx status.

### Custom configuration
You can build a docker image includes your own `nginx.conf`:

```
FROM quay.io/wantedly/nginx-image-server
COPY nginx.conf /etc/nginx/nginx.conf
```

Then build with `docker build -t your-nginx-image-server .` and run:

```bash
$ docker run \
    -d \
    --name your-nginx-image-server \
    -p 80:80 \
    your-nginx-image-server
```

Be sure to include `daemon off;` in your custom configuration to run Nginx in the foreground.
Otherwise your container will stop immediately after starting.

## HOW TO DEVELOP

```bash
# on your local machine
$ git clone https://github.com/wantedly/nginx-image-server.git && cd nginx-image-server
$ script/bootstrap
$ cp .env.sample .env
```

```
# .env
TIMEZONE=Asia/Tokyo
```

```
$ vagrant up
$ vi Dockerfile

# login to VM and test it
$ vagrant ssh
@core-01 $ cd share
@core-01 $ docker build -t=quay.io/wantedly/nginx-image-server .
@core-01 $ script/test
```


## TEST
[![wercker status](https://app.wercker.com/status/e1d50221515bacea622f6a6f5f0adde6/s/master "wercker status")](https://app.wercker.com/project/bykey/e1d50221515bacea622f6a6f5f0adde6)

### Feature(behavior) test
Behavior test with [infrataster](https://github.com/ryotarai/infrataster).
Test files are under `test/feature` directory. You can run this test with follwing script:

```bash
$ script/test
```

### Performance test
Performance test with [locust](http://locust.io/).
Test files are under `test/performance` directory. You can run locust with follwing script:

```bash
# Run target container
$ script/run

# Export target IP
$ export TARGET_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' nginx-image-server)

# Run locust as WebTool
$ script/run-locust -f locustfile.py -H http://${TARGET_IP}

# Run locust as CLI
$ script/run-locust -f locustfile.py -H http://${TARGET_IP} --no-web -c 5 -r 1 -n 10
```

## LICENSE
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)


================================================
FILE: coreos/Vagrantfile
================================================
# -*- mode: ruby -*-
# # vi: set ft=ruby :

require 'fileutils'

Vagrant.require_version ">= 1.6.0"

CLOUD_CONFIG_PATH = File.join(File.dirname(__FILE__), "user-data")
CONFIG = File.join(File.dirname(__FILE__), "config.rb")

# Defaults for config options defined in CONFIG
$num_instances = 1
$update_channel = "alpha"
$enable_serial_logging = false
$vb_gui = false
$vb_memory = 1024
$vb_cpus = 1

# Attempt to apply the deprecated environment variable NUM_INSTANCES to
# $num_instances while allowing config.rb to override it
if ENV["NUM_INSTANCES"].to_i > 0 && ENV["NUM_INSTANCES"]
  $num_instances = ENV["NUM_INSTANCES"].to_i
end

if File.exist?(CONFIG)
  require CONFIG
end

Vagrant.configure("2") do |config|
  # always use Vagrants insecure key
  config.ssh.insert_key = false

  config.vm.box = "coreos-%s" % $update_channel
  config.vm.box_version = ">= 308.0.1"
  config.vm.box_url = "http://%s.release.core-os.net/amd64-usr/current/coreos_production_vagrant.json" % $update_channel

  config.vm.provider :vmware_fusion do |vb, override|
    override.vm.box_url = "http://%s.release.core-os.net/amd64-usr/current/coreos_production_vagrant_vmware_fusion.json" % $update_channel
  end

  config.vm.provider :virtualbox do |v|
    # On VirtualBox, we don't have guest additions or a functional vboxsf
    # in CoreOS, so tell Vagrant that so it can be smarter.
    v.check_guest_additions = false
    v.functional_vboxsf     = false
  end

  # plugin conflict
  if Vagrant.has_plugin?("vagrant-vbguest") then
    config.vbguest.auto_update = false
  end

  (1..$num_instances).each do |i|
    config.vm.define vm_name = "core-%02d" % i do |config|
      config.vm.hostname = vm_name

      if $enable_serial_logging
        logdir = File.join(File.dirname(__FILE__), "log")
        FileUtils.mkdir_p(logdir)

        serialFile = File.join(logdir, "%s-serial.txt" % vm_name)
        FileUtils.touch(serialFile)

        config.vm.provider :vmware_fusion do |v, override|
          v.vmx["serial0.present"] = "TRUE"
          v.vmx["serial0.fileType"] = "file"
          v.vmx["serial0.fileName"] = serialFile
          v.vmx["serial0.tryNoRxLoss"] = "FALSE"
        end

        config.vm.provider :virtualbox do |vb, override|
          vb.customize ["modifyvm", :id, "--uart1", "0x3F8", "4"]
          vb.customize ["modifyvm", :id, "--uartmode1", serialFile]
        end
      end

      if $expose_docker_tcp
        config.vm.network "forwarded_port", guest: 2375, host: ($expose_docker_tcp + i - 1), auto_correct: true
      end

      config.vm.provider :vmware_fusion do |vb|
        vb.gui = $vb_gui
      end

      config.vm.provider :virtualbox do |vb|
        vb.gui = $vb_gui
        vb.memory = $vb_memory
        vb.cpus = $vb_cpus
      end

      ip = "172.17.8.#{i+100}"
      config.vm.network :private_network, ip: ip

      # Uncomment below to enable NFS for sharing the host machine into the coreos-vagrant VM.
      config.vm.synced_folder "../", "/home/core/share", id: "core", :nfs => true, :mount_options => ['nolock,vers=3,udp']

      if File.exist?(CLOUD_CONFIG_PATH)
        config.vm.provision :file, :source => "#{CLOUD_CONFIG_PATH}", :destination => "/tmp/vagrantfile-user-data"
        config.vm.provision :shell, :inline => "mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/", :privileged => true
      end

    end
  end
end


================================================
FILE: coreos/config.rb
================================================
require 'erb'
require 'dotenv'

# Create user-data from erb template
Dotenv.load
erb = File.open(File.join(File.dirname(__FILE__), "user-data.yml.erb")) { |f| ERB.new(f.read) }
File.write(File.join(File.dirname(__FILE__), "user-data"), erb.result(binding))

# To automatically replace the discovery token on 'vagrant up', uncomment
# the lines below:
#
#if File.exists?('user-data') && ARGV[0].eql?('up')
#  require 'open-uri'
#  require 'yaml'
#
#  token = open('https://discovery.etcd.io/new').read
#
#  data = YAML.load(IO.readlines('user-data')[1..-1].join)
#  data['coreos']['etcd']['discovery'] = token
#
#  yaml = YAML.dump(data)
#  File.open('user-data', 'w') { |file| file.write("#cloud-config\n\n#{yaml}") }
#end
#

#
# coreos-vagrant is configured through a series of configuration
# options (global ruby variables) which are detailed below. To modify
# these options, first copy this file to "config.rb". Then simply
# uncomment the necessary lines, leaving the $, and replace everything
# after the equals sign..

# Size of the CoreOS cluster created by Vagrant
$num_instances=1

# Official CoreOS channel from which updates should be downloaded
$update_channel="beta"

# Log the serial consoles of CoreOS VMs to log/
# Enable by setting value to true, disable with false
# WARNING: Serial logging is known to result in extremely high CPU usage with
# VirtualBox, so should only be used in debugging situations
#$enable_serial_logging=false

# Enable port forwarding of Docker TCP socket
# Set to the TCP port you want exposed on the *host* machine, default is 2375
# If 2375 is used, Vagrant will auto-increment (e.g. in the case of $num_instances > 1)
# You can then use the docker tool locally by setting the following env var:
#   export DOCKER_HOST='tcp://127.0.0.1:2375'
#$expose_docker_tcp=2375

# Setting for VirtualBox VMs
#$vb_gui = false
#$vb_memory = 1024
#$vb_cpus = 1


================================================
FILE: coreos/user-data.yml.erb
================================================
#cloud-config

coreos:
  update:
    group: beta
    reboot-strategy: off
  units:
    - name: settimezone.service
      command: start
      content: |
        [Unit]
        Description=Set the timezone

        [Service]
        ExecStart=/usr/bin/timedatectl set-timezone <%= ENV["TIMEZONE"] %>
        RemainAfterExit=yes
        Type=oneshot
    - name: docker-tcp.socket
      command: start
      enable: true
      content: |
        [Unit]
        Description=Docker Socket for the API

        [Socket]
        ListenStream=2375
        Service=docker.service
        BindIPv6Only=both

        [Install]
        WantedBy=sockets.target
write_files:
  - path: /etc/ssh/sshd_config
    permissions: 0600
    owner: root:root
    content: |
      # Use most defaults for sshd configuration.
      UsePrivilegeSeparation sandbox
      Subsystem sftp internal-sftp

      PermitRootLogin no
      PasswordAuthentication no
      ChallengeResponseAuthentication no
  - path: /etc/ntp.conf
    content: |
      # Common pool
      server 0.pool.ntp.org
      server 1.pool.ntp.org
      server 2.pool.ntp.org
      server 3.pool.ntp.org

      # - Allow only time queries, at a limited rate.
      # - Allow all local queries (IPv4, IPv6)
      restrict default nomodify nopeer noquery limited kod
      restrict 127.0.0.1
      restrict [::1]


================================================
FILE: files/mime.types
================================================
types {
    text/html                             html htm shtml;
    text/css                              css;
    text/xml                              xml;
    image/gif                             gif;
    image/jpeg                            jpeg jpg;
    application/javascript                js;
    application/json                      json;
    application/atom+xml                  atom;
    application/rss+xml                   rss;
    text/mathml                           mml;
    text/plain                            txt;
    text/vnd.sun.j2me.app-descriptor      jad;
    text/vnd.wap.wml                      wml;
    text/x-component                      htc;
    image/png                             png;
    image/tiff                            tif tiff;
    image/vnd.wap.wbmp                    wbmp;
    image/x-icon                          ico;
    image/x-jng                           jng;
    image/x-ms-bmp                        bmp;
    image/svg+xml                         svg svgz;
    image/webp                            webp;
    application/java-archive              jar war ear;
    application/mac-binhex40              hqx;
    application/msword                    doc;
    application/pdf                       pdf;
    application/postscript                ps eps ai;
    application/rtf                       rtf;
    application/vnd.ms-excel              xls;
    application/vnd.ms-powerpoint         ppt;
    application/vnd.wap.wmlc              wmlc;
    application/vnd.google-earth.kml+xml  kml;
    application/vnd.google-earth.kmz      kmz;
    application/x-7z-compressed           7z;
    application/x-cocoa                   cco;
    application/x-java-archive-diff       jardiff;
    application/x-java-jnlp-file          jnlp;
    application/x-makeself                run;
    application/x-perl                    pl pm;
    application/x-pilot                   prc pdb;
    application/x-rar-compressed          rar;
    application/x-redhat-package-manager  rpm;
    application/x-sea                     sea;
    application/x-shockwave-flash         swf;
    application/x-stuffit                 sit;
    application/x-tcl                     tcl tk;
    application/x-x509-ca-cert            der pem crt;
    application/x-xpinstall               xpi;
    application/xhtml+xml                 xhtml;
    application/zip                       zip;
    application/octet-stream              bin exe dll;
    application/octet-stream              deb;
    application/octet-stream              dmg;
    application/octet-stream              eot;
    application/octet-stream              iso img;
    application/octet-stream              msi msp msm;
    audio/midi                            mid midi kar;
    audio/mpeg                            mp3;
    audio/ogg                             ogg;
    audio/x-m4a                           m4a;
    audio/x-realaudio                     ra;
    video/3gpp                            3gpp 3gp;
    video/mp4                             mp4;
    video/mpeg                            mpeg mpg;
    video/quicktime                       mov;
    video/webm                            webm;
    video/x-flv                           flv;
    video/x-m4v                           m4v;
    video/x-mng                           mng;
    video/x-ms-asf                        asx asf;
    video/x-ms-wmv                        wmv;
    video/x-msvideo                       avi;
}


================================================
FILE: files/nginx.conf
================================================
env SERVER_NAME;
env S3_HOST;

user root;
worker_processes 4;
daemon off;
#worker_rlimit_nofile
error_log /dev/stdout info;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    #multi_accept on;
    #use
}

http {
    perl_modules perl/lib;
    perl_require validator.pm;

    perl_set $server_name_from_env 'sub { return $ENV{"SERVER_NAME"}; }';
    perl_set $s3_host_from_env 'sub { return $ENV{"S3_HOST"}; }';

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    #access_log off;
    access_log /dev/stdout;
    server_tokens off;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    keepalive_timeout 65;

    gzip on;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_vary off;
    #gzip_buffers
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/rss+xml application/atom+xml text/javascript application/javascript application/json text/mathml;
    gzip_min_length  1000;
    gzip_disable     MSIE [1-6]\.;

    server_names_hash_bucket_size 64;
    types_hash_max_size 2048;
    types_hash_bucket_size 64;
    #proxy_read_timeout
    #client_body_buffer_size
    #client_max_body_size

    limit_req_zone $binary_remote_addr zone=default:10m rate=1r/s;

    proxy_cache_path /var/www/nginx/cache levels=1:2 keys_zone=cache-space:4m max_size=50m inactive=120m;
    proxy_temp_path /var/www/nginx/tmp;

    server {
      listen 80;
      server_name $server_name_from_env;

      location ~ ^/(.+)$ {
        proxy_pass http://localhost:8080;
        proxy_cache cache-space;
        proxy_cache_valid 200 60m;
      }
    }

    server {
      listen 8080;
      server_name $server_name_from_env;
      resolver 8.8.8.8;
      small_light on;

      location @empty {
        empty_gif;
      }

      location /favicon.ico {
        empty_gif;
        access_log    off;
        log_not_found off;
      }

      # Image processing for images in local file
      location ~ ^/local/small_light[^/]*/(.+)$ {
        set $small_light_maximum_size 3072;
        perl validator::handler;
      }

      # Image processing for images in AWS S3
      location ~ ^/small_light[^/]*/(.+)$ {
        set $small_light_maximum_size 3072;
        perl validator::handler;
      }

      location ~ ^/images/(.+)$ {
        root /var/www/nginx;
        error_page 415 = @empty;
      }

      location ~ ^/(.+)$ {
        proxy_pass http://$s3_host_from_env/$1;
        error_page 415 = @empty;
      }
    }

    server {
      listen 8090;
      server_name $server_name_from_env;

      location /status {
        stub_status on;
        access_log off;
      }
    }

    include /etc/nginx/conf.d/*.conf;
}


================================================
FILE: files/validator.pm
================================================
package validator;

use nginx;
use strict;
use warnings;

sub handler {
  my $r = shift;
  my $uri = "/" . ($r->uri =~ /^.*\/small_light[^\/]*\/(.+)$/m)[0];
  my $threshold = $r->variable("small_light_maximum_size");

  unless ($threshold) {
    $r->log_error(100, "small_light_maximum_size is not defined!");
    $r->internal_redirect($uri);

    return OK;
  }

  my $bad_request = 0;
  my @params = $r->uri =~ /([a-zA-Z]+=[0-9a-zA-Z]+),?/g;

  foreach my $param (@params) {
    my ($key, $value) = split("=", $param);

    if (grep(/^${key}$/, ("cw", "dw", "ch", "dh"))) {
      if ($value > $threshold) {
        $r->log_error(100, "Invalid resize parameter, " . $key . ": " . $value);
        $bad_request = 1;
        last;
      }
    }
  }

  if ($bad_request) {
    # to avoid ngx_small_light process and return 400
    $r->send_http_header;

    return HTTP_BAD_REQUEST;
  }

  $r->internal_redirect($uri);

  return OK;
}

1;
__END__


================================================
FILE: script/bootstrap
================================================
#!/bin/bash
#
# bootstrap
#
# Get readly to develop

set -e

#
# Welcome message
#
echo ""
echo "  nginx-image-server"
echo ""

#
# Check for VirtualBox
#
if test ! $(which virtualbox)
then
  echo "  x You need to install VirtualBox."
  echo "    You can download it from https://www.virtualbox.org/wiki/Downloads"
  exit 1
else
  echo "  + VirtualBox found."
fi

#
# Check for Vagrant
#
if test ! $(which vagrant)
then
  echo "  x You need to install Vagrant."
  echo "    You can download it from http://www.vagrantup.com/downloads.html"
  exit 1
else
  echo "  + Vagrant found."
fi

#
# Install vagrant plugin
#
if [[ $(vagrant plugin list) =~ dotenv ]]
then
  echo "  + Vagrant plugin 'dotenv' found."
else
  echo "  x You need to install Vagrant plugin 'dotenv':"
  echo "    $ vagrant plugin install dotenv"
  exit 1
fi

#
# Startup instructions
#
echo ""
echo "  Good work. We're ready."

exit 0


================================================
FILE: script/build
================================================
#!/bin/bash
#
# Usage: script/build
# Description: build nginx-image-server
#

set -e

docker build -t=quay.io/wantedly/nginx-image-server .


================================================
FILE: script/run
================================================
#!/bin/bash
#
# Usage: script/run <MODE>
# Description: run nginx-image-server container
# Example:
#   $ script/run-target
#   $ script/run-target -d
#

BASE_DIRECTORY=`pwd`
MODE="--rm -it"

if [ $# -eq 1 ]; then
  if [ $1 = "-d" ]; then
    MODE="-d"
  fi
fi

cd ${BASE_DIRECTORY}
docker kill target > /dev/null 2>&1 || true
docker rm   target > /dev/null 2>&1 || true
docker run \
  ${MODE} \
  --name nginx-image-server \
  -p 80:80 \
  -p 8090:8090 \
  -v ${BASE_DIRECTORY}/examples:/var/www/nginx/images/ \
  -e "SERVER_NAME=${SERVER_NAME}" \
  -e "S3_HOST=${S3_HOST}" \
  quay.io/wantedly/nginx-image-server:latest


================================================
FILE: script/run-infrataster
================================================
#!/bin/bash
#
# Usage: script/run-infrataster
# Description: run infrataster container
#

BASE_DIRECTORY=`pwd`

cd ${BASE_DIRECTORY}/test/feature
docker kill tester > /dev/null 2>&1 || true
docker rm   tester > /dev/null 2>&1 || true
docker run \
  --rm \
  --name infrataster \
  -v $PWD/spec:/test/spec \
  -e TARGET_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' nginx-image-server) \
  quay.io/wantedly/infrataster:latest


================================================
FILE: script/run-locust
================================================
#!/bin/bash
#
# Usage: script/run-locust <LOCUST_ARGS>
# Description: run tester container
# Example:
#   script/run-locust -f locustfile.py -H localhost --no-web -c 10 -r 1 -n 30
#   script/run-locust -f locustfile.py -H localhost
#

BASE_DIRECTORY=`pwd`
LOCUST_ARGS=$@

cd ${BASE_DIRECTORY}/test/performance
docker kill locust > /dev/null 2>&1 || true
docker rm   locust > /dev/null 2>&1 || true
docker run \
  --rm \
  -it \
  --name locust \
  -p 8089:8089 \
  -v ${BASE_DIRECTORY}/test/performance:/test \
  quay.io/wantedly/locust:latest \
  ${LOCUST_ARGS}


================================================
FILE: script/test
================================================
#!/bin/sh
#
# Usage: script/cibuild
# Description: script to run test
#

set -e

# this script should be run in project root
BASE_DIRECTORY=`pwd`
SERVER_NAME="image.example.com"

echo "==> Building target..."
cd ${BASE_DIRECTORY}
script/build

echo "==> Running nginx-image-server..."
docker kill nginx-image-server > /dev/null 2>&1 || true
docker rm   nginx-image-server > /dev/null 2>&1 || true
docker kill infrataster > /dev/null 2>&1 || true
docker rm   infrataster > /dev/null 2>&1 || true
script/run -d

echo "==> Running test..."
script/run-infrataster

echo "==> Cleaning up..."
docker kill nginx-image-server > /dev/null 2>&1 || true
docker rm   nginx-image-server > /dev/null 2>&1 || true
docker kill infrataster > /dev/null 2>&1 || true
docker rm   infrataster > /dev/null 2>&1 || true


================================================
FILE: test/feature/spec/nginx_image_server_spec.rb
================================================
require "spec_helper"

describe server(:target) do
  describe http('http://target/images/example.jpg') do
    it "responds OK 200" do
      expect(response.status).to eq(200)
    end
    it "responds as 'image/jpeg'" do
      expect(response.headers['content-type']).to eq("image/jpeg")
    end
  end

  describe http('http://target/local/small_light(dh=600,da=l,ds=s,of=png)/images/example.jpg') do
    it "responds OK 200" do
      expect(response.status).to eq(200)
    end
    it "responds as 'image/png'" do
      expect(response.headers['content-type']).to eq("image/png")
    end
  end

  describe http('http://target/local/small_light(dh=600,da=l,ds=s,of=webp)/images/example.jpg') do
    it "responds OK 200" do
      expect(response.status).to eq(200)
    end
    it "responds as 'image/webp'" do
      expect(response.headers['content-type']).to eq("image/webp")
    end
  end

  describe http('http://target:8090/status') do
    it "responds OK 200" do
      expect(response.status).to eq(200)
    end
    it "responds content including 'Active connections'" do
      expect(response.body).to include("Active connections")
    end
  end

  describe http('http://target/local/small_light(dh=3600,da=l,ds=s,of=webp)/images/example.jpg') do
    it "responds Bad Request 400" do
      expect(response.status).to eq(400)
    end
  end

  describe http('http://target/local/small_light(ch=3600,da=l,ds=s,of=webp)/images/example.jpg') do
    it "responds Bad Request 400" do
      expect(response.status).to eq(400)
    end
  end

  describe http('http://target/local/small_light(dw=3600,da=l,ds=s,of=webp)/images/example.jpg') do
    it "responds Bad Request 400" do
      expect(response.status).to eq(400)
    end
  end

  describe http('http://target/local/small_light(cw=3600,da=l,ds=s,of=webp)/images/example.jpg') do
    it "responds Bad Request 400" do
      expect(response.status).to eq(400)
    end
  end
end


================================================
FILE: test/feature/spec/spec_helper.rb
================================================
require "infrataster/rspec"

Infrataster::Server.define(
  :target,
  ENV["TARGET_IP"],
  vagrant: false,
)


================================================
FILE: test/performance/locustfile.py
================================================
from locust import HttpLocust, TaskSet, task
import random

class MyTaskSet(TaskSet):
    @task
    def index(self):
      dh = random.randint(1, 1200)
      of = random.choice(["jpg", "gif", "png", "webp"])
      self.client.get("/local/small_light(dh=" + str(dh) + ",da=l,ds=s,cc=FFFFFF,of=" + of + ")/images/example.jpg")

class WebsiteUser(HttpLocust):
    task_set = MyTaskSet
    min_wait=5000
    max_wait=9000


================================================
FILE: wercker.yml
================================================
box: wercker-labs/docker
build:
  steps:
    - script:
        name: Check docker version
        code: |
          docker -v
    - script:
        name: Build quay.io/wantedly/nginx-image-server
        code: |
          cd ${WERCKER_SOURCE_DIR}
          docker build -t quay.io/wantedly/nginx-image-server .
    - script:
        name: Run quay.io/wantedly/nginx-image-server
        code: >
          script/run -d
    - script:
        name: Run tester
        code: >
          script/run-infrataster
  after-steps:
    - wantedly/pretty-slack-notify:
        webhook_url: $SLACK_WEBHOOK_URL
        channel: $SLACK_CHANNEL
Download .txt
gitextract_dwuep06d/

├── .dockerignore
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE
├── README.md
├── coreos/
│   ├── Vagrantfile
│   ├── config.rb
│   └── user-data.yml.erb
├── files/
│   ├── mime.types
│   ├── nginx.conf
│   └── validator.pm
├── script/
│   ├── bootstrap
│   ├── build
│   ├── run
│   ├── run-infrataster
│   ├── run-locust
│   └── test
├── test/
│   ├── feature/
│   │   └── spec/
│   │       ├── nginx_image_server_spec.rb
│   │       └── spec_helper.rb
│   └── performance/
│       └── locustfile.py
└── wercker.yml
Download .txt
SYMBOL INDEX (3 symbols across 1 files)

FILE: test/performance/locustfile.py
  class MyTaskSet (line 4) | class MyTaskSet(TaskSet):
    method index (line 6) | def index(self):
  class WebsiteUser (line 11) | class WebsiteUser(HttpLocust):
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (31K chars).
[
  {
    "path": ".dockerignore",
    "chars": 23,
    "preview": "*\n!Dockerfile\n!files/*\n"
  },
  {
    "path": ".gitignore",
    "chars": 49,
    "preview": ".env\n.DS_Store\nlocustfile.pyc\nuser-data\n.vagrant\n"
  },
  {
    "path": ".travis.yml",
    "chars": 360,
    "preview": "sudo: required\nservices:\n- docker\nscript:\n- docker -v\n- docker build -t quay.io/wantedly/nginx-image-server .\n- script/r"
  },
  {
    "path": "Dockerfile",
    "chars": 2836,
    "preview": "FROM ubuntu:14.04\n\nENV NGINX_VERSION 1.10.0\nENV NGX_SMALL_LIGHT_VERSION 0.9.1\nENV IMAGEMAGICK_VERSION 6.8.6-8\n\n# Install"
  },
  {
    "path": "LICENSE",
    "chars": 1086,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014-2016 Wantedly, Inc.\n\nPermission is hereby granted, free of charge, to any pers"
  },
  {
    "path": "README.md",
    "chars": 3715,
    "preview": "# Nginx Image Server\n[![Docker Repository on Quay.io](https://quay.io/repository/wantedly/nginx-image-server/status \"Doc"
  },
  {
    "path": "coreos/Vagrantfile",
    "chars": 3373,
    "preview": "# -*- mode: ruby -*-\n# # vi: set ft=ruby :\n\nrequire 'fileutils'\n\nVagrant.require_version \">= 1.6.0\"\n\nCLOUD_CONFIG_PATH ="
  },
  {
    "path": "coreos/config.rb",
    "chars": 1895,
    "preview": "require 'erb'\nrequire 'dotenv'\n\n# Create user-data from erb template\nDotenv.load\nerb = File.open(File.join(File.dirname("
  },
  {
    "path": "coreos/user-data.yml.erb",
    "chars": 1349,
    "preview": "#cloud-config\n\ncoreos:\n  update:\n    group: beta\n    reboot-strategy: off\n  units:\n    - name: settimezone.service\n     "
  },
  {
    "path": "files/mime.types",
    "chars": 3504,
    "preview": "types {\n    text/html                             html htm shtml;\n    text/css                              css;\n    tex"
  },
  {
    "path": "files/nginx.conf",
    "chars": 2738,
    "preview": "env SERVER_NAME;\nenv S3_HOST;\n\nuser root;\nworker_processes 4;\ndaemon off;\n#worker_rlimit_nofile\nerror_log /dev/stdout in"
  },
  {
    "path": "files/validator.pm",
    "chars": 945,
    "preview": "package validator;\n\nuse nginx;\nuse strict;\nuse warnings;\n\nsub handler {\n  my $r = shift;\n  my $uri = \"/\" . ($r->uri =~ /"
  },
  {
    "path": "script/bootstrap",
    "chars": 903,
    "preview": "#!/bin/bash\n#\n# bootstrap\n#\n# Get readly to develop\n\nset -e\n\n#\n# Welcome message\n#\necho \"\"\necho \"  nginx-image-server\"\ne"
  },
  {
    "path": "script/build",
    "chars": 141,
    "preview": "#!/bin/bash\n#\n# Usage: script/build\n# Description: build nginx-image-server\n#\n\nset -e\n\ndocker build -t=quay.io/wantedly/"
  },
  {
    "path": "script/run",
    "chars": 622,
    "preview": "#!/bin/bash\n#\n# Usage: script/run <MODE>\n# Description: run nginx-image-server container\n# Example:\n#   $ script/run-tar"
  },
  {
    "path": "script/run-infrataster",
    "chars": 443,
    "preview": "#!/bin/bash\n#\n# Usage: script/run-infrataster\n# Description: run infrataster container\n#\n\nBASE_DIRECTORY=`pwd`\n\ncd ${BAS"
  },
  {
    "path": "script/run-locust",
    "chars": 563,
    "preview": "#!/bin/bash\n#\n# Usage: script/run-locust <LOCUST_ARGS>\n# Description: run tester container\n# Example:\n#   script/run-loc"
  },
  {
    "path": "script/test",
    "chars": 797,
    "preview": "#!/bin/sh\n#\n# Usage: script/cibuild\n# Description: script to run test\n#\n\nset -e\n\n# this script should be run in project "
  },
  {
    "path": "test/feature/spec/nginx_image_server_spec.rb",
    "chars": 1925,
    "preview": "require \"spec_helper\"\n\ndescribe server(:target) do\n  describe http('http://target/images/example.jpg') do\n    it \"respon"
  },
  {
    "path": "test/feature/spec/spec_helper.rb",
    "chars": 108,
    "preview": "require \"infrataster/rspec\"\n\nInfrataster::Server.define(\n  :target,\n  ENV[\"TARGET_IP\"],\n  vagrant: false,\n)\n"
  },
  {
    "path": "test/performance/locustfile.py",
    "chars": 418,
    "preview": "from locust import HttpLocust, TaskSet, task\nimport random\n\nclass MyTaskSet(TaskSet):\n    @task\n    def index(self):\n   "
  },
  {
    "path": "wercker.yml",
    "chars": 630,
    "preview": "box: wercker-labs/docker\nbuild:\n  steps:\n    - script:\n        name: Check docker version\n        code: |\n          dock"
  }
]

About this extraction

This page contains the full source code of the wantedly/nginx-image-server GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (27.8 KB), approximately 8.3k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!