Skip to content

Commit

Permalink
iter4 completed
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteDSM committed Oct 9, 2023
1 parent bbb404c commit 3febb4d
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 97 deletions.
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
# cmd/shortener
# go-musthave-shortener-tpl

В данной директории будет содержаться код, который скомпилируется в бинарное приложение
Шаблон репозитория для трека «Сервис сокращения URL».

## Начало работы

1. Склонируйте репозиторий в любую подходящую директорию на вашем компьютере.
2. В корне репозитория выполните команду `go mod init <name>` (где `<name>` — адрес вашего репозитория на GitHub без префикса `https://`) для создания модуля.

## Обновление шаблона

Чтобы иметь возможность получать обновления автотестов и других частей шаблона, выполните команду:

```
git remote add -m main template https://github.com/Yandex-Practicum/go-musthave-shortener-tpl.git
```

Для обновления кода автотестов выполните команду:

```
git fetch template && git checkout template/main .github
```

Затем добавьте полученные изменения в свой репозиторий.

## Запуск автотестов

Для успешного запуска автотестов называйте ветки `iter<number>`, где `<number>` — порядковый номер инкремента. Например, в ветке с названием `iter4` запустятся автотесты для инкрементов с первого по четвёртый.

При мёрже ветки с инкрементом в основную ветку `main` будут запускаться все автотесты.

Подробнее про локальный и автоматический запуск читайте в [README автотестов](https://github.com/Yandex-Practicum/go-autotests).
55 changes: 55 additions & 0 deletions cmd/client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package main

import (
"bufio"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
)

func main() {
endpoint := "http://localhost:8080/"
// контейнер данных для запроса
data := url.Values{}
// приглашение в консоли
fmt.Println("Введите длинный URL")
// открываем потоковое чтение из консоли
reader := bufio.NewReader(os.Stdin)
// читаем строку из консоли
long, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
long = strings.TrimSuffix(long, "\n")
// заполняем контейнер данными
data.Set("url", long)
// добавляем HTTP-клиент
client := &http.Client{}
// пишем запрос
// запрос методом POST должен, помимо заголовков, содержать тело
// тело должно быть источником потокового чтения io.Reader
request, err := http.NewRequest(http.MethodPost, endpoint, strings.NewReader(data.Encode()))
if err != nil {
panic(err)
}
// в заголовках запроса указываем кодировку
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
// отправляем запрос и получаем ответ
response, err := client.Do(request)
if err != nil {
panic(err)
}
// выводим код ответа
fmt.Println("Статус-код ", response.Status)
defer response.Body.Close()
// читаем поток из тела ответа
body, err := io.ReadAll(response.Body)
if err != nil {
panic(err)
}
// и печатаем его
fmt.Println(string(body))
}
21 changes: 21 additions & 0 deletions cmd/config/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package config

import (
flag "github.com/spf13/pflag"
)

// Config структура для хранения настроек
type Config struct {
RunAddr string
ResultURL string
}

// parseFlags обрабатывает аргументы командной строки
// и сохраняет их значения в соответствующих переменных
func ParseFlags(cfg *Config) {
//fs := flag.NewFlagSet("myflags", flag.ExitOnError)
flag.StringVarP(&cfg.RunAddr, "a", "a", "localhost:8080", "Адрес запуска HTTP-сервера.")
flag.StringVarP(&cfg.ResultURL, "b", "b", "http://localhost:8080", "Адрес результирующего сокращённого URL.")
// парсим переданные серверу аргументы в зарегистрированные переменные
flag.Parse()
}
93 changes: 92 additions & 1 deletion cmd/shortener/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,94 @@
package main

func main() {}
import (
"encoding/base64"
"fmt"
"github.com/gorilla/mux"
"github.com/nabbat/url-shortener-server.git/cmd/config"
"io"
"log"
"net/http"
)

// Словарь для хранения соответствий между сокращёнными и оригинальными URL
// TODO Создать хранилище
var urlMap = map[string]string{}

// Перенаправляем по полной ссылке
func redirectHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "invalid request type", http.StatusBadRequest)
return
}
// Добавляем тестовое соответствие в словарь
urlMap["aHR0cH"] = "https://practicum.yandex.ru/"
// Получаем идентификатор из URL-пути
id := r.URL.Path[1:]

// Получаем оригинальный URL из словаря

if originalURL, found := urlMap[id]; found {
// Устанавливаем заголовок Location и возвращаем ответ с кодом 307
w.Header().Set("Location", originalURL)
w.WriteHeader(http.StatusTemporaryRedirect)
return
}
http.Error(w, "Ссылка не найдена", http.StatusBadRequest)

}

func shortenURLHandler(w http.ResponseWriter, r *http.Request, cfg *config.Config) {
// Читаем тело запроса (URL)
urlBytes, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Ошибка чтения запроса", http.StatusBadRequest)
return
}

// Преобразуем в строку
url := string(urlBytes)

// Генерируем уникальный идентификатор сокращённого URL
id := generateID(url)

// Добавляем соответствие в словарь
urlMap[id] = url

// Отправляем ответ с сокращённым URL
shortenedURL := fmt.Sprintf("%s/%s", cfg.ResultURL, id)
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusCreated)
if _, err := io.WriteString(w, shortenedURL); err != nil {
log.Fatal(err)
}
}

// Простая функция для генерации уникального идентификатора
func generateID(fullURL string) string {
encodedStr := base64.URLEncoding.EncodeToString([]byte(fullURL))
// Возвращаем первые 6 символов закодированной строки
if len(encodedStr) > 6 {
return encodedStr[:6]
}
return encodedStr
}

func main() {
// Create a Config instance
cfg := &config.Config{}

// Parse command line flags and populate the Config instance
config.ParseFlags(cfg)

// Run server
r := mux.NewRouter()
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
shortenURLHandler(w, r, cfg)
}).Methods("POST")
r.HandleFunc("/{idShortenURL}", redirectHandler).Methods("GET")
fmt.Println("Running server on", cfg.RunAddr)
err := http.ListenAndServe(cfg.RunAddr, r)
if err != nil {
panic(err)
}
}
File renamed without changes.
15 changes: 15 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module github.com/nabbat/url-shortener-server.git

go 1.20

require (
github.com/gorilla/mux v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
94 changes: 0 additions & 94 deletions main.go

This file was deleted.

Binary file removed shortener
Binary file not shown.

0 comments on commit 3febb4d

Please sign in to comment.